diff options
Diffstat (limited to 'src')
56 files changed, 5261 insertions, 5124 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 8dd3ee9..5d747b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,85 +1,35 @@ -if GLITZ_BUILD_GLX_BACKEND -libglitz_glx_library = libglitz-glx.la -libglitz_glx_header = glitz-glx.h -else -libglitz_glx_library = -libglitz_glx_header = -endif +SUBDIRS = . glx agl -if GLITZ_BUILD_AGL_BACKEND -libglitz_agl_library = libglitz-agl.la -libglitz_agl_header = glitz-agl.h -else -libglitz_agl_library = -libglitz_agl_header = -endif +lib_LTLIBRARIES = libglitz.la +include_HEADERS = glitz.h -lib_LTLIBRARIES = \ - libglitz.la \ - $(libglitz_glx_library) \ - $(libglitz_agl_library) - -include_HEADERS = \ - glitz.h \ - $(libglitz_glx_header) \ - $(libglitz_agl_header) - -libglitz_la_SOURCES = \ - glitz.c \ - glitz.h \ +libglitz_la_SOURCES = \ + glitz.h \ + glitz.c \ glitz_operator.c \ - glitz_surface.c \ - glitz_texture.c \ - glitz_rect.c \ - glitz_status.c \ - glitz_util.c \ - glitz_format.c \ - glitz_program.c \ - glitz_compose.c \ - glitz_filter.c \ - glitz_buffer.c \ + glitz_drawable.c \ + glitz_surface.c \ + glitz_texture.c \ + glitz_rect.c \ + glitz_status.c \ + glitz_util.c \ + glitz_region.c \ + glitz_format.c \ + glitz_program.c \ + glitz_compose.c \ + glitz_filter.c \ + glitz_buffer.c \ glitz_geometry.c \ - glitz_pixel.c \ - glitz_gl.h \ + glitz_pixel.c \ + glitz_gl.h \ glitzint.h libglitz_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined -libglitz_la_CFLAGS = libglitz_la_LIBADD = -lm -if GLITZ_BUILD_GLX_BACKEND -libglitz_glx_la_SOURCES = \ - glitz.h \ - glitz_gl.h \ - glitzint.h \ - glitz-glx.h \ - glitz_glx_surface.c \ - glitz_glx_format.c \ - glitz_glx_info.c \ - glitz_glx_extension.c \ - glitz_glx_context.c \ - glitz_glx_pbuffer.c \ - glitz_glxext.h \ - glitz_glxint.h -libglitz_glx_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined -libglitz_glx_la_CFLAGS = $(GLX_CFLAGS) -libglitz_glx_la_LIBADD = -lglitz $(GLX_LIBS) -endif +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = glitz.pc -if GLITZ_BUILD_AGL_BACKEND -libglitz_agl_la_SOURCES = \ - glitz.h \ - glitz_gl.h \ - glitzint.h \ - glitz-agl.h \ - glitz_agl_surface.c \ - glitz_agl_format.c \ - glitz_agl_info.c \ - glitz_agl_extension.c \ - glitz_agl_context.c \ - glitz_agl_pbuffer.c \ - glitz_aglint.h -libglitz_agl_la_LDFLAGS = -version-info @VERSION_INFO@ -libglitz_agl_la_CFLAGS = $(AGL_CFLAGS) -libglitz_agl_la_LIBADD = -lglitz $(AGL_LIBS) -endif +EXTRA_DIST = \ + glitz.pc.in \ + glitz.man
\ No newline at end of file diff --git a/src/agl/Makefile.am b/src/agl/Makefile.am new file mode 100644 index 0000000..ee4134a --- /dev/null +++ b/src/agl/Makefile.am @@ -0,0 +1,38 @@ +if GLITZ_BUILD_AGL_BACKEND + +INCLUDES = \ + $(GLITZ_INC) \ + $(AGL_CFLAGS) + +lib_LTLIBRARIES = libglitz-agl.la +include_HEADERS = glitz-agl.h + +libglitz_agl_la_SOURCES = \ + glitz-agl.h \ + glitz_agl_drawable.c \ + glitz_agl_format.c \ + glitz_agl_info.c \ + glitz_agl_extension.c \ + glitz_agl_context.c \ + glitz_agl_pbuffer.c \ + glitz_aglint.h + +libglitz_agl_la_LDFLAGS = -version-info @VERSION_INFO@ +libglitz_agl_la_LIBADD = $(GLITZ_LIB) $(AGL_LIBS) + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = glitz-agl.pc + +endif + +EXTRA_DIST = \ + glitz-agl.h \ + glitz_agl_drawable.c \ + glitz_agl_format.c \ + glitz_agl_info.c \ + glitz_agl_extension.c \ + glitz_agl_context.c \ + glitz_agl_pbuffer.c \ + glitz_aglint.h \ + glitz-agl.pc.in \ + glitz-agl.man diff --git a/src/agl/glitz-agl.h b/src/agl/glitz-agl.h new file mode 100644 index 0000000..0d6b637 --- /dev/null +++ b/src/agl/glitz-agl.h @@ -0,0 +1,73 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifndef GLITZ_AGL_H_INCLUDED +#define GLITZ_AGL_H_INCLUDED + +#include <glitz.h> + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include <Carbon/Carbon.h> + + +/* glitz_agl_info.c */ + +void +glitz_agl_init (void); + +void +glitz_agl_fini (void); + + +/* glitz_agl_format.c */ + +glitz_drawable_format_t * +glitz_agl_find_drawable_format (unsigned long mask, + const glitz_drawable_format_t *templ, + int count); + + +/* glitz_agl_drawable.c */ + +glitz_drawable_t * +glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format, + WindowRef window, + int width, + int height); + +glitz_drawable_t * +glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask); + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* GLITZ_AGL_H_INCLUDED */ diff --git a/src/agl/glitz-agl.man b/src/agl/glitz-agl.man new file mode 100644 index 0000000..5cfbb19 --- /dev/null +++ b/src/agl/glitz-agl.man @@ -0,0 +1,26 @@ +.\" +.\" +.de TQ +.br +.ns +.TP +\\$1 +.. +.TH GLITZ-AGL 3 "Version 1.0" + +.SH NAME +GLITZ-AGL \- AGL interface to glitz + +.SH SYNOPSIS +.nf +.B #include <glitz-agl.h> +.fi +.SH DESCRIPTION + +AGL interface to glitz. + +.SH AUTHOR +David Reveman + +.SH "SEE ALSO" +.BR GLITZ (3)
\ No newline at end of file diff --git a/src/agl/glitz-agl.pc.in b/src/agl/glitz-agl.pc.in new file mode 100644 index 0000000..abe98cc --- /dev/null +++ b/src/agl/glitz-agl.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libglitz-agl +Description: OpenGL compositing library (AGL backend) +Version: @VERSION@ +Requires: glitz +Libs: -L${libdir} -lglitz-agl @AGL_LIBS@ +Cflags: -I${includedir} @AGL_CFLAGS@ diff --git a/src/agl/glitz_agl_context.c b/src/agl/glitz_agl_context.c new file mode 100644 index 0000000..d6be7d1 --- /dev/null +++ b/src/agl/glitz_agl_context.c @@ -0,0 +1,318 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitz_aglint.h" + +extern glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address; + +static CFBundleRef +_glitz_agl_get_bundle (const char *name) +{ + CFBundleRef bundle = 0; + FSRefParam ref_param; + unsigned char framework_name[256]; + + framework_name[0] = strlen (name); + strcpy (&framework_name[1], name); + + memset (&ref_param, 0, sizeof (ref_param)); + + if (FindFolder (kSystemDomain, + kFrameworksFolderType, + kDontCreateFolder, + &ref_param.ioVRefNum, + &ref_param.ioDirID) == noErr) { + FSRef ref; + + memset (&ref, 0, sizeof (ref)); + + ref_param.ioNamePtr = framework_name; + ref_param.newRef = &ref; + + if (PBMakeFSRefSync (&ref_param) == noErr) { + CFURLRef url; + + url = CFURLCreateFromFSRef (kCFAllocatorDefault, &ref); + if (url) { + bundle = CFBundleCreate (kCFAllocatorDefault, url); + CFRelease (url); + + if (!CFBundleLoadExecutable (bundle)) { + CFRelease (bundle); + return (CFBundleRef) 0; + } + } + } + } + + return bundle; +} + +static void +_glitz_agl_release_bundle (CFBundleRef bundle) +{ + if (bundle) { + CFBundleUnloadExecutable (bundle); + CFRelease (bundle); + } +} + +static glitz_function_pointer_t +_glitz_agl_get_proc_address (const char *name, void *closure) +{ + glitz_function_pointer_t address = NULL; + CFBundleRef bundle = (CFBundleRef) closure; + CFStringRef str; + + if (bundle) { + str = CFStringCreateWithCString (kCFAllocatorDefault, name, + kCFStringEncodingMacRoman); + + address = CFBundleGetFunctionPointerForName (bundle, str); + + CFRelease (str); + } + + return address; +} + +glitz_agl_context_t * +glitz_agl_context_get (glitz_agl_thread_info_t *thread_info, + glitz_drawable_format_t *format) +{ + glitz_agl_context_t *context; + glitz_agl_context_t **contexts = thread_info->contexts; + int index, n_contexts = thread_info->n_contexts; + + for (; n_contexts; n_contexts--, contexts++) + if ((*contexts)->id == format->id) + return *contexts; + + index = thread_info->n_contexts++; + + thread_info->contexts = + realloc (thread_info->contexts, + sizeof (glitz_agl_context_t *) * thread_info->n_contexts); + if (!thread_info->contexts) + return NULL; + + context = malloc (sizeof (glitz_agl_context_t)); + if (!context) + return NULL; + + thread_info->contexts[index] = context; + + context->context = + aglCreateContext (thread_info->pixel_formats[format->id], + thread_info->root_context); + if (!context->context) { + free (context); + return NULL; + } + + context->id = format->id; + context->pbuffer = 0; + + if (!thread_info->root_context) + thread_info->root_context = context->context; + + memcpy (&context->backend.gl, + &_glitz_agl_gl_proc_address, + sizeof (glitz_gl_proc_address_list_t)); + + context->backend.create_pbuffer = glitz_agl_create_pbuffer; + context->backend.destroy = glitz_agl_destroy; + context->backend.push_current = glitz_agl_push_current; + context->backend.pop_current = glitz_agl_pop_current; + context->backend.swap_buffers = glitz_agl_swap_buffers; + context->backend.make_current_read = glitz_agl_make_current_read; + + context->backend.drawable_formats = thread_info->formats; + context->backend.n_drawable_formats = thread_info->n_formats; + + context->backend.texture_formats = NULL; + context->backend.formats = NULL; + context->backend.n_formats = 0; + + context->backend.program_map = &thread_info->program_map; + context->backend.feature_mask = 0; + + context->initialized = 0; + + return context; +} + +void +glitz_agl_context_destroy (glitz_agl_thread_info_t *thread_info, + glitz_agl_context_t *context) +{ + if (context->backend.formats) + free (context->backend.formats); + + if (context->backend.texture_formats) + free (context->backend.texture_formats); + + aglDestroyContext (context->context); + + free (context); +} + +static void +_glitz_agl_context_initialize (glitz_agl_thread_info_t *thread_info, + glitz_agl_context_t *context) +{ + CFBundleRef bundle; + + bundle = _glitz_agl_get_bundle ("OpenGL.framework"); + + glitz_backend_init (&context->backend, + _glitz_agl_get_proc_address, + (void *) bundle); + + _glitz_agl_release_bundle (bundle); + + context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS, + context->max_viewport_dims); + + glitz_initiate_state (&_glitz_agl_gl_proc_address); + + context->initialized = 1; +} + +static void +_glitz_agl_context_make_current (glitz_agl_drawable_t *drawable, + glitz_bool_t flush) +{ + if (flush) + glFlush (); + + if (drawable->pbuffer) { + aglSetPBuffer (drawable->context->context, drawable->pbuffer, 0, 0, + aglGetVirtualScreen (drawable->context->context)); + drawable->context->pbuffer = 1; + } else { + if (drawable->context->pbuffer) { + aglSetDrawable (drawable->context->context, NULL); + drawable->context->pbuffer = 0; + } + + aglSetDrawable (drawable->context->context, drawable->drawable); + } + + aglSetCurrentContext (drawable->context->context); + + drawable->base.update_all = 1; + + if (!drawable->context->initialized) + _glitz_agl_context_initialize (drawable->thread_info, drawable->context); +} + +static void +_glitz_agl_context_update (glitz_agl_drawable_t *drawable, + glitz_constraint_t constraint) +{ + AGLContext context; + + switch (constraint) { + case GLITZ_NONE: + break; + case GLITZ_ANY_CONTEXT_CURRENT: + context = aglGetCurrentContext (); + if (context == (AGLContext) 0) + _glitz_agl_context_make_current (drawable, 0); + break; + case GLITZ_CONTEXT_CURRENT: + context = aglGetCurrentContext (); + if (context != drawable->context->context) + _glitz_agl_context_make_current (drawable, (context)? 1: 0); + break; + case GLITZ_DRAWABLE_CURRENT: + context = aglGetCurrentContext (); + if (context != drawable->context->context) { + _glitz_agl_context_make_current (drawable, (context)? 1: 0); + } else { + if (drawable->pbuffer) { + AGLPbuffer pbuffer; + GLuint unused; + + aglGetPBuffer (drawable->context->context, &pbuffer, + &unused, &unused, &unused); + + if (pbuffer != drawable->pbuffer) + _glitz_agl_context_make_current (drawable, (context)? 1: 0); + + } else if (drawable->drawable) { + if (aglGetDrawable (drawable->context->context) != drawable->drawable) + _glitz_agl_context_make_current (drawable, (context)? 1: 0); + } + } + break; + } +} + +void +glitz_agl_push_current (void *abstract_drawable, + glitz_surface_t *surface, + glitz_constraint_t constraint) +{ + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; + glitz_agl_context_info_t *context_info; + int index; + + index = drawable->thread_info->context_stack_size++; + + context_info = &drawable->thread_info->context_stack[index]; + context_info->drawable = drawable; + context_info->surface = surface; + context_info->constraint = constraint; + + _glitz_agl_context_update (context_info->drawable, constraint); +} + +glitz_surface_t * +glitz_agl_pop_current (void *abstract_drawable) +{ + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; + glitz_agl_context_info_t *context_info = NULL; + int index; + + drawable->thread_info->context_stack_size--; + index = drawable->thread_info->context_stack_size - 1; + + context_info = &drawable->thread_info->context_stack[index]; + + if (context_info->drawable) + _glitz_agl_context_update (context_info->drawable, + context_info->constraint); + + if (context_info->constraint == GLITZ_DRAWABLE_CURRENT) + return context_info->surface; + + return NULL; +} diff --git a/src/agl/glitz_agl_drawable.c b/src/agl/glitz_agl_drawable.c new file mode 100644 index 0000000..661181d --- /dev/null +++ b/src/agl/glitz_agl_drawable.c @@ -0,0 +1,227 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitz_aglint.h" + +glitz_status_t +glitz_agl_make_current_read (void *abstract_surface) +{ + return GLITZ_STATUS_NOT_SUPPORTED; +} + +static glitz_agl_drawable_t * +_glitz_agl_create_drawable (glitz_agl_thread_info_t *thread_info, + glitz_agl_context_t *context, + glitz_drawable_format_t *format, + AGLDrawable agl_drawable, + AGLPbuffer agl_pbuffer, + int width, + int height) +{ + glitz_agl_drawable_t *drawable; + + if (width <= 0 || height <= 0) + return NULL; + + drawable = (glitz_agl_drawable_t *) malloc (sizeof (glitz_agl_drawable_t)); + if (drawable == NULL) + return NULL; + + drawable->base.ref_count = 1; + drawable->thread_info = thread_info; + drawable->context = context; + drawable->drawable = agl_drawable; + drawable->pbuffer = agl_pbuffer; + drawable->base.format = format; + drawable->base.backend = &context->backend; + + glitz_drawable_update_size (&drawable->base, width, height); + + if (!context->initialized) { + glitz_agl_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT); + glitz_agl_pop_current (drawable); + } + + if (width > context->max_viewport_dims[0] || + height > context->max_viewport_dims[1]) { + free (drawable); + return NULL; + } + + thread_info->drawables++; + + return drawable; +} + +static glitz_drawable_t * +_glitz_agl_create_pbuffer_drawable (glitz_agl_thread_info_t *thread_info, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask) +{ + glitz_agl_drawable_t *drawable; + glitz_agl_context_t *context; + AGLPbuffer pbuffer; + int width, height; + + if (!format->types.pbuffer) + return NULL; + + context = glitz_agl_context_get (thread_info, format); + if (!context) + return NULL; + + pbuffer = glitz_agl_pbuffer_create (thread_info, attributes, mask, + &width, &height); + if (!pbuffer) + return NULL; + + drawable = _glitz_agl_create_drawable (thread_info, context, format, + (AGLDrawable) 0, pbuffer, + width, height); + if (!drawable) { + glitz_agl_pbuffer_destroy (pbuffer); + return NULL; + } + + return &drawable->base; +} + +glitz_drawable_t * +glitz_agl_create_pbuffer (void *abstract_templ, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask) +{ + glitz_agl_drawable_t *templ = (glitz_agl_drawable_t *) abstract_templ; + + return _glitz_agl_create_pbuffer_drawable (templ->thread_info, format, + attributes, mask); +} + +glitz_drawable_t * +glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format, + WindowRef window, + int width, + int height) +{ + glitz_agl_drawable_t *drawable; + glitz_agl_thread_info_t *thread_info; + glitz_agl_context_t *context; + AGLDrawable agl_drawable; + + agl_drawable = (AGLDrawable) GetWindowPort (window); + if (!agl_drawable) + return NULL; + + thread_info = glitz_agl_thread_info_get (); + if (!thread_info) + return NULL; + + context = glitz_agl_context_get (thread_info, format); + if (!context) + return NULL; + + drawable = _glitz_agl_create_drawable (thread_info, context, format, + agl_drawable, (AGLPbuffer) 0, + width, height); + if (!drawable) + return NULL; + + return &drawable->base; +} +slim_hidden_def(glitz_agl_create_drawable_for_window); + +glitz_drawable_t * +glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask) +{ + glitz_agl_thread_info_t *thread_info; + + thread_info = glitz_agl_thread_info_get (); + if (!thread_info) + return NULL; + + return _glitz_agl_create_pbuffer_drawable (thread_info, format, + attributes, mask); +} +slim_hidden_def(glitz_agl_create_pbuffer_drawable); + +void +glitz_agl_destroy (void *abstract_drawable) +{ + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; + + drawable->thread_info->drawables--; + if (drawable->thread_info->drawables == 0) { + /* + * Last drawable? We have to destroy all fragment programs as this may + * be our last chance to have a context current. + */ + glitz_agl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT); + glitz_program_map_fini (&drawable->base.backend->gl, + &drawable->thread_info->program_map); + glitz_agl_pop_current (abstract_drawable); + } + + if (drawable->drawable || drawable->pbuffer) { + AGLContext context = aglGetCurrentContext (); + + if (context == drawable->context->context) { + if (drawable->pbuffer) { + AGLPbuffer pbuffer; + GLuint unused; + + aglGetPBuffer (context, &pbuffer, &unused, &unused, &unused); + + if (pbuffer == drawable->pbuffer) + aglSetCurrentContext (NULL); + } else { + if (aglGetDrawable (context) == drawable->drawable) + aglSetCurrentContext (NULL); + } + } + + if (drawable->pbuffer) + glitz_agl_pbuffer_destroy (drawable->pbuffer); + } + + free (drawable); +} + +void +glitz_agl_swap_buffers (void *abstract_drawable) +{ + glitz_agl_drawable_t *drawable = (glitz_agl_drawable_t *) abstract_drawable; + + glitz_agl_push_current (abstract_drawable, NULL, GLITZ_DRAWABLE_CURRENT); + aglSwapBuffers (drawable->context->context); + glitz_agl_pop_current (abstract_drawable); +} diff --git a/src/agl/glitz_agl_extension.c b/src/agl/glitz_agl_extension.c new file mode 100644 index 0000000..22b800e --- /dev/null +++ b/src/agl/glitz_agl_extension.c @@ -0,0 +1,92 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitz_aglint.h" + +static glitz_extension_map agl_extensions[] = { + { 0.0, "GL_APPLE_pixel_buffer", GLITZ_AGL_FEATURE_PBUFFER_MASK }, + { 0.0, "GL_ARB_multisample", GLITZ_AGL_FEATURE_MULTISAMPLE_MASK }, + { 0.0, "GL_ARB_texture_rectangle", + GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_EXT_texture_rectangle", + GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_NV_texture_rectangle", GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, NULL, 0 } +}; + +glitz_status_t +glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info) +{ + GLint attrib[] = { + AGL_RGBA, + AGL_NO_RECOVERY, + AGL_NONE + }; + AGLPixelFormat pf; + AGLContext context; + + thread_info->agl_feature_mask = 0; + + pf = aglChoosePixelFormat (NULL, 0, attrib); + context = aglCreateContext (pf, NULL); + + if (context) { + const char *gl_extensions_string; + + aglSetCurrentContext (context); + + gl_extensions_string = (const char *) glGetString (GL_EXTENSIONS); + + thread_info->agl_feature_mask = + glitz_extensions_query (0.0, + gl_extensions_string, + agl_extensions); + + if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK) { + const char *vendor; + + vendor = glGetString (GL_VENDOR); + + if (vendor) { + + /* NVIDIA's driver seem to support multisample with pbuffers */ + if (!strncmp ("NVIDIA", vendor, 6)) + thread_info->agl_feature_mask |= + GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK; + } + } + + aglSetCurrentContext (NULL); + aglDestroyContext (context); + } + + aglDestroyPixelFormat (pf); + + return GLITZ_STATUS_SUCCESS; +} diff --git a/src/agl/glitz_agl_format.c b/src/agl/glitz_agl_format.c new file mode 100644 index 0000000..072c14f --- /dev/null +++ b/src/agl/glitz_agl_format.c @@ -0,0 +1,333 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitz_aglint.h" + +#include <stdlib.h> +#include <string.h> + +static GLint _attribs[] = { + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_NONE +}; + +static GLint _db_attribs[] = { + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_NONE +}; + +static GLint _stencil_attribs[] = { + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_DEPTH_SIZE, 8, + AGL_STENCIL_SIZE, 8, + AGL_NONE +}; + +static GLint _db_stencil_attribs[] = { + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_NONE +}; + +static GLint _ms2_attribs[] = { + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 2, + AGL_NONE +}; + +static GLint _db_ms2_attribs[] = { + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 2, + AGL_NONE +}; + +static GLint _ms4_attribs[] = { + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 4, + AGL_NONE +}; + +static GLint _db_ms4_attribs[] = { + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 4, + AGL_NONE +}; + +static GLint _ms6_attribs[] = { + AGL_RGBA, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 6, + AGL_NONE +}; + +static GLint _db_ms6_attribs[] = { + AGL_RGBA, + AGL_DOUBLEBUFFER, + AGL_ALPHA_SIZE, 16, + AGL_RED_SIZE, 16, + AGL_STENCIL_SIZE, 8, + AGL_SAMPLE_BUFFERS_ARB, 1, + AGL_SAMPLES_ARB, 6, + AGL_NONE +}; + +static GLint *_attribs_list[] = { + _attribs, + _db_attribs, + _stencil_attribs, + _db_stencil_attribs, + _ms2_attribs, + _db_ms2_attribs, + _ms4_attribs, + _db_ms4_attribs, + _ms6_attribs, + _db_ms6_attribs +}; + +static int +_glitz_agl_format_compare (const void *elem1, + const void *elem2) +{ + int i, score[2]; + glitz_drawable_format_t *format[2]; + + format[0] = (glitz_drawable_format_t *) elem1; + format[1] = (glitz_drawable_format_t *) elem2; + i = score[0] = score[1] = 0; + + for (; i < 2; i++) { + if (format[i]->color.red_size) { + if (format[i]->color.red_size == 8) + score[i] += 5; + score[i] += 10; + } + + if (format[i]->color.green_size) { + if (format[i]->color.green_size == 8) + score[i] += 5; + score[i] += 10; + } + + if (format[i]->color.alpha_size) { + if (format[i]->color.alpha_size == 8) + score[i] += 5; + score[i] += 10; + } + + if (format[i]->stencil_size) + score[i] += 5; + + if (format[i]->depth_size) + score[i] += 5; + + if (format[i]->doublebuffer) + score[i] += 10; + + if (format[i]->types.window) + score[i] += 10; + + if (format[i]->types.pbuffer) + score[i] += 10; + + if (format[i]->samples > 1) + score[i] -= (20 - format[i]->samples); + } + + return score[1] - score[0]; +} + +static void +_glitz_add_format (glitz_agl_thread_info_t *thread_info, + glitz_drawable_format_t *format, + AGLPixelFormat pixel_format) +{ + if (!glitz_drawable_format_find (thread_info->formats, + thread_info->n_formats, + GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK, + format, 0)) { + int n = thread_info->n_formats; + + thread_info->formats = + realloc (thread_info->formats, + sizeof (glitz_drawable_format_t) * (n + 1)); + thread_info->pixel_formats = + realloc (thread_info->pixel_formats, + sizeof (AGLPixelFormat) * (n + 1)); + + if (thread_info->formats && thread_info->pixel_formats) { + thread_info->formats[n] = *format; + thread_info->formats[n].id = n; + thread_info->pixel_formats[n] = pixel_format; + thread_info->n_formats++; + } + } +} + +void +glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info) +{ + glitz_drawable_format_t format; + AGLPixelFormat pixel_format, *new_pfs; + int n_attribs_list, i; + + format.types.window = 1; + format.id = 0; + + n_attribs_list = sizeof (_attribs_list) / sizeof (GLint *); + + for (i = 0; i < n_attribs_list; i++) { + GLint value; + + pixel_format = aglChoosePixelFormat (NULL, 0, _attribs_list[i]); + + /* Stereo is not supported yet */ + if (!(aglDescribePixelFormat (pixel_format, AGL_STEREO, &value)) || + value) { + aglDestroyPixelFormat (pixel_format); + continue; + } + + aglDescribePixelFormat (pixel_format, AGL_DOUBLEBUFFER, &value); + format.doublebuffer = (value)? 1: 0; + + aglDescribePixelFormat (pixel_format, AGL_RED_SIZE, &value); + format.color.red_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_GREEN_SIZE, &value); + format.color.green_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_BLUE_SIZE, &value); + format.color.blue_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_ALPHA_SIZE, &value); + format.color.alpha_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_DEPTH_SIZE, &value); + format.depth_size = (unsigned short) value; + aglDescribePixelFormat (pixel_format, AGL_STENCIL_SIZE, &value); + format.stencil_size = (unsigned short) value; + + if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK) { + aglDescribePixelFormat (pixel_format, AGL_SAMPLE_BUFFERS_ARB, &value); + if (value) { + aglDescribePixelFormat (pixel_format, AGL_SAMPLES_ARB, &value); + format.samples = (unsigned short) (value > 1)? value: 1; + } else + format.samples = 1; + } else + format.samples = 1; + + if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_PBUFFER_MASK) { + if (format.color.red_size && format.color.green_size && + format.color.blue_size && format.color.alpha_size && + format.doublebuffer == 0 && format.stencil_size == 0 && + format.depth_size == 0) { + + if (thread_info->agl_feature_mask & + GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK) + format.types.pbuffer = 1; + else if (format.samples == 1) + format.types.pbuffer = 1; + else + format.types.pbuffer = 0; + } else + format.types.pbuffer = 0; + } else + format.types.pbuffer = 0; + + if (format.color.red_size || + format.color.green_size || + format.color.blue_size || + format.color.alpha_size) + _glitz_add_format (thread_info, &format, pixel_format); + } + + if (!thread_info->n_formats) + return; + + qsort (thread_info->formats, thread_info->n_formats, + sizeof (glitz_drawable_format_t), _glitz_agl_format_compare); + + /* + * Update AGLPixelFormat list so that it matches the sorted format list. + */ + new_pfs = malloc (sizeof (AGLPixelFormat) * thread_info->n_formats); + if (!new_pfs) { + thread_info->n_formats = 0; + return; + } + + for (i = 0; i < thread_info->n_formats; i++) { + new_pfs[i] = thread_info->pixel_formats[thread_info->formats[i].id]; + thread_info->formats[i].id = i; + } + + free (thread_info->pixel_formats); + thread_info->pixel_formats = new_pfs; +} + +glitz_drawable_format_t * +glitz_agl_find_drawable_format (unsigned long mask, + const glitz_drawable_format_t *templ, + int count) +{ + glitz_agl_thread_info_t *thread_info = glitz_agl_thread_info_get (); + + return glitz_drawable_format_find (thread_info->formats, + thread_info->n_formats, + mask, templ, count); +} +slim_hidden_def(glitz_agl_find_drawable_format); diff --git a/src/glitz_agl_info.c b/src/agl/glitz_agl_info.c index 3a921a6..575c022 100644 --- a/src/glitz_agl_info.c +++ b/src/agl/glitz_agl_info.c @@ -1,28 +1,26 @@ /* - * Copyright © 2004 David Reveman, Peter Nilsson - * + * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. + * 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 AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. + * 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. * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> + * Author: David Reveman <c99drn@cs.umu.se> */ #ifdef HAVE_CONFIG_H @@ -34,9 +32,12 @@ #include <OpenGL/glext.h> glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address = { + + /* core */ (glitz_gl_enable_t) glEnable, (glitz_gl_disable_t) glDisable, (glitz_gl_get_error_t) glGetError, + (glitz_gl_get_string_t) glGetString, (glitz_gl_enable_client_state_t) glEnableClientState, (glitz_gl_disable_client_state_t) glDisableClientState, (glitz_gl_vertex_pointer_t) glVertexPointer, @@ -91,6 +92,7 @@ glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address = { (glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D, (glitz_gl_get_integer_v_t) glGetIntegerv, + /* extensions */ (glitz_gl_blend_color_t) 0, (glitz_gl_active_texture_t) 0, (glitz_gl_gen_programs_t) 0, @@ -106,81 +108,9 @@ glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address = { (glitz_gl_buffer_sub_data_t) 0, (glitz_gl_get_buffer_sub_data_t) 0, (glitz_gl_map_buffer_t) 0, - (glitz_gl_unmap_buffer_t) 0, - - 1 + (glitz_gl_unmap_buffer_t) 0 }; -CFBundleRef -glitz_agl_get_bundle (const char *name) -{ - CFBundleRef bundle = 0; - FSRefParam ref_param; - unsigned char framework_name[256]; - - framework_name[0] = strlen (name); - strcpy (&framework_name[1], name); - - memset (&ref_param, 0, sizeof (ref_param)); - - if (FindFolder (kSystemDomain, - kFrameworksFolderType, - kDontCreateFolder, - &ref_param.ioVRefNum, - &ref_param.ioDirID) == noErr) { - FSRef ref; - - memset (&ref, 0, sizeof (ref)); - - ref_param.ioNamePtr = framework_name; - ref_param.newRef = &ref; - - if (PBMakeFSRefSync (&ref_param) == noErr) { - CFURLRef url; - - url = CFURLCreateFromFSRef (kCFAllocatorDefault, &ref); - if (url) { - bundle = CFBundleCreate (kCFAllocatorDefault, url); - CFRelease (url); - - if (!CFBundleLoadExecutable (bundle)) { - CFRelease (bundle); - return (CFBundleRef) 0; - } - } - } - } - - return bundle; -} - -void -glitz_agl_release_bundle (CFBundleRef bundle) -{ - if (bundle) { - CFBundleUnloadExecutable (bundle); - CFRelease (bundle); - } -} - -glitz_function_pointer_t -glitz_agl_get_proc_address (CFBundleRef bundle, const char *name) -{ - glitz_function_pointer_t address = NULL; - CFStringRef str; - - if (bundle) { - str = CFStringCreateWithCString (kCFAllocatorDefault, name, - kCFStringEncodingMacRoman); - - address = CFBundleGetFunctionPointerForName (bundle, str); - - CFRelease (str); - } - - return address; -} - static void glitz_agl_thread_info_init (glitz_agl_thread_info_t *thread_info); @@ -244,6 +174,7 @@ glitz_agl_thread_info_get (void) /* not thread safe */ static glitz_agl_thread_info_t _thread_info = { + 0, NULL, NULL, 0, @@ -251,10 +182,7 @@ static glitz_agl_thread_info_t _thread_info = { 0, { 0 }, 0, - { 0 }, - 0, - 0, - 0, + NULL, 0, { 0 } }; @@ -280,59 +208,24 @@ glitz_agl_thread_info_get (void) static void glitz_agl_thread_info_init (glitz_agl_thread_info_t *thread_info) { - GLint attrib[] = { - AGL_RGBA, - AGL_NO_RECOVERY, - AGL_NONE - }; - thread_info->formats = NULL; - thread_info->format_ids = NULL; + thread_info->pixel_formats = (AGLPixelFormat *) 0; thread_info->n_formats = 0; thread_info->contexts = NULL; thread_info->n_contexts = 0; - glitz_program_map_init (&thread_info->program_map); - - glitz_agl_surface_backend_init (&thread_info->root_context.backend); + thread_info->context_stack_size = 1; + thread_info->context_stack->surface = NULL; + thread_info->context_stack->constraint = GLITZ_NONE; - memcpy (&thread_info->root_context.backend.gl, - &_glitz_agl_gl_proc_address, - sizeof (glitz_gl_proc_address_list_t)); - - thread_info->root_context.backend.formats = NULL; - thread_info->root_context.backend.n_formats = 0; - thread_info->root_context.backend.program_map = NULL; - thread_info->root_context.backend.feature_mask = 0; + thread_info->root_context = NULL; - thread_info->agl_feature_mask = thread_info->feature_mask = 0; - - thread_info->root_context.pixel_format = - aglChoosePixelFormat (NULL, 0, attrib); - if (thread_info->root_context.pixel_format) { - thread_info->root_context.context = - aglCreateContext (thread_info->root_context.pixel_format, NULL); - if (thread_info->root_context.context) { + thread_info->agl_feature_mask = 0; - aglSetCurrentContext (thread_info->root_context.context); - - if (glitz_agl_query_extensions (thread_info) == GLITZ_STATUS_SUCCESS) { - thread_info->root_context.backend.feature_mask = - thread_info->feature_mask; - glitz_agl_context_proc_address_lookup (thread_info, - &thread_info->root_context); - glitz_agl_query_formats (thread_info); - } - } - } - - thread_info->root_context.backend.formats = thread_info->formats; - thread_info->root_context.backend.n_formats = thread_info->n_formats; - thread_info->root_context.backend.program_map = &thread_info->program_map; + glitz_program_map_init (&thread_info->program_map); - thread_info->context_stack_size = 1; - thread_info->context_stack->surface = NULL; - thread_info->context_stack->constraint = GLITZ_CN_NONE; + if (!glitz_agl_query_extensions (thread_info)) + glitz_agl_query_formats (thread_info); } static void @@ -340,27 +233,17 @@ glitz_agl_thread_info_fini (glitz_agl_thread_info_t *thread_info) { int i; - if (thread_info->root_context.context) { - aglSetCurrentContext (thread_info->root_context.context); - glitz_program_map_fini (&thread_info->root_context.backend.gl, - &thread_info->program_map); - aglSetCurrentContext (NULL); - } - for (i = 0; i < thread_info->n_contexts; i++) glitz_agl_context_destroy (thread_info, thread_info->contexts[i]); - + for (i = 0; i < thread_info->n_formats; i++) - aglDestroyPixelFormat (thread_info->format_ids[i]); - + aglDestroyPixelFormat (thread_info->pixel_formats[i]); + if (thread_info->formats) free (thread_info->formats); - if (thread_info->format_ids) - free (thread_info->format_ids); - - if (thread_info->root_context.context) - aglDestroyContext (thread_info->root_context.context); + if (thread_info->pixel_formats) + free (thread_info->pixel_formats); } void @@ -373,8 +256,7 @@ slim_hidden_def(glitz_agl_init); void glitz_agl_fini (void) { - glitz_agl_thread_info_t *info = - glitz_agl_thread_info_get (); + glitz_agl_thread_info_t *info = glitz_agl_thread_info_get (); glitz_agl_thread_info_destroy (info); } diff --git a/src/agl/glitz_agl_pbuffer.c b/src/agl/glitz_agl_pbuffer.c new file mode 100644 index 0000000..5237316 --- /dev/null +++ b/src/agl/glitz_agl_pbuffer.c @@ -0,0 +1,74 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../../config.h" +#endif + +#include "glitz_aglint.h" + +AGLPbuffer +glitz_agl_pbuffer_create (glitz_agl_thread_info_t *thread_info, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask, + int *width, + int *height) +{ + AGLPbuffer pbuffer; + glitz_gl_enum_t target; + int w, h; + + if (mask & GLITZ_PBUFFER_WIDTH_MASK) + w = attributes->width; + else + w = GLITZ_DEFAULT_PBUFFER_WIDTH; + + if (mask & GLITZ_PBUFFER_HEIGHT_MASK) + h = attributes->height; + else + h = GLITZ_DEFAULT_PBUFFER_HEIGHT; + + if (!POWER_OF_TWO (w) || !POWER_OF_TWO (h)) { + if (thread_info->agl_feature_mask & + GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK) + target = GLITZ_GL_TEXTURE_RECTANGLE; + else + return (AGLPbuffer) 0; + } else + target = GLITZ_GL_TEXTURE_2D; + + aglCreatePBuffer (w, h, target, GLITZ_GL_RGBA, 0, &pbuffer); + + *width = w; + *height = h; + + return pbuffer; +} + +void +glitz_agl_pbuffer_destroy (AGLPbuffer pbuffer) +{ + aglDestroyPBuffer (pbuffer); +} diff --git a/src/agl/glitz_aglint.h b/src/agl/glitz_aglint.h new file mode 100644 index 0000000..0127117 --- /dev/null +++ b/src/agl/glitz_aglint.h @@ -0,0 +1,145 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifndef GLITZ_GLXINT_H_INCLUDED +#define GLITZ_GLXINT_H_INCLUDED + +#include "glitz.h" +#include "glitzint.h" + +#include "glitz-agl.h" + +#include <OpenGL/gl.h> +#include <Carbon/Carbon.h> +#include <AGL/agl.h> + +#define GLITZ_AGL_FEATURE_PBUFFER_MASK (1L << 0) +#define GLITZ_AGL_FEATURE_MULTISAMPLE_MASK (1L << 1) +#define GLITZ_AGL_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 2) +#define GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 3) + +typedef struct _glitz_agl_drawable glitz_agl_drawable_t; + +typedef struct _glitz_agl_context_info_t { + glitz_agl_drawable_t *drawable; + glitz_surface_t *surface; + glitz_constraint_t constraint; +} glitz_agl_context_info_t; + +typedef struct _glitz_agl_context_t { + AGLContext context; + glitz_format_id_t id; + AGLPixelFormat pixel_format; + glitz_bool_t pbuffer; + glitz_backend_t backend; + glitz_gl_int_t max_viewport_dims[2]; + glitz_gl_int_t max_texture_2d_size; + glitz_gl_int_t max_texture_rect_size; + glitz_bool_t initialized; +} glitz_agl_context_t; + +typedef struct _glitz_agl_thread_info_t { + int drawables; + glitz_drawable_format_t *formats; + AGLPixelFormat *pixel_formats; + int n_formats; + glitz_agl_context_t **contexts; + int n_contexts; + glitz_agl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; + int context_stack_size; + AGLContext root_context; + unsigned long agl_feature_mask; + glitz_program_map_t program_map; +} glitz_agl_thread_info_t; + +struct _glitz_agl_drawable { + glitz_drawable_t base; + + glitz_agl_thread_info_t *thread_info; + glitz_agl_context_t *context; + AGLDrawable drawable; + AGLPbuffer pbuffer; + WindowRef window; +}; + +extern glitz_status_t __internal_linkage +glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info); + +extern glitz_agl_thread_info_t *__internal_linkage +glitz_agl_thread_info_get (void); + +extern glitz_agl_context_t *__internal_linkage +glitz_agl_context_get (glitz_agl_thread_info_t *thread_info, + glitz_drawable_format_t *format); + +extern void __internal_linkage +glitz_agl_context_destroy (glitz_agl_thread_info_t *thread_info, + glitz_agl_context_t *context); + +extern void __internal_linkage +glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info); + +extern AGLPbuffer __internal_linkage +glitz_agl_pbuffer_create (glitz_agl_thread_info_t *thread_info, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask, + int *width, + int *height); + +extern void __internal_linkage +glitz_agl_pbuffer_destroy (AGLPbuffer pbuffer); + +extern glitz_drawable_t *__internal_linkage +glitz_agl_create_pbuffer (void *abstract_templ, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask); + +extern void __internal_linkage +glitz_agl_push_current (void *abstract_drawable, + glitz_surface_t *surface, + glitz_constraint_t constraint); + +extern glitz_surface_t *__internal_linkage +glitz_agl_pop_current (void *abstract_drawable); + +extern glitz_status_t __internal_linkage +glitz_agl_make_current_read (void *abstract_surface); + +extern void __internal_linkage +glitz_agl_destroy (void *abstract_drawable); + +extern void __internal_linkage +glitz_agl_swap_buffers (void *abstract_drawable); + +/* Avoid unnecessary PLT entries. */ + +slim_hidden_proto(glitz_agl_init) +slim_hidden_proto(glitz_agl_fini) +slim_hidden_proto(glitz_agl_find_drawable_format) +slim_hidden_proto(glitz_agl_create_drawable_for_window) +slim_hidden_proto(glitz_agl_create_pbuffer_drawable) + +#endif /* GLITZ_GLXINT_H_INCLUDED */ diff --git a/src/glitz-agl.h b/src/glitz-agl.h deleted file mode 100644 index b89409d..0000000 --- a/src/glitz-agl.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifndef GLITZ_AGL_H_INCLUDED -#define GLITZ_AGL_H_INCLUDED - -#include <glitz.h> - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -#include <Carbon/Carbon.h> - -/* glitz_agl_info.c */ - -void -glitz_agl_init (void); - -void -glitz_agl_fini (void); - - -/* glitz_agl_format.c */ - -glitz_format_t * -glitz_agl_find_format (unsigned long mask, - const glitz_format_t *templ, - int count); - -glitz_format_t * -glitz_agl_find_standard_format (glitz_format_name_t format_name); - - -/* glitz_agl_surface.c */ - -glitz_surface_t * -glitz_agl_surface_create (glitz_format_t *format, - int width, - int height); - -glitz_surface_t * -glitz_agl_surface_create_for_window (glitz_format_t *format, - WindowRef window, - int width, - int height); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* GLITZ_AGL_H_INCLUDED */ diff --git a/src/glitz-glx.h b/src/glitz-glx.h deleted file mode 100644 index e4b9aad..0000000 --- a/src/glitz-glx.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifndef GLITZ_GLX_H_INCLUDED -#define GLITZ_GLX_H_INCLUDED - -#include <glitz.h> - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -/* glitz_glx_info.c */ - -void -glitz_glx_init (const char *gl_library); - -void -glitz_glx_fini (void); - - -/* glitz_glx_format.c */ - -glitz_format_t * -glitz_glx_find_format (Display *display, - int screen, - unsigned long mask, - const glitz_format_t *templ, - int count); - -glitz_format_t * -glitz_glx_find_standard_format (Display *display, - int screen, - glitz_format_name_t format_name); - -XVisualInfo * -glitz_glx_get_visual_info_from_format (Display *display, - int screen, - glitz_format_t *format); - - -/* glitz_glx_surface.c */ - -glitz_surface_t * -glitz_glx_surface_create (Display *display, - int screen, - glitz_format_t *format, - int width, - int height); - -glitz_surface_t * -glitz_glx_surface_create_for_window (Display *display, - int screen, - glitz_format_t *format, - Window window, - int width, - int height); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* GLITZ_GLX_H_INCLUDED */ diff --git a/src/glitz.c b/src/glitz.c index 423adc3..39620a5 100644 --- a/src/glitz.c +++ b/src/glitz.c @@ -61,9 +61,6 @@ glitz_composite (glitz_operator_t op, int width, int height) { - glitz_gl_proc_address_list_t *gl = &dst->backend->gl; - glitz_surface_t *intermediate = NULL; - glitz_bounding_box_t rect; glitz_composite_op_t comp_op; int i, passes, texture_nr = -1; glitz_texture_t *stexture, *mtexture; @@ -72,6 +69,9 @@ glitz_composite (glitz_operator_t op, glitz_gl_enum_t primitive; glitz_gl_int_t first; glitz_gl_sizei_t count; + glitz_box_t rect; + + GLITZ_GL_SURFACE (dst); if (width <= 0 || height <= 0) return; @@ -84,64 +84,6 @@ glitz_composite (glitz_operator_t op, src = comp_op.src; mask = comp_op.mask; - - if (comp_op.type == GLITZ_COMBINE_TYPE_INTERMEDIATE) { - glitz_format_t templ; - glitz_format_t *format; - unsigned long templ_mask; - - templ.red_size = src->format->red_size; - templ.green_size = src->format->green_size; - templ.blue_size = src->format->blue_size; - templ.alpha_size = MAX (src->format->alpha_size, mask->format->alpha_size); - templ.draw.offscreen = 1; - - templ_mask = GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK | - GLITZ_FORMAT_BLUE_SIZE_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK | - GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; - - format = glitz_surface_find_similar_format (dst, templ_mask, &templ, 0); - if (!format) { - glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK); - return; - } - - intermediate = glitz_surface_create_similar (dst, format, width, height); - if (!intermediate) { - glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK); - return; - } - - glitz_composite (GLITZ_OPERATOR_SRC, - mask, NULL, intermediate, - x_mask, y_mask, - 0, 0, - 0, 0, - width, - height); - - glitz_composite (GLITZ_OPERATOR_IN, - src, NULL, intermediate, - x_src, y_src, - 0, 0, - 0, 0, - width, - height); - - src = intermediate; - mask = NULL; - x_src = y_src = 0; - - glitz_composite_op_init (&comp_op, op, src, mask, dst); - if (comp_op.type == GLITZ_COMBINE_TYPE_NA) { - glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK); - glitz_surface_destroy (intermediate); - return; - } - - src = comp_op.src; - mask = comp_op.mask; - } if (src) { stexture = glitz_surface_get_texture (src, 0); @@ -157,7 +99,7 @@ glitz_composite (glitz_operator_t op, } else mtexture = NULL; - if (!glitz_surface_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) { + if (!glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) { glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK); glitz_surface_pop_current (dst); return; @@ -202,7 +144,7 @@ glitz_composite (glitz_operator_t op, else glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_REPEAT); } else { - if ((!(dst->backend->feature_mask & + if ((!(dst->drawable->backend->feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)) || SURFACE_PAD (mask)) glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_CLAMP_TO_EDGE); @@ -235,7 +177,7 @@ glitz_composite (glitz_operator_t op, gl->load_matrix_f (SURFACE_EYE_COORDS (src)? src->transform->m: src->transform->t); gl->matrix_mode (GLITZ_GL_MODELVIEW); - + if (SURFACE_LINEAR_TRANSFORM_FILTER (src)) glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_LINEAR); else @@ -249,7 +191,7 @@ glitz_composite (glitz_operator_t op, else glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_REPEAT); } else { - if ((!(dst->backend->feature_mask & + if ((!(dst->drawable->backend->feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)) || SURFACE_PAD (src)) glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_CLAMP_TO_EDGE); @@ -258,8 +200,8 @@ glitz_composite (glitz_operator_t op, } } - gl->scissor (rect.x1, - dst->height - rect.y2, + gl->scissor (rect.x1 + dst->x, + dst->attached->height - dst->y - rect.y2, width, height); gl->push_matrix (); @@ -388,13 +330,12 @@ glitz_composite (glitz_operator_t op, if (i > 0) gl->active_texture (textures[i - 1].unit); } - - glitz_surface_dirty (dst, &rect); + + glitz_surface_damage (dst, &rect, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); glitz_surface_pop_current (dst); - - if (intermediate) - glitz_surface_destroy (intermediate); } void @@ -407,8 +348,9 @@ glitz_copy_area (glitz_surface_t *src, int x_dst, int y_dst) { - glitz_gl_proc_address_list_t *gl; - int status; + glitz_status_t status; + + GLITZ_GL_SURFACE (dst); if (x_src < 0) { x_dst -= x_src; @@ -443,35 +385,44 @@ glitz_copy_area (glitz_surface_t *src, if (width <= 0 || height <= 0) return; - gl = &dst->backend->gl; - - status = 0; - if (glitz_surface_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) { - glitz_bounding_box_t box; + status = GLITZ_STATUS_NOT_SUPPORTED; + if (glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) { + glitz_box_t box; - if (src != dst) + if (src->attached == dst->attached) { + if (REGION_NOTEMPTY (&src->drawable_damage)) { + glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT); + glitz_surface_pop_current (src); + } + status = GLITZ_STATUS_SUCCESS; + } else status = glitz_surface_make_current_read (src); - else - status = 1; box.x1 = x_dst; box.y1 = y_dst; box.x2 = box.x1 + width; box.y2 = box.y1 + height; - if (status) { - if (src->format->doublebuffer) - gl->read_buffer (src->read_buffer); + if (!status) { + gl->read_buffer (src->buffer); + gl->draw_buffer (dst->buffer); glitz_set_operator (gl, GLITZ_OPERATOR_SRC); - gl->scissor (0, 0, dst->width, dst->height); + gl->disable (GLITZ_GL_SCISSOR_TEST); - glitz_set_raster_pos (gl, x_dst, dst->height - (y_dst + height)); - gl->copy_pixels (x_src, src->height - (y_src + height), + glitz_set_raster_pos (gl, + x_dst + dst->x, + dst->attached->height - (y_dst + dst->y + height)); + gl->copy_pixels (x_src + src->x, + src->attached->height - (y_src + src->y + height), width, height, GLITZ_GL_COLOR); + + gl->enable (GLITZ_GL_SCISSOR_TEST); } else { - glitz_texture_t *texture = glitz_surface_get_texture (src, 0); + glitz_texture_t *texture; + + texture = glitz_surface_get_texture (src, 0); if (texture) { glitz_texture_bind (gl, texture); @@ -489,8 +440,8 @@ glitz_copy_area (glitz_surface_t *src, glitz_set_operator (gl, GLITZ_OPERATOR_SRC); - gl->scissor (box.x1, - dst->height - box.y2, + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, width, height); glitz_geometry_enable_default (gl, dst, &box); @@ -501,57 +452,56 @@ glitz_copy_area (glitz_surface_t *src, } } - glitz_surface_dirty (dst, &box); + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); - status = 1; + status = GLITZ_STATUS_SUCCESS; } glitz_surface_pop_current (dst); - if (!status) { - if (glitz_surface_push_current (src, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) { + if (status) { + if (glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT)) { glitz_texture_t *texture; - if (src->format->doublebuffer) - gl->read_buffer (src->read_buffer); - - gl->scissor (0, 0, src->width, src->height); + gl->read_buffer (src->buffer); texture = glitz_surface_get_texture (dst, 1); if (texture) { - glitz_texture_copy_surface (texture, src, - x_src, y_src, width, height, x_dst, y_dst); - status = 1; + glitz_box_t box; + + gl->disable (GLITZ_GL_SCISSOR_TEST); + + glitz_texture_bind (gl, texture); + + glitz_texture_copy_drawable (gl, + texture, + src->attached, + x_src + src->x, + y_src + src->y, + width, height, + x_dst, y_dst); + + glitz_texture_unbind (gl, texture); + + gl->enable (GLITZ_GL_SCISSOR_TEST); + + box.x1 = x_dst; + box.y1 = y_dst; + box.x2 = box.x1 + width; + box.y2 = box.y1 + height; + + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_DRAWABLE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + + status = GLITZ_STATUS_SUCCESS; } } glitz_surface_pop_current (src); } - if (!status) { - static glitz_pixel_format_t pf = { - { - 32, - 0xff000000, - 0x00ff0000, - 0x0000ff00, - 0x000000ff - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - }; - glitz_buffer_t *buffer = - glitz_pixel_buffer_create (src, - NULL, - width * height * 4, - GLITZ_BUFFER_HINT_STATIC_COPY); - if (!buffer) { - glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); - return; - } - - glitz_get_pixels (src, x_src, y_src, width, height, &pf, buffer); - glitz_set_pixels (dst, x_dst, y_dst, width, height, &pf, buffer); - - glitz_buffer_destroy (buffer); - } + if (status) + glitz_surface_status_add (dst, glitz_status_to_status_mask (status)); } diff --git a/src/glitz.h b/src/glitz.h index e9ddecb..1425125 100644 --- a/src/glitz.h +++ b/src/glitz.h @@ -36,10 +36,9 @@ # endif #endif -/* NOTE: Must be manually synchronized with GLITZ_VERSION in configure.in */ -#define GLITZ_MAJOR 0 -#define GLITZ_MINOR 2 -#define GLITZ_REVISION 3 +#define GLITZ_MAJOR 0 +#define GLITZ_MINOR 3 +#define GLITZ_REVISION 0 #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -53,7 +52,7 @@ typedef double glitz_double_t; typedef int glitz_fixed16_16_t; typedef struct _glitz_rectangle_t { - short x, y; + short x, y; unsigned short width, height; } glitz_rectangle_t; @@ -90,8 +89,7 @@ typedef enum { GLITZ_OPERATOR_ATOP, GLITZ_OPERATOR_ATOP_REVERSE, GLITZ_OPERATOR_XOR, - GLITZ_OPERATOR_ADD, - GLITZ_OPERATOR_SATURATE + GLITZ_OPERATOR_ADD } glitz_operator_t; #define GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 0) @@ -99,16 +97,16 @@ typedef enum { #define GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 2) #define GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK (1L << 3) #define GLITZ_FEATURE_MULTISAMPLE_MASK (1L << 4) -#define GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK (1L << 5) -#define GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK (1L << 6) -#define GLITZ_FEATURE_MULTITEXTURE_MASK (1L << 7) -#define GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK (1L << 8) -#define GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK (1L << 9) -#define GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK (1L << 10) -#define GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK (1L << 11) -#define GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK (1L << 12) -#define GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK (1L << 13) -#define GLITZ_FEATURE_BLEND_COLOR_MASK (1L << 14) +#define GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK (1L << 5) +#define GLITZ_FEATURE_MULTITEXTURE_MASK (1L << 6) +#define GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK (1L << 7) +#define GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK (1L << 8) +#define GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK (1L << 9) +#define GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK (1L << 10) +#define GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK (1L << 11) +#define GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK (1L << 12) +#define GLITZ_FEATURE_BLEND_COLOR_MASK (1L << 13) +#define GLITZ_FEATURE_PACKED_PIXELS_MASK (1L << 14) typedef enum { GLITZ_STANDARD_ARGB32, @@ -117,69 +115,155 @@ typedef enum { GLITZ_STANDARD_A1 } glitz_format_name_t; -#define GLITZ_FORMAT_ID_MASK (1L << 0) -#define GLITZ_FORMAT_RED_SIZE_MASK (1L << 6) -#define GLITZ_FORMAT_GREEN_SIZE_MASK (1L << 7) -#define GLITZ_FORMAT_BLUE_SIZE_MASK (1L << 8) -#define GLITZ_FORMAT_ALPHA_SIZE_MASK (1L << 9) -#define GLITZ_FORMAT_DEPTH_SIZE_MASK (1L << 10) -#define GLITZ_FORMAT_STENCIL_SIZE_MASK (1L << 11) -#define GLITZ_FORMAT_DOUBLEBUFFER_MASK (1L << 12) -#define GLITZ_FORMAT_READ_ONSCREEN_MASK (1L << 13) -#define GLITZ_FORMAT_READ_OFFSCREEN_MASK (1L << 14) -#define GLITZ_FORMAT_DRAW_ONSCREEN_MASK (1L << 15) -#define GLITZ_FORMAT_DRAW_OFFSCREEN_MASK (1L << 16) -#define GLITZ_FORMAT_MULTISAMPLE_MASK (1L << 17) -#define GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK (1L << 18) - -typedef unsigned long int glitz_format_id_t; - -typedef struct _glitz_drawable_type_t { - glitz_bool_t onscreen; - glitz_bool_t offscreen; -} glitz_drawable_type_t; - -typedef struct _glitz_multisample_format_t { - glitz_bool_t supported; - unsigned short samples; -} glitz_multisample_format_t; +#define GLITZ_FORMAT_ID_MASK (1L << 0) +#define GLITZ_FORMAT_RED_SIZE_MASK (1L << 1) +#define GLITZ_FORMAT_GREEN_SIZE_MASK (1L << 2) +#define GLITZ_FORMAT_BLUE_SIZE_MASK (1L << 3) +#define GLITZ_FORMAT_ALPHA_SIZE_MASK (1L << 4) -typedef struct _glitz_format_t { - glitz_format_id_t id; - +typedef unsigned long glitz_format_id_t; + +typedef struct _glitz_color_format_t { unsigned short red_size; unsigned short green_size; unsigned short blue_size; unsigned short alpha_size; - unsigned short depth_size; - unsigned short stencil_size; - - glitz_bool_t doublebuffer; - glitz_drawable_type_t read; - glitz_drawable_type_t draw; - glitz_multisample_format_t multisample; -} glitz_format_t; - -typedef struct _glitz_surface glitz_surface_t; -typedef struct _glitz_buffer glitz_buffer_t; +} glitz_color_format_t; /* glitz_status.c */ typedef enum { - GLITZ_STATUS_SUCCESS = 0, - GLITZ_STATUS_NO_MEMORY, - GLITZ_STATUS_BAD_COORDINATE, - GLITZ_STATUS_NOT_SUPPORTED, - GLITZ_STATUS_CONTENT_DESTROYED + GLITZ_STATUS_SUCCESS = 0, + GLITZ_STATUS_NO_MEMORY, + GLITZ_STATUS_BAD_COORDINATE, + GLITZ_STATUS_NOT_SUPPORTED, + GLITZ_STATUS_CONTENT_DESTROYED } glitz_status_t; const char * glitz_status_string (glitz_status_t status); + +/* glitz_drawable.c */ + +typedef struct _glitz_drawable glitz_drawable_t; + +typedef enum { + GLITZ_DRAWABLE_BUFFER_FRONT_COLOR, + GLITZ_DRAWABLE_BUFFER_BACK_COLOR +} glitz_drawable_buffer_t; + +#define GLITZ_FORMAT_DEPTH_SIZE_MASK (1L << 5) +#define GLITZ_FORMAT_STENCIL_SIZE_MASK (1L << 6) +#define GLITZ_FORMAT_DOUBLEBUFFER_MASK (1L << 7) +#define GLITZ_FORMAT_SAMPLES_MASK (1L << 8) +#define GLITZ_FORMAT_WINDOW_MASK (1L << 9) +#define GLITZ_FORMAT_PBUFFER_MASK (1L << 10) + +typedef struct _glitz_drawable_types_t { + glitz_bool_t window; + glitz_bool_t pbuffer; +} glitz_drawable_types_t; + +typedef struct _glitz_drawable_format_t { + glitz_format_id_t id; + glitz_color_format_t color; + unsigned short depth_size; + unsigned short stencil_size; + unsigned short samples; + glitz_bool_t doublebuffer; + glitz_drawable_types_t types; +} glitz_drawable_format_t; + +#define GLITZ_PBUFFER_WIDTH_MASK (1L << 0) +#define GLITZ_PBUFFER_HEIGHT_MASK (1L << 1) + +typedef struct _glitz_pbuffer_attributes_t { + unsigned int width; + unsigned int height; +} glitz_pbuffer_attributes_t; + +glitz_drawable_format_t * +glitz_find_similar_drawable_format (glitz_drawable_t *other, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count); + +glitz_drawable_t * +glitz_create_pbuffer_drawable (glitz_drawable_t *other, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask); + +void +glitz_drawable_destroy (glitz_drawable_t *drawable); + +void +glitz_drawable_reference (glitz_drawable_t *drawable); + +void +glitz_drawable_update_size (glitz_drawable_t *drawable, + unsigned int width, + unsigned int height); + +unsigned int +glitz_drawable_get_width (glitz_drawable_t *drawable); + +unsigned int +glitz_drawable_get_height (glitz_drawable_t *drawable); + +void +glitz_drawable_swap_buffers (glitz_drawable_t *drawable); + +void +glitz_drawable_flush (glitz_drawable_t *drawable); + +void +glitz_drawable_finish (glitz_drawable_t *drawable); + +unsigned long +glitz_drawable_get_features (glitz_drawable_t *drawable); + +glitz_drawable_format_t * +glitz_drawable_get_format (glitz_drawable_t *drawable); + +/* glitz_format.c */ + +#define GLITZ_FORMAT_TYPE_MASK (1L << 5) + +typedef enum { + GLITZ_FORMAT_TYPE_COLOR +} glitz_format_type_t; + +typedef struct _glitz_format_t { + glitz_format_id_t id; + glitz_format_type_t type; + glitz_color_format_t color; +} glitz_format_t; + +glitz_format_t * +glitz_find_standard_format (glitz_drawable_t *drawable, + glitz_format_name_t format_name); + +glitz_format_t * +glitz_find_format (glitz_drawable_t *drawable, + unsigned long mask, + const glitz_format_t *templ, + int count); + + /* glitz_surface.c */ +typedef struct _glitz_surface glitz_surface_t; + +glitz_surface_t * +glitz_surface_create (glitz_drawable_t *drawable, + glitz_format_t *format, + unsigned int width, + unsigned int height); + void glitz_surface_destroy (glitz_surface_t *surface); @@ -187,7 +271,26 @@ void glitz_surface_reference (glitz_surface_t *surface); void -glitz_surface_set_transform (glitz_surface_t *surface, +glitz_surface_attach (glitz_surface_t *surface, + glitz_drawable_t *drawable, + glitz_drawable_buffer_t buffer, + int x, + int y); + +void +glitz_surface_detach (glitz_surface_t *surface); + +void +glitz_surface_flush (glitz_surface_t *surface); + +glitz_drawable_t * +glitz_surface_get_drawable (glitz_surface_t *surface); + +glitz_drawable_t * +glitz_surface_get_attached_drawable (glitz_surface_t *surface); + +void +glitz_surface_set_transform (glitz_surface_t *surface, glitz_transform_t *transform); typedef enum { @@ -199,91 +302,56 @@ typedef enum { void glitz_surface_set_fill (glitz_surface_t *surface, - glitz_fill_t fill); + glitz_fill_t fill); void glitz_surface_set_component_alpha (glitz_surface_t *surface, - glitz_bool_t component_alpha); + glitz_bool_t component_alpha); void -glitz_surface_set_filter (glitz_surface_t *surface, - glitz_filter_t filter, +glitz_surface_set_filter (glitz_surface_t *surface, + glitz_filter_t filter, glitz_fixed16_16_t *params, - int n_params); - -typedef enum { - GLITZ_COLOR_BUFFER_FRONT, - GLITZ_COLOR_BUFFER_BACK -} glitz_color_buffer_t; - -void -glitz_surface_set_read_color_buffer (glitz_surface_t *surface, - glitz_color_buffer_t buffer); + int n_params); void -glitz_surface_set_draw_color_buffer (glitz_surface_t *surface, - glitz_color_buffer_t buffer); - -void -glitz_surface_swap_buffers (glitz_surface_t *surface); - -void -glitz_surface_flush (glitz_surface_t *surface); +glitz_surface_set_dither (glitz_surface_t *surface, + glitz_bool_t dither); -void -glitz_surface_finish (glitz_surface_t *surface); - -int +unsigned int glitz_surface_get_width (glitz_surface_t *surface); -int +unsigned int glitz_surface_get_height (glitz_surface_t *surface); glitz_status_t glitz_surface_get_status (glitz_surface_t *surface); -unsigned long -glitz_surface_get_features (glitz_surface_t *surface); - glitz_format_t * glitz_surface_get_format (glitz_surface_t *surface); -glitz_format_t * -glitz_surface_find_similar_standard_format (glitz_surface_t *surface, - glitz_format_name_t format_name); - -glitz_format_t * -glitz_surface_find_similar_format (glitz_surface_t *surface, - unsigned long mask, - const glitz_format_t *templ, - int count); - -glitz_surface_t * -glitz_surface_create_similar (glitz_surface_t *templ, - glitz_format_t *format, - int width, - int height); - /* glitz_rect.c */ void -glitz_set_rectangle (glitz_surface_t *dst, +glitz_set_rectangle (glitz_surface_t *dst, const glitz_color_t *color, - int x, - int y, - unsigned int width, - unsigned int height); + int x, + int y, + unsigned int width, + unsigned int height); void -glitz_set_rectangles (glitz_surface_t *dst, - const glitz_color_t *color, +glitz_set_rectangles (glitz_surface_t *dst, + const glitz_color_t *color, const glitz_rectangle_t *rects, - int n_rects); + int n_rects); /* glitz_buffer.c */ - + +typedef struct _glitz_buffer glitz_buffer_t; + typedef enum { GLITZ_BUFFER_HINT_STREAM_DRAW, GLITZ_BUFFER_HINT_STREAM_READ, @@ -303,15 +371,15 @@ typedef enum { } glitz_buffer_access_t; glitz_buffer_t * -glitz_geometry_buffer_create (glitz_surface_t *surface, - void *data, - unsigned int size, +glitz_geometry_buffer_create (glitz_drawable_t *drawable, + void *data, + unsigned int size, glitz_buffer_hint_t hint); glitz_buffer_t * -glitz_pixel_buffer_create (glitz_surface_t *surface, - void *data, - unsigned int size, +glitz_pixel_buffer_create (glitz_drawable_t *drawable, + void *data, + unsigned int size, glitz_buffer_hint_t hint); glitz_buffer_t * @@ -325,18 +393,18 @@ glitz_buffer_reference (glitz_buffer_t *buffer); void glitz_buffer_set_data (glitz_buffer_t *buffer, - int offset, - unsigned int size, - const void *data); + int offset, + unsigned int size, + const void *data); void glitz_buffer_get_data (glitz_buffer_t *buffer, - int offset, - unsigned int size, - void *data); + int offset, + unsigned int size, + void *data); void * -glitz_buffer_map (glitz_buffer_t *buffer, +glitz_buffer_map (glitz_buffer_t *buffer, glitz_buffer_access_t access); glitz_status_t @@ -351,7 +419,7 @@ typedef enum { } glitz_pixel_scanline_order_t; typedef struct _glitz_pixel_masks { - int bpp; + int bpp; unsigned long alpha_mask; unsigned long red_mask; unsigned long green_mask; @@ -359,30 +427,30 @@ typedef struct _glitz_pixel_masks { } glitz_pixel_masks_t; typedef struct _glitz_pixel_format { - glitz_pixel_masks_t masks; - int xoffset; - int skip_lines; - int bytes_per_line; + glitz_pixel_masks_t masks; + int xoffset; + int skip_lines; + int bytes_per_line; glitz_pixel_scanline_order_t scanline_order; } glitz_pixel_format_t; void -glitz_set_pixels (glitz_surface_t *dst, - int x_dst, - int y_dst, - int width, - int height, +glitz_set_pixels (glitz_surface_t *dst, + int x_dst, + int y_dst, + int width, + int height, glitz_pixel_format_t *format, - glitz_buffer_t *buffer); + glitz_buffer_t *buffer); void -glitz_get_pixels (glitz_surface_t *src, - int x_src, - int y_src, - int width, - int height, +glitz_get_pixels (glitz_surface_t *src, + int x_src, + int y_src, + int width, + int height, glitz_pixel_format_t *format, - glitz_buffer_t *buffer); + glitz_buffer_t *buffer); /* glitz_geometry.c */ @@ -400,6 +468,10 @@ typedef enum { } glitz_geometry_edge_hint_t; typedef enum { + GLITZ_GEOMETRY_PRIMITIVE_POINTS, + GLITZ_GEOMETRY_PRIMITIVE_LINES, + GLITZ_GEOMETRY_PRIMITIVE_LINE_STRIP, + GLITZ_GEOMETRY_PRIMITIVE_LINE_LOOP, GLITZ_GEOMETRY_PRIMITIVE_TRIANGLES, GLITZ_GEOMETRY_PRIMITIVE_TRIANGLE_STRIP, GLITZ_GEOMETRY_PRIMITIVE_TRIANGLE_FAN, @@ -416,47 +488,47 @@ typedef enum { } glitz_data_type_t; typedef struct _glitz_geometry_format { - glitz_geometry_mode_t mode; + glitz_geometry_mode_t mode; glitz_geometry_edge_hint_t edge_hint; glitz_geometry_primitive_t primitive; - glitz_data_type_t type; - int first; - unsigned int count; + glitz_data_type_t type; + int first; + unsigned int count; } glitz_geometry_format_t; void -glitz_set_geometry (glitz_surface_t *dst, - int x_dst, - int y_dst, +glitz_set_geometry (glitz_surface_t *dst, + glitz_fixed16_16_t x_dst, + glitz_fixed16_16_t y_dst, glitz_geometry_format_t *format, - glitz_buffer_t *buffer); + glitz_buffer_t *buffer); /* glitz.c */ void glitz_composite (glitz_operator_t op, - glitz_surface_t *src, - glitz_surface_t *mask, - glitz_surface_t *dst, - int x_src, - int y_src, - int x_mask, - int y_mask, - int x_dst, - int y_dst, - int width, - int height); + glitz_surface_t *src, + glitz_surface_t *mask, + glitz_surface_t *dst, + int x_src, + int y_src, + int x_mask, + int y_mask, + int x_dst, + int y_dst, + int width, + int height); void glitz_copy_area (glitz_surface_t *src, glitz_surface_t *dst, - int x_src, - int y_src, - int width, - int height, - int x_dst, - int y_dst); + int x_src, + int y_src, + int width, + int height, + int x_dst, + int y_dst); #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/src/glitz.pc.in b/src/glitz.pc.in new file mode 100644 index 0000000..fee3a7d --- /dev/null +++ b/src/glitz.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libglitz +Description: OpenGL compositing library +Version: @VERSION@ +Libs: -L${libdir} -lglitz -lm +Cflags: -I${includedir} diff --git a/src/glitz_agl_context.c b/src/glitz_agl_context.c deleted file mode 100644 index 04c100c..0000000 --- a/src/glitz_agl_context.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_aglint.h" - -extern glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address; - -static void -_glitz_agl_context_create (glitz_agl_thread_info_t *thread_info, - AGLPixelFormat pixel_format, - glitz_agl_context_t *context) -{ - context->context = - aglCreateContext (pixel_format, thread_info->root_context.context); - context->pixel_format = pixel_format; -} - -glitz_agl_context_t * -glitz_agl_context_get (glitz_agl_thread_info_t *thread_info, - glitz_format_t *format, - glitz_bool_t offscreen) -{ - glitz_agl_context_t *context; - glitz_agl_context_t **contexts = thread_info->contexts; - int index, n_contexts = thread_info->n_contexts; - - if (thread_info->format_ids[format->id] == (AGLPixelFormat) 0) - return &thread_info->root_context; - - for (; n_contexts; n_contexts--, contexts++) - if ((*contexts)->pixel_format == thread_info->format_ids[format->id] && - (*contexts)->offscreen == offscreen) - return *contexts; - - index = thread_info->n_contexts++; - - thread_info->contexts = - realloc (thread_info->contexts, - sizeof (glitz_agl_context_t *) * thread_info->n_contexts); - - context = malloc (sizeof (glitz_agl_context_t)); - thread_info->contexts[index] = context; - - _glitz_agl_context_create (thread_info, - thread_info->format_ids[format->id], - context); - context->offscreen = offscreen; - - glitz_agl_surface_backend_init (&context->backend); - - memcpy (&context->backend.gl, - &_glitz_agl_gl_proc_address, - sizeof (glitz_gl_proc_address_list_t)); - - context->backend.formats = thread_info->formats; - context->backend.n_formats = thread_info->n_formats; - context->backend.program_map = &thread_info->program_map; - context->backend.feature_mask = thread_info->feature_mask; - - context->backend.gl.need_lookup = 1; - - return context; -} - -void -glitz_agl_context_destroy (glitz_agl_thread_info_t *thread_info, - glitz_agl_context_t *context) -{ - aglDestroyContext (context->context); - free (context); -} - -/* These function addresses are never context specific but we retrive them - for each context anyway. */ -void -glitz_agl_context_proc_address_lookup (glitz_agl_thread_info_t *thread_info, - glitz_agl_context_t *context) -{ - CFBundleRef bundle; - - bundle = glitz_agl_get_bundle ("OpenGL.framework"); - - if (thread_info->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) { - if (thread_info->gl_version >= 1.4f) { - context->backend.gl.blend_color = (glitz_gl_blend_color_t) - glitz_agl_get_proc_address (bundle, "glBlendColor"); - } else { - context->backend.gl.blend_color = (glitz_gl_blend_color_t) - glitz_agl_get_proc_address (bundle, "glBlendColorEXT"); - } - - if (!context->backend.gl.blend_color) - context->backend.feature_mask &= ~GLITZ_FEATURE_BLEND_COLOR_MASK; - } - - if (thread_info->feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK) { - if (thread_info->gl_version >= 1.3f) { - context->backend.gl.active_texture = (glitz_gl_active_texture_t) - glitz_agl_get_proc_address (bundle, "glActiveTexture"); - } else { - context->backend.gl.active_texture = (glitz_gl_active_texture_t) - glitz_agl_get_proc_address (bundle, "glActiveTextureARB"); - } - - if (!context->backend.gl.active_texture) { - context->backend.feature_mask &= ~GLITZ_FEATURE_MULTITEXTURE_MASK; - context->backend.feature_mask &= - ~GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; - } - } - - if (thread_info->feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) { - context->backend.gl.gen_programs = (glitz_gl_gen_programs_t) - glitz_agl_get_proc_address (bundle, "glGenProgramsARB"); - context->backend.gl.delete_programs = (glitz_gl_delete_programs_t) - glitz_agl_get_proc_address (bundle, "glDeleteProgramsARB"); - context->backend.gl.program_string = (glitz_gl_program_string_t) - glitz_agl_get_proc_address (bundle, "glProgramStringARB"); - context->backend.gl.bind_program = (glitz_gl_bind_program_t) - glitz_agl_get_proc_address (bundle, "glBindProgramARB"); - context->backend.gl.program_local_param_4fv = - (glitz_gl_program_local_param_4fv_t) - glitz_agl_get_proc_address (bundle, - "glProgramLocalParameter4fvARB"); - context->backend.gl.get_program_iv = (glitz_gl_get_program_iv_t) - glitz_agl_get_proc_address (bundle, "glGetProgramivARB"); - - if ((!context->backend.gl.gen_programs) || - (!context->backend.gl.delete_programs) || - (!context->backend.gl.program_string) || - (!context->backend.gl.bind_program) || - (!context->backend.gl.program_local_param_4fv)) - context->backend.feature_mask &= ~GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK; - } - - if ((thread_info->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) || - (thread_info->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)) { - if (thread_info->gl_version >= 1.5f) { - context->backend.gl.gen_buffers = (glitz_gl_gen_buffers_t) - glitz_agl_get_proc_address (bundle, "glGenBuffers"); - context->backend.gl.delete_buffers = (glitz_gl_delete_buffers_t) - glitz_agl_get_proc_address (bundle, "glDeleteBuffers"); - context->backend.gl.bind_buffer = (glitz_gl_bind_buffer_t) - glitz_agl_get_proc_address (bundle, "glBindBuffer"); - context->backend.gl.buffer_data = (glitz_gl_buffer_data_t) - glitz_agl_get_proc_address (bundle, "glBufferData"); - context->backend.gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t) - glitz_agl_get_proc_address (bundle, "glBufferSubData"); - context->backend.gl.get_buffer_sub_data = - (glitz_gl_get_buffer_sub_data_t) - glitz_agl_get_proc_address (bundle, "glGetBufferSubData"); - context->backend.gl.map_buffer = (glitz_gl_map_buffer_t) - glitz_agl_get_proc_address (bundle, "glMapBuffer"); - context->backend.gl.unmap_buffer = (glitz_gl_unmap_buffer_t) - glitz_agl_get_proc_address (bundle, "glUnmapBuffer"); - } else { - context->backend.gl.gen_buffers = (glitz_gl_gen_buffers_t) - glitz_agl_get_proc_address (bundle, "glGenBuffersARB"); - context->backend.gl.delete_buffers = (glitz_gl_delete_buffers_t) - glitz_agl_get_proc_address (bundle, "glDeleteBuffersARB"); - context->backend.gl.bind_buffer = (glitz_gl_bind_buffer_t) - glitz_agl_get_proc_address (bundle, "glBindBufferARB"); - context->backend.gl.buffer_data = (glitz_gl_buffer_data_t) - glitz_agl_get_proc_address (bundle, "glBufferDataARB"); - context->backend.gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t) - glitz_agl_get_proc_address (bundle, "glBufferSubDataARB"); - context->backend.gl.get_buffer_sub_data = - (glitz_gl_get_buffer_sub_data_t) - glitz_agl_get_proc_address (bundle, "glGetBufferSubDataARB"); - context->backend.gl.map_buffer = (glitz_gl_map_buffer_t) - glitz_agl_get_proc_address (bundle, "glMapBufferARB"); - context->backend.gl.unmap_buffer = (glitz_gl_unmap_buffer_t) - glitz_agl_get_proc_address (bundle, "glUnmapBufferARB"); - } - - if ((!context->backend.gl.gen_buffers) || - (!context->backend.gl.delete_buffers) || - (!context->backend.gl.bind_buffer) || - (!context->backend.gl.buffer_data) || - (!context->backend.gl.buffer_sub_data) || - (!context->backend.gl.get_buffer_sub_data) || - (!context->backend.gl.map_buffer) || - (!context->backend.gl.unmap_buffer)) { - context->backend.feature_mask &= - ~GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK; - context->backend.feature_mask &= ~GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK; - } - } - - glitz_agl_release_bundle (bundle); - - context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS, - context->max_viewport_dims); - context->backend.gl.get_integer_v (GLITZ_GL_MAX_TEXTURE_SIZE, - &context->max_texture_2d_size); - - if (thread_info->feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) - context->backend.gl.get_integer_v (GLITZ_GL_MAX_RECTANGLE_TEXTURE_SIZE, - &context->max_texture_rect_size); - else - context->max_texture_rect_size = 0; - - context->backend.gl.need_lookup = 0; -} - -void -glitz_agl_context_make_current (glitz_agl_surface_t *surface, - glitz_bool_t flush) -{ - AGLContext context; - AGLDrawable drawable = (AGLDrawable) 0; - AGLPbuffer pbuffer = (AGLPbuffer) 0; - - if (flush) - glFlush (); - - if ((!surface->drawable) && (!surface->pbuffer)) { - context = surface->thread_info->root_context.context; - } else { - context = surface->context->context; - pbuffer = surface->pbuffer; - drawable = surface->drawable; - surface->base.update_mask |= GLITZ_UPDATE_ALL_MASK; - } - - if (pbuffer) - aglSetPBuffer (context, pbuffer, 0, 0, aglGetVirtualScreen (context)); - else - aglSetDrawable (context, drawable); - - aglSetCurrentContext (context); - - if (surface->context->backend.gl.need_lookup) - glitz_agl_context_proc_address_lookup (surface->thread_info, - surface->context); -} - -static void -glitz_agl_context_update (glitz_agl_surface_t *surface, - glitz_constraint_t constraint) -{ - AGLContext context = aglGetCurrentContext (); - - switch (constraint) { - case GLITZ_CN_NONE: - break; - case GLITZ_CN_ANY_CONTEXT_CURRENT: - if (context == NULL) - glitz_agl_context_make_current (surface, 0); - break; - case GLITZ_CN_SURFACE_CONTEXT_CURRENT: - if (context != surface->context->context) - glitz_agl_context_make_current (surface, (context)? 1: 0); - break; - case GLITZ_CN_SURFACE_DRAWABLE_CURRENT: - if (context != surface->context->context) { - glitz_agl_context_make_current (surface, (context)? 1: 0); - } else { - if (surface->pbuffer) { - AGLPbuffer pbuffer; - GLuint unused; - - aglGetPBuffer (surface->context->context, &pbuffer, - &unused, &unused, &unused); - - if (pbuffer != surface->pbuffer) - glitz_agl_context_make_current (surface, (context)? 1: 0); - - } else if (surface->drawable) { - if (aglGetDrawable (surface->context->context) != surface->drawable) - glitz_agl_context_make_current (surface, (context)? 1: 0); - } - } - break; - } -} - -glitz_agl_surface_t * -glitz_agl_context_push_current (glitz_agl_surface_t *surface, - glitz_constraint_t constraint) -{ - glitz_agl_thread_info_t *thread_info; - glitz_agl_context_info_t *context_info; - int index; - - thread_info = surface->thread_info; - - index = thread_info->context_stack_size++; - - context_info = &thread_info->context_stack[index]; - context_info->surface = surface; - context_info->constraint = constraint; - - glitz_agl_context_update (context_info->surface, constraint); - - if (context_info->constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT) - return context_info->surface; - - return NULL; -} - -glitz_agl_surface_t * -glitz_agl_context_pop_current (glitz_agl_surface_t *surface) -{ - glitz_agl_thread_info_t *thread_info; - glitz_agl_context_info_t *context_info = NULL; - int index; - - thread_info = surface->thread_info; - - thread_info->context_stack_size--; - index = thread_info->context_stack_size - 1; - - context_info = &thread_info->context_stack[index]; - - if (context_info->surface) - glitz_agl_context_update (context_info->surface, context_info->constraint); - - if (context_info->constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT) - return context_info->surface; - - return NULL; -} diff --git a/src/glitz_agl_extension.c b/src/glitz_agl_extension.c deleted file mode 100644 index 99efa18..0000000 --- a/src/glitz_agl_extension.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_aglint.h" - -extern glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address; - -static glitz_extension_map gl_extensions[] = { - { 0.0, "GL_APPLE_pixel_buffer", GLITZ_AGL_FEATURE_PBUFFER_MASK }, - { 0.0, "GL_ARB_texture_rectangle", - GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_EXT_texture_rectangle", - GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_NV_texture_rectangle", GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_ARB_texture_non_power_of_two", - GLITZ_AGL_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK }, - { 0.0, "GL_ARB_texture_mirrored_repeat", - GLITZ_AGL_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK }, - { 0.0, "GL_ARB_texture_border_clamp", - GLITZ_AGL_FEATURE_TEXTURE_BORDER_CLAMP_MASK }, - { 0.0, "GL_ARB_texture_env_combine", - GLITZ_AGL_FEATURE_TEXTURE_ENV_COMBINE_MASK }, - { 0.0, "GL_EXT_texture_env_combine", - GLITZ_AGL_FEATURE_TEXTURE_ENV_COMBINE_MASK }, - { 0.0, "GL_ARB_texture_env_dot3", GLITZ_AGL_FEATURE_TEXTURE_ENV_DOT3_MASK }, - { 0.0, "GL_ARB_multisample", GLITZ_AGL_FEATURE_MULTISAMPLE_MASK }, - { 0.0, "GL_NV_multisample_filter_hint", - GLITZ_AGL_FEATURE_MULTISAMPLE_FILTER_HINT_MASK }, - { 0.0, "GL_ARB_multitexture", GLITZ_AGL_FEATURE_MULTITEXTURE_MASK }, - { 0.0, "GL_ARB_fragment_program", GLITZ_AGL_FEATURE_FRAGMENT_PROGRAM_MASK }, - { 0.0, "GL_ARB_vertex_buffer_object", - GLITZ_AGL_FEATURE_VERTEX_BUFFER_OBJECT_MASK }, - { 0.0, "GL_EXT_pixel_buffer_object", - GLITZ_AGL_FEATURE_PIXEL_BUFFER_OBJECT_MASK }, - { 0.0, "GL_EXT_blend_color", - GLITZ_AGL_FEATURE_BLEND_COLOR_MASK }, - { 0.0, "GL_ARB_imaging", - GLITZ_AGL_FEATURE_BLEND_COLOR_MASK }, - { 0.0, NULL, 0 } -}; - -static unsigned long -_glitz_agl_extension_query_gl (glitz_gl_float_t gl_version) -{ - const char *gl_extensions_string; - - gl_extensions_string = (const char *) glGetString (GL_EXTENSIONS); - - return glitz_extensions_query (gl_version, - gl_extensions_string, - gl_extensions); -} - -glitz_status_t -glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info) -{ - thread_info->gl_version = atof ((const char *) glGetString (GL_VERSION)); - if (thread_info->gl_version < 1.2) - return GLITZ_STATUS_NOT_SUPPORTED; - - thread_info->agl_feature_mask = 0; - - thread_info->agl_feature_mask |= - _glitz_agl_extension_query_gl (thread_info->gl_version); - - thread_info->feature_mask = 0; - - if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTISAMPLE_MASK) { - thread_info->feature_mask |= GLITZ_FEATURE_MULTISAMPLE_MASK; - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_MULTISAMPLE_FILTER_HINT_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK; - - /* - if (strcmp ("Card supporting pbuffer multisampling", - glGetString (GL_RENDERER))) - thread_info->feature_mask |= GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK; - */ - } - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK; - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK; - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK; - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_TEXTURE_BORDER_CLAMP_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK; - - if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_MULTITEXTURE_MASK) { - thread_info->feature_mask |= GLITZ_FEATURE_MULTITEXTURE_MASK; - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_TEXTURE_ENV_COMBINE_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK; - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_TEXTURE_ENV_DOT3_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK; - - if ((thread_info->feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) && - (thread_info->feature_mask & GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK)) { - GLint max_texture_units; - - glGetIntegerv (GLITZ_GL_MAX_TEXTURE_UNITS, &max_texture_units); - if (max_texture_units >= 3) - thread_info->feature_mask |= - GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; - } - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_FRAGMENT_PROGRAM_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK; - } - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_VERTEX_BUFFER_OBJECT_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK; - - if (thread_info->agl_feature_mask & - GLITZ_AGL_FEATURE_PIXEL_BUFFER_OBJECT_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK; - - if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_BLEND_COLOR_MASK) - thread_info->feature_mask |= GLITZ_FEATURE_BLEND_COLOR_MASK; - - return GLITZ_STATUS_SUCCESS; -} diff --git a/src/glitz_agl_format.c b/src/glitz_agl_format.c deleted file mode 100644 index 1b945b9..0000000 --- a/src/glitz_agl_format.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_aglint.h" - -#include <stdlib.h> - -extern glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address; - -static const struct _glx_pixel_format_attrib { - GLint attrib[20]; -} pixel_format_attrib_map[] = { - { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_ALPHA_SIZE, 0, - AGL_NO_RECOVERY, - AGL_NONE, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_ALPHA_SIZE, 8, - AGL_NO_RECOVERY, - AGL_NONE, 0, 0, 0, 0, 0, 0, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_NO_RECOVERY, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 2, - AGL_NONE, 0, 0, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_NO_RECOVERY, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 4, - AGL_NONE, 0, 0, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_ALPHA_SIZE, 0, - AGL_DEPTH_SIZE, 1, - AGL_NO_RECOVERY, - AGL_NONE, 0, 0, 0, 0, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_ALPHA_SIZE, 8, - AGL_DEPTH_SIZE, 1, - AGL_NO_RECOVERY, - AGL_NONE, 0, 0, 0, 0, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_DEPTH_SIZE, 1, - AGL_NO_RECOVERY, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 2, - AGL_NONE, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_DEPTH_SIZE, 1, - AGL_NO_RECOVERY, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 4, - AGL_NONE, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_ALPHA_SIZE, 0, - AGL_DEPTH_SIZE, 1, - AGL_STENCIL_SIZE, 2, - AGL_NO_RECOVERY, - AGL_NONE, 0, 0, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_ALPHA_SIZE, 8, - AGL_DEPTH_SIZE, 1, - AGL_STENCIL_SIZE, 2, - AGL_NO_RECOVERY, - AGL_NONE, 0, 0, 0, 0 - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_DEPTH_SIZE, 1, - AGL_STENCIL_SIZE, 2, - AGL_NO_RECOVERY, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 2, - AGL_NONE, - } - }, { - { - AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_RED_SIZE, 8, - AGL_GREEN_SIZE, 8, - AGL_BLUE_SIZE, 8, - AGL_DEPTH_SIZE, 1, - AGL_STENCIL_SIZE, 2, - AGL_NO_RECOVERY, - AGL_SAMPLE_BUFFERS_ARB, 1, - AGL_SAMPLES_ARB, 4, - AGL_NONE, - } - }, { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - } - } -}; - -static int -_glitz_agl_format_compare (const void *elem1, - const void *elem2) -{ - int i, score[2]; - glitz_format_t *format[2]; - - format[0] = (glitz_format_t *) elem1; - format[1] = (glitz_format_t *) elem2; - i = score[0] = score[1] = 0; - - for (; i < 2; i++) { - if (format[i]->red_size) - score[i] += 10; - if (format[i]->alpha_size) - score[i] += 10; - if (format[i]->stencil_size) - score[i] += (10 + format[i]->stencil_size); - if (format[i]->multisample.supported) - score[i] -= (10 - format[i]->multisample.samples); - } - - return score[1] - score[0]; -} - -static void -_glitz_add_format (glitz_agl_thread_info_t *thread_info, - glitz_format_t *format) -{ - if (!glitz_format_find (thread_info->formats, thread_info->n_formats, - GLITZ_FORMAT_ALL_EXCEPT_ID_MASK, format, 0)) { - int index = thread_info->n_formats++; - - thread_info->formats = - realloc (thread_info->formats, - sizeof (glitz_format_t) * thread_info->n_formats); - - thread_info->formats[index] = *format; - } -} - -static void -_glitz_move_out_ids (glitz_agl_thread_info_t *thread_info) -{ - int i; - glitz_format_t *formats = thread_info->formats; - int n_formats = thread_info->n_formats; - - thread_info->format_ids = malloc (sizeof (AGLPixelFormat) * n_formats); - - for (i = 0; n_formats; n_formats--, formats++) { - thread_info->format_ids[i] = (AGLPixelFormat) formats->id; - formats->id = i++; - } -} - -static void -_glitz_agl_add_texture_format (glitz_format_t *texture_format, void *ptr) -{ - glitz_agl_thread_info_t *thread_info = (glitz_agl_thread_info_t *) ptr; - glitz_format_t format; - - format = *texture_format; - format.id = 0; - - _glitz_add_format (thread_info, &format); -} - -void -glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info) -{ - glitz_format_t format; - AGLPixelFormat pixel_format; - int i = 0; - - for (i = 0; *(pixel_format_attrib_map[i].attrib); i++) { - GLint value; - - pixel_format = aglChoosePixelFormat (NULL, 0, - pixel_format_attrib_map[i].attrib); - - /* Stereo is not supported yet */ - if (!(aglDescribePixelFormat (pixel_format, AGL_STEREO, &value)) || - value) { - aglDestroyPixelFormat (pixel_format); - continue; - } - - aglDescribePixelFormat (pixel_format, AGL_DOUBLEBUFFER, &value); - format.doublebuffer = (value)? 1: 0; - - /* We don't support single buffering in MacOS X */ - if (!format.doublebuffer) { - aglDestroyPixelFormat (pixel_format); - continue; - } - - format.id = (unsigned long int) pixel_format; - - format.read.onscreen = format.draw.onscreen = 1; - if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_PBUFFER_MASK) - format.read.offscreen = format.draw.offscreen = 1; - else - format.read.offscreen = format.draw.offscreen = 0; - - aglDescribePixelFormat (pixel_format, AGL_RED_SIZE, &value); - format.red_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_GREEN_SIZE, &value); - format.green_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_BLUE_SIZE, &value); - format.blue_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_ALPHA_SIZE, &value); - format.alpha_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_DEPTH_SIZE, &value); - format.depth_size = (unsigned short) value; - aglDescribePixelFormat (pixel_format, AGL_STENCIL_SIZE, &value); - format.stencil_size = (unsigned short) value; - - if (thread_info->feature_mask & GLITZ_FEATURE_MULTISAMPLE_MASK) { - aglDescribePixelFormat (pixel_format, AGL_SAMPLE_BUFFERS_ARB, &value); - format.multisample.supported = (value)? 1: 0; - aglDescribePixelFormat (pixel_format, AGL_SAMPLES_ARB, &value); - format.multisample.samples = (unsigned short) value; - - if (format.multisample.supported) { - if (!(thread_info->feature_mask & - GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK)) - format.read.offscreen = format.draw.offscreen = 0; - } - } else { - format.multisample.supported = 0; - format.multisample.samples = 0; - } - - if (format.red_size || format.green_size || format.blue_size || - format.alpha_size) - _glitz_add_format (thread_info, &format); - } - - qsort (thread_info->formats, thread_info->n_formats, - sizeof (glitz_format_t), _glitz_agl_format_compare); - - glitz_format_for_each_texture_format (&_glitz_agl_add_texture_format, - &_glitz_agl_gl_proc_address, - (void *) thread_info); - - _glitz_move_out_ids (thread_info); -} - -glitz_format_t * -glitz_agl_find_format (unsigned long mask, - const glitz_format_t *templ, - int count) -{ - glitz_agl_thread_info_t *thread_info = glitz_agl_thread_info_get (); - - return glitz_format_find (thread_info->formats, thread_info->n_formats, - mask, templ, count); -} -slim_hidden_def(glitz_agl_find_format); - -glitz_format_t * -glitz_agl_find_standard_format (glitz_format_name_t format_name) -{ - glitz_agl_thread_info_t *thread_info = glitz_agl_thread_info_get (); - - return - glitz_format_find_standard (thread_info->formats, thread_info->n_formats, - format_name); -} -slim_hidden_def(glitz_agl_find_standard_format); diff --git a/src/glitz_agl_pbuffer.c b/src/glitz_agl_pbuffer.c deleted file mode 100644 index 0e8f3af..0000000 --- a/src/glitz_agl_pbuffer.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_aglint.h" - -extern glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address; - -AGLPbuffer -glitz_agl_pbuffer_create (glitz_texture_t *texture) -{ - AGLPbuffer pbuffer; - - aglCreatePBuffer (texture->width, texture->height, - texture->target, texture->format, 0, &pbuffer); - - return pbuffer; -} - -void -glitz_agl_pbuffer_destroy (AGLPbuffer pbuffer) -{ - aglDestroyPBuffer (pbuffer); -} diff --git a/src/glitz_agl_surface.c b/src/glitz_agl_surface.c deleted file mode 100644 index 47da21a..0000000 --- a/src/glitz_agl_surface.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_aglint.h" - -static glitz_bool_t -_glitz_agl_surface_push_current (void *abstract_surface, - glitz_constraint_t constraint) -{ - glitz_agl_surface_t *surface = (glitz_agl_surface_t *) abstract_surface; - glitz_bool_t success = 1; - - if (constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT && - (!surface->pbuffer) && (!surface->drawable)) { - if (surface->base.format->draw.offscreen) { - surface->pbuffer = glitz_agl_pbuffer_create (&surface->base.texture); - } else { - constraint = GLITZ_CN_ANY_CONTEXT_CURRENT; - success = 0; - } - } - - surface = glitz_agl_context_push_current (surface, constraint); - - if (surface) { - glitz_surface_update_state (&surface->base); - return 1; - } - - return success; -} - -static void -_glitz_agl_surface_pop_current (void *abstract_surface) -{ - glitz_agl_surface_t *surface = (glitz_agl_surface_t *) abstract_surface; - - surface = glitz_agl_context_pop_current (surface); - - if (surface) - glitz_surface_update_state (&surface->base); -} - -static glitz_bool_t -_glitz_agl_surface_make_current_read (void *abstract_surface) -{ - return 0; -} - -static glitz_texture_t * -_glitz_agl_surface_get_texture (void *abstract_surface, - glitz_bool_t allocate) { - glitz_agl_surface_t *surface = (glitz_agl_surface_t *) abstract_surface; - - if (surface->base.flags & GLITZ_SURFACE_FLAG_DIRTY_MASK) { - glitz_bounding_box_t copy_box; - - copy_box.x1 = copy_box.y1 = 0; - copy_box.x2 = surface->base.width; - copy_box.y2 = surface->base.height; - glitz_intersect_bounding_box (&surface->base.dirty_box, - ©_box, ©_box); - - if (!(TEXTURE_ALLOCATED (&surface->base.texture))) - glitz_texture_allocate (&surface->base.backend->gl, - &surface->base.texture); - - glitz_texture_copy_surface (&surface->base.texture, &surface->base, - copy_box.x1, - copy_box.y1, - copy_box.x2 - copy_box.x1, - copy_box.y2 - copy_box.y1, - copy_box.x1, - copy_box.y1); - - surface->base.flags &= ~GLITZ_SURFACE_FLAG_DIRTY_MASK; - } - - if (allocate) { - if (!(TEXTURE_ALLOCATED (&surface->base.texture))) - glitz_texture_allocate (&surface->base.backend->gl, - &surface->base.texture); - } - - if (TEXTURE_ALLOCATED (&surface->base.texture)) - return &surface->base.texture; - else - return NULL; -} - -static glitz_surface_t * -_glitz_agl_surface_create (glitz_agl_thread_info_t *thread_info, - glitz_format_t *format, - int width, - int height) -{ - glitz_agl_surface_t *surface; - glitz_agl_context_t *context; - - if (width <= 0 || height <= 0) - return NULL; - - context = glitz_agl_context_get (thread_info, format, 1); - if (!context) - return NULL; - - surface = (glitz_agl_surface_t *) calloc (1, sizeof (glitz_agl_surface_t)); - if (surface == NULL) - return NULL; - - glitz_surface_init (&surface->base, - &context->backend, - format, - width, - height); - - surface->thread_info = thread_info; - surface->context = context; - - surface->base.flags |= GLITZ_SURFACE_FLAG_OFFSCREEN_MASK; - - if (format->draw.offscreen) - surface->base.flags |= GLITZ_SURFACE_FLAG_DRAWABLE_MASK; - - if (surface->context->backend.gl.need_lookup) { - glitz_agl_context_push_current (surface, GLITZ_CN_SURFACE_CONTEXT_CURRENT); - glitz_agl_context_pop_current (surface); - } - - if (width > 64 || height > 64) { - glitz_agl_context_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT); - glitz_texture_size_check (&surface->base.backend->gl, - &surface->base.texture, - context->max_texture_2d_size, - context->max_texture_rect_size); - glitz_agl_context_pop_current (surface); - if (TEXTURE_INVALID_SIZE (&surface->base.texture) || - (format->draw.offscreen && - ((width > context->max_viewport_dims[0]) || - (height > context->max_viewport_dims[1])))) { - glitz_surface_destroy (&surface->base); - return NULL; - } - } - - return &surface->base; -} - -glitz_surface_t * -glitz_agl_surface_create (glitz_format_t *format, - int width, - int height) -{ - glitz_agl_thread_info_t *thread_info; - - thread_info = glitz_agl_thread_info_get (); - if (!thread_info) - return NULL; - - return _glitz_agl_surface_create (thread_info, format, width, height); -} -slim_hidden_def(glitz_agl_surface_create_offscreen); - -glitz_surface_t * -glitz_agl_surface_create_for_window (glitz_format_t *format, - WindowRef window, - int width, - int height) -{ - glitz_agl_surface_t *surface; - glitz_agl_context_t *context; - glitz_agl_thread_info_t *thread_info; - AGLDrawable drawable; - - if (width <= 0 || height <= 0) - return NULL; - - drawable = GetWindowPort (window); - if (!drawable) - return NULL; - - thread_info = glitz_agl_thread_info_get (); - if (!thread_info) - return NULL; - - context = glitz_agl_context_get (thread_info, format, 0); - if (!context) - return NULL; - - surface = (glitz_agl_surface_t *) calloc (1, sizeof (glitz_agl_surface_t)); - if (surface == NULL) - return NULL; - - glitz_surface_init (&surface->base, - &context->backend, - format, - width, - height); - - surface->thread_info = thread_info; - surface->context = context; - surface->window = window; - surface->drawable = drawable; - - surface->base.flags |= GLITZ_SURFACE_FLAG_DRAWABLE_MASK; - - if (surface->context->backend.gl.need_lookup) { - glitz_agl_context_push_current (surface, GLITZ_CN_SURFACE_CONTEXT_CURRENT); - glitz_agl_context_pop_current (surface); - } - - if (width > 64 || height > 64) { - glitz_agl_context_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT); - glitz_texture_size_check (&surface->base.backend->gl, - &surface->base.texture, - context->max_texture_2d_size, - context->max_texture_rect_size); - glitz_agl_context_pop_current (surface); - if (TEXTURE_INVALID_SIZE (&surface->base.texture) || - (width > context->max_viewport_dims[0]) || - (height > context->max_viewport_dims[1])) { - glitz_surface_destroy (&surface->base); - return NULL; - } - } - - return &surface->base; -} -slim_hidden_def(glitz_agl_surface_create_for_window); - -static glitz_surface_t * -_glitz_agl_surface_create_similar (void *abstract_templ, - glitz_format_t *format, - int width, - int height) -{ - glitz_agl_surface_t *templ = (glitz_agl_surface_t *) abstract_templ; - - if (!format->read.offscreen) - return NULL; - - return _glitz_agl_surface_create (templ->thread_info, format, width, height); -} - -static void -_glitz_agl_surface_destroy (void *abstract_surface) -{ - glitz_agl_surface_t *surface = (glitz_agl_surface_t *) abstract_surface; - - glitz_surface_fini (&surface->base); - - if (surface->drawable || surface->pbuffer) { - AGLContext context = aglGetCurrentContext (); - - if (context == surface->context->context) { - if (surface->pbuffer) { - AGLPbuffer pbuffer; - GLuint unused; - - aglGetPBuffer (context, &pbuffer, &unused, &unused, &unused); - - if (pbuffer == surface->pbuffer) - glitz_agl_context_make_current (surface, 0); - } else { - if (aglGetDrawable (context) == surface->drawable) - glitz_agl_context_make_current (surface, 0); - } - } - - if (surface->pbuffer) - glitz_agl_pbuffer_destroy (surface->pbuffer); - } - - free (surface); -} - -static void -_glitz_agl_surface_swap_buffers (void *abstract_surface) -{ - glitz_agl_surface_t *surface = (glitz_agl_surface_t *) abstract_surface; - - glitz_agl_context_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT); - - aglSwapBuffers (surface->context->context); - - glitz_agl_context_pop_current (surface); -} - -void -glitz_agl_surface_backend_init (glitz_surface_backend_t *backend) -{ - backend->create_similar = _glitz_agl_surface_create_similar; - backend->destroy = _glitz_agl_surface_destroy; - backend->push_current = _glitz_agl_surface_push_current; - backend->pop_current = _glitz_agl_surface_pop_current; - backend->get_texture = _glitz_agl_surface_get_texture; - backend->swap_buffers = _glitz_agl_surface_swap_buffers; - backend->make_current_read = _glitz_agl_surface_make_current_read; -} diff --git a/src/glitz_aglint.h b/src/glitz_aglint.h deleted file mode 100644 index 5f5ff77..0000000 --- a/src/glitz_aglint.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifndef GLITZ_AGLINT_H_INCLUDED -#define GLITZ_AGLINT_H_INCLUDED - -#include "glitzint.h" - -#include "glitz-agl.h" - -#include <OpenGL/gl.h> -#include <Carbon/Carbon.h> -#include <AGL/agl.h> - -#define GLITZ_AGL_FEATURE_PBUFFER_MASK (1L << 0) -#define GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 1) -#define GLITZ_AGL_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK (1L << 2) -#define GLITZ_AGL_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 3) -#define GLITZ_AGL_FEATURE_TEXTURE_BORDER_CLAMP_MASK (1L << 4) -#define GLITZ_AGL_FEATURE_MULTISAMPLE_MASK (1L << 5) -#define GLITZ_AGL_FEATURE_MULTISAMPLE_FILTER_HINT_MASK (1L << 6) -#define GLITZ_AGL_FEATURE_MULTITEXTURE_MASK (1L << 7) -#define GLITZ_AGL_FEATURE_TEXTURE_ENV_COMBINE_MASK (1L << 8) -#define GLITZ_AGL_FEATURE_TEXTURE_ENV_DOT3_MASK (1L << 9) -#define GLITZ_AGL_FEATURE_FRAGMENT_PROGRAM_MASK (1L << 10) -#define GLITZ_AGL_FEATURE_VERTEX_BUFFER_OBJECT_MASK (1L << 11) -#define GLITZ_AGL_FEATURE_PIXEL_BUFFER_OBJECT_MASK (1L << 12) -#define GLITZ_AGL_FEATURE_BLEND_COLOR_MASK (1L << 13) - -typedef struct _glitz_agl_surface_t glitz_agl_surface_t; - -typedef struct _glitz_agl_context_info_t { - glitz_agl_surface_t *surface; - glitz_constraint_t constraint; -} glitz_agl_context_info_t; - -typedef struct _glitz_agl_context_t { - AGLContext context; - AGLPixelFormat pixel_format; - glitz_bool_t offscreen; - glitz_surface_backend_t backend; - glitz_gl_int_t max_viewport_dims[2]; - glitz_gl_int_t max_texture_2d_size; - glitz_gl_int_t max_texture_rect_size; -} glitz_agl_context_t; - -typedef struct _glitz_agl_thread_info_t { - glitz_format_t *formats; - AGLPixelFormat *format_ids; - int n_formats; - - glitz_agl_context_t **contexts; - int n_contexts; - - glitz_agl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; - int context_stack_size; - - glitz_agl_context_t root_context; - - unsigned long feature_mask; - unsigned long agl_feature_mask; - glitz_gl_float_t gl_version; - - glitz_program_map_t program_map; -} glitz_agl_thread_info_t; - -struct _glitz_agl_surface_t { - glitz_surface_t base; - - glitz_agl_thread_info_t *thread_info; - glitz_agl_context_t *context; - AGLDrawable drawable; - AGLPbuffer pbuffer; - WindowRef window; - glitz_gl_enum_t bound_buffer; -}; - -extern glitz_status_t __internal_linkage -glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info); - -extern glitz_agl_thread_info_t *__internal_linkage -glitz_agl_thread_info_get (void); - -extern CFBundleRef __internal_linkage -glitz_agl_get_bundle (const char *name); - -extern void __internal_linkage -glitz_agl_release_bundle (CFBundleRef bundle); - -extern glitz_function_pointer_t __internal_linkage -glitz_agl_get_proc_address (CFBundleRef bundle, const char *name); - -extern glitz_agl_context_t *__internal_linkage -glitz_agl_context_get (glitz_agl_thread_info_t *thread_info, - glitz_format_t *format, - glitz_bool_t offscreen); - -extern void __internal_linkage -glitz_agl_context_destroy (glitz_agl_thread_info_t *thread_info, - glitz_agl_context_t *context); - -extern void __internal_linkage -glitz_agl_context_make_current (glitz_agl_surface_t *surface, - glitz_bool_t flush); - -extern glitz_agl_surface_t *__internal_linkage -glitz_agl_context_push_current (glitz_agl_surface_t *surface, - glitz_constraint_t constraint); - -extern glitz_agl_surface_t *__internal_linkage -glitz_agl_context_pop_current (glitz_agl_surface_t *surface); - -extern void __internal_linkage -glitz_agl_context_proc_address_lookup (glitz_agl_thread_info_t *thread_info, - glitz_agl_context_t *context); - -extern void __internal_linkage -glitz_agl_query_formats (glitz_agl_thread_info_t *thread_info); - -extern AGLPbuffer __internal_linkage -glitz_agl_pbuffer_create (glitz_texture_t *texture); - -extern void __internal_linkage -glitz_agl_pbuffer_destroy (AGLPbuffer pbuffer); - -extern void __internal_linkage -glitz_agl_surface_backend_init (glitz_surface_backend_t *backend); - - -/* Avoid unnecessary PLT entries. */ - -slim_hidden_proto(glitz_agl_init) -slim_hidden_proto(glitz_agl_fini) -slim_hidden_proto(glitz_agl_find_format) -slim_hidden_proto(glitz_agl_find_standard_format) -slim_hidden_proto(glitz_agl_surface_create) -slim_hidden_proto(glitz_agl_surface_create_for_window) - -#endif /* GLITZ_AGLINT_H_INCLUDED */ diff --git a/src/glitz_buffer.c b/src/glitz_buffer.c index f27ee61..32abc2d 100644 --- a/src/glitz_buffer.c +++ b/src/glitz_buffer.c @@ -30,17 +30,17 @@ #include "glitzint.h" static glitz_status_t -_glitz_buffer_init (glitz_buffer_t *buffer, - glitz_surface_t *surface, - void *data, - unsigned int size, +_glitz_buffer_init (glitz_buffer_t *buffer, + glitz_drawable_t *drawable, + void *data, + unsigned int size, glitz_buffer_hint_t hint) { glitz_gl_enum_t usage; buffer->ref_count = 1; buffer->name = 0; - + switch (hint) { case GLITZ_BUFFER_HINT_STREAM_DRAW: usage = GLITZ_GL_STREAM_DRAW; @@ -71,21 +71,26 @@ _glitz_buffer_init (glitz_buffer_t *buffer, break; } - if (surface) { - buffer->surface = surface; - glitz_surface_reference (surface); + if (drawable) { + + GLITZ_GL_DRAWABLE (drawable); + + buffer->drawable = drawable; + glitz_drawable_reference (drawable); - glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT); + drawable->backend->push_current (drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); - surface->backend->gl.gen_buffers (1, &buffer->name); + gl->gen_buffers (1, &buffer->name); if (buffer->name) { - surface->backend->gl.bind_buffer (buffer->target, buffer->name); - surface->backend->gl.buffer_data (buffer->target, size, data, usage); - surface->backend->gl.bind_buffer (buffer->target, 0); + gl->bind_buffer (buffer->target, buffer->name); + gl->buffer_data (buffer->target, size, data, usage); + gl->bind_buffer (buffer->target, 0); } - glitz_surface_pop_current (buffer->surface); + + drawable->backend->pop_current (drawable); } else - buffer->surface = NULL; + buffer->drawable = NULL; if (size > 0 && buffer->name == 0) { buffer->data = malloc (size); @@ -105,9 +110,9 @@ _glitz_buffer_init (glitz_buffer_t *buffer, } glitz_buffer_t * -glitz_geometry_buffer_create (glitz_surface_t *surface, - void *data, - unsigned int size, +glitz_geometry_buffer_create (glitz_drawable_t *drawable, + void *data, + unsigned int size, glitz_buffer_hint_t hint) { glitz_buffer_t *buffer; @@ -116,14 +121,15 @@ glitz_geometry_buffer_create (glitz_surface_t *surface, if (size == 0) return NULL; - buffer = malloc (sizeof (glitz_buffer_t)); + buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); if (buffer == NULL) return NULL; buffer->target = GLITZ_GL_ARRAY_BUFFER; - - if (surface->backend->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) - status = _glitz_buffer_init (buffer, surface, data, size, hint); + + if (drawable->backend->feature_mask & + GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) + status = _glitz_buffer_init (buffer, drawable, data, size, hint); else status = _glitz_buffer_init (buffer, NULL, data, size, hint); @@ -136,9 +142,9 @@ glitz_geometry_buffer_create (glitz_surface_t *surface, } glitz_buffer_t * -glitz_pixel_buffer_create (glitz_surface_t *surface, - void *data, - unsigned int size, +glitz_pixel_buffer_create (glitz_drawable_t *drawable, + void *data, + unsigned int size, glitz_buffer_hint_t hint) { glitz_buffer_t *buffer; @@ -147,7 +153,7 @@ glitz_pixel_buffer_create (glitz_surface_t *surface, if (size == 0) return NULL; - buffer = malloc (sizeof (glitz_buffer_t)); + buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); if (buffer == NULL) return NULL; @@ -162,8 +168,8 @@ glitz_pixel_buffer_create (glitz_surface_t *surface, break; } - if (surface->backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK) - status = _glitz_buffer_init (buffer, surface, data, size, hint); + if (drawable->backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK) + status = _glitz_buffer_init (buffer, drawable, data, size, hint); else status = _glitz_buffer_init (buffer, NULL, data, size, hint); @@ -183,7 +189,7 @@ glitz_buffer_create_for_data (void *data) if (data == NULL) return NULL; - buffer = malloc (sizeof (glitz_buffer_t)); + buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); if (buffer == NULL) return NULL; @@ -205,11 +211,12 @@ glitz_buffer_destroy (glitz_buffer_t *buffer) if (buffer->ref_count) return; - if (buffer->surface) { - glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT); - buffer->surface->backend->gl.delete_buffers (1, &buffer->name); - glitz_surface_pop_current (buffer->surface); - glitz_surface_destroy (buffer->surface); + if (buffer->drawable) { + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + buffer->drawable->backend->gl.delete_buffers (1, &buffer->name); + buffer->drawable->backend->pop_current (buffer->drawable); + glitz_drawable_destroy (buffer->drawable); } else if (buffer->owns_data) free (buffer->data); @@ -227,19 +234,19 @@ glitz_buffer_reference (glitz_buffer_t *buffer) void glitz_buffer_set_data (glitz_buffer_t *buffer, - int offset, - unsigned int size, - const void *data) + int offset, + unsigned int size, + const void *data) { - if (buffer->surface) { - glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT); - - buffer->surface->backend->gl.bind_buffer (buffer->target, buffer->name); - buffer->surface->backend->gl.buffer_sub_data (buffer->target, - offset, size, data); - buffer->surface->backend->gl.bind_buffer (buffer->target, 0); + if (buffer->drawable) { + GLITZ_GL_DRAWABLE (buffer->drawable); - glitz_surface_pop_current (buffer->surface); + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + gl->bind_buffer (buffer->target, buffer->name); + gl->buffer_sub_data (buffer->target, offset, size, data); + gl->bind_buffer (buffer->target, 0); + buffer->drawable->backend->pop_current (buffer->drawable); } else if (buffer->data) memcpy ((char *) buffer->data + offset, data, size); } @@ -247,34 +254,39 @@ slim_hidden_def(glitz_buffer_set_data); void glitz_buffer_get_data (glitz_buffer_t *buffer, - int offset, - unsigned int size, - void *data) + int offset, + unsigned int size, + void *data) { - if (buffer->surface) { - glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT); + if (buffer->drawable) { + GLITZ_GL_DRAWABLE (buffer->drawable); - buffer->surface->backend->gl.bind_buffer (buffer->target, buffer->name); - buffer->surface->backend->gl.get_buffer_sub_data (buffer->target, - offset, size, data); - buffer->surface->backend->gl.bind_buffer (buffer->target, 0); + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); - glitz_surface_pop_current (buffer->surface); + gl->bind_buffer (buffer->target, buffer->name); + gl->get_buffer_sub_data (buffer->target, offset, size, data); + gl->bind_buffer (buffer->target, 0); + + buffer->drawable->backend->pop_current (buffer->drawable); } else if (buffer->data) memcpy (data, (char *) buffer->data + offset, size); } slim_hidden_def(glitz_buffer_get_data); void * -glitz_buffer_map (glitz_buffer_t *buffer, +glitz_buffer_map (glitz_buffer_t *buffer, glitz_buffer_access_t access) { void *pointer = NULL; - if (buffer->surface) { + if (buffer->drawable) { glitz_gl_enum_t buffer_access; - - glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT); + + GLITZ_GL_DRAWABLE (buffer->drawable); + + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); switch (access) { case GLITZ_BUFFER_ACCESS_READ_ONLY: @@ -288,11 +300,10 @@ glitz_buffer_map (glitz_buffer_t *buffer, break; } - buffer->surface->backend->gl.bind_buffer (buffer->target, buffer->name); - pointer = buffer->surface->backend->gl.map_buffer (buffer->target, - buffer_access); + gl->bind_buffer (buffer->target, buffer->name); + pointer = gl->map_buffer (buffer->target, buffer_access); - glitz_surface_pop_current (buffer->surface); + buffer->drawable->backend->pop_current (buffer->drawable); } if (pointer == NULL) @@ -306,16 +317,18 @@ glitz_buffer_unmap (glitz_buffer_t *buffer) { glitz_status_t status = GLITZ_STATUS_SUCCESS; - if (buffer->surface) { - glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT); + if (buffer->drawable) { + GLITZ_GL_DRAWABLE (buffer->drawable); - if (buffer->surface->backend->gl.unmap_buffer (buffer->target) == - GLITZ_GL_FALSE) + buffer->drawable->backend->push_current (buffer->drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + + if (gl->unmap_buffer (buffer->target) == GLITZ_GL_FALSE) status = GLITZ_STATUS_CONTENT_DESTROYED; - buffer->surface->backend->gl.bind_buffer (buffer->target, 0); - - glitz_surface_pop_current (buffer->surface); + gl->bind_buffer (buffer->target, 0); + + buffer->drawable->backend->pop_current (buffer->drawable); } return status; @@ -325,8 +338,8 @@ void * glitz_buffer_bind (glitz_buffer_t *buffer, glitz_gl_enum_t target) { - if (buffer->surface) { - buffer->surface->backend->gl.bind_buffer (target, buffer->name); + if (buffer->drawable) { + buffer->drawable->backend->gl.bind_buffer (target, buffer->name); buffer->target = target; return NULL; @@ -338,6 +351,6 @@ glitz_buffer_bind (glitz_buffer_t *buffer, void glitz_buffer_unbind (glitz_buffer_t *buffer) { - if (buffer->surface) - buffer->surface->backend->gl.bind_buffer (buffer->target, 0); + if (buffer->drawable) + buffer->drawable->backend->gl.bind_buffer (buffer->target, 0); } diff --git a/src/glitz_compose.c b/src/glitz_compose.c index afac19c..1f7ff83 100644 --- a/src/glitz_compose.c +++ b/src/glitz_compose.c @@ -449,12 +449,13 @@ glitz_composite_op_init (glitz_composite_op_t *op, glitz_surface_type_t src_type; glitz_surface_type_t mask_type; glitz_combine_t *combine; + unsigned long feature_mask; op->render_op = render_op; op->type = GLITZ_COMBINE_TYPE_NA; op->combine = NULL; op->alpha_mask = _default_alpha_mask; - op->gl = &dst->backend->gl; + op->gl = &dst->drawable->backend->gl; op->src = src; op->mask = mask; op->dst = dst; @@ -463,14 +464,16 @@ glitz_composite_op_init (glitz_composite_op_t *op, op->per_component = 0; op->fp = 0; - if (dst->indirect && (dst->format->stencil_size < 1)) + feature_mask = dst->attached->backend->feature_mask; + + if (dst->indirect && (dst->attached->format->stencil_size < 1)) return; - src_type = _glitz_get_surface_type (src, dst->backend->feature_mask); + src_type = _glitz_get_surface_type (src, feature_mask); if (src_type < 1) return; - mask_type = _glitz_get_surface_type (mask, dst->backend->feature_mask); + mask_type = _glitz_get_surface_type (mask, feature_mask); if (mask_type < 0) return; @@ -488,62 +491,51 @@ glitz_composite_op_init (glitz_composite_op_t *op, src_type = GLITZ_SURFACE_TYPE_ARGB; combine = &_glitz_combine_map[src_type][mask_type]; - if (combine->type == GLITZ_COMBINE_TYPE_NA) { - op->type = GLITZ_COMBINE_TYPE_INTERMEDIATE; - + if (!combine->type) return; - } if (src_type == GLITZ_SURFACE_TYPE_SOLID) { - glitz_surface_ensure_solid (src); + glitz_surface_sync_solid (src); op->solid = &src->solid; op->src = NULL; } if (mask_type == GLITZ_SURFACE_TYPE_SOLID) { - glitz_surface_ensure_solid (mask); + glitz_surface_sync_solid (mask); op->alpha_mask = mask->solid; op->mask = NULL; op->combine = combine; } else if (mask_type == GLITZ_SURFACE_TYPE_SOLIDC) { - glitz_surface_ensure_solid (mask); + glitz_surface_sync_solid (mask); op->alpha_mask = mask->solid; op->mask = NULL; if (op->src) { op->per_component = 4; op->combine = combine; - } else if (dst->backend->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) + } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) op->combine = combine; } else if (mask_type != GLITZ_SURFACE_TYPE_NULL) { if (mask_type == GLITZ_SURFACE_TYPE_ARGBC) { if (op->src) { op->per_component = 4; - if (dst->backend->feature_mask & - GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) + if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) op->combine = combine; - } else if (dst->backend->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) + } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) op->combine = combine; - } else if (dst->backend->feature_mask & - GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) + } else if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) op->combine = combine; } else op->combine = combine; - if (!(dst->backend->feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK)) { - if (op->src && op->mask) { - if (!op->per_component) { - op->type = GLITZ_COMBINE_TYPE_INTERMEDIATE; - return; - } else - op->combine = NULL; - } + if (!(feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK)) { + if (op->src && op->mask) + op->combine = NULL; } if (op->per_component && - (!(dst->backend->feature_mask & - GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK))) + (!(feature_mask & GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK))) op->combine = NULL; if (op->combine == combine) { diff --git a/src/glitz_drawable.c b/src/glitz_drawable.c new file mode 100644 index 0000000..f39b136 --- /dev/null +++ b/src/glitz_drawable.c @@ -0,0 +1,147 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitzint.h" + +glitz_drawable_format_t * +glitz_find_similar_drawable_format (glitz_drawable_t *other, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count) +{ + return glitz_drawable_format_find (other->backend->drawable_formats, + other->backend->n_drawable_formats, + mask, templ, count); +} +slim_hidden_def(glitz_find_similar_drawable_format); + +glitz_drawable_t * +glitz_create_pbuffer_drawable (glitz_drawable_t *other, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask) +{ + if (!format->types.pbuffer) + return NULL; + + return other->backend->create_pbuffer (other, format, attributes, mask); +} +slim_hidden_def(glitz_create_pbuffer_drawable); + +void +glitz_drawable_destroy (glitz_drawable_t *drawable) +{ + if (!drawable) + return; + + drawable->ref_count--; + if (drawable->ref_count) + return; + + drawable->backend->destroy (drawable); +} + +void +glitz_drawable_reference (glitz_drawable_t *drawable) +{ + if (drawable == NULL) + return; + + drawable->ref_count++; +} + +void +glitz_drawable_update_size (glitz_drawable_t *drawable, + unsigned int width, + unsigned int height) +{ + drawable->width = (int) width; + drawable->height = (int) height; + + drawable->viewport.x = -32767; + drawable->viewport.y = -32767; + drawable->viewport.width = 65535; + drawable->viewport.height = 65535; + + drawable->update_all = 1; +} + +unsigned int +glitz_drawable_get_width (glitz_drawable_t *drawable) +{ + return (unsigned int) drawable->width; +} +slim_hidden_def(glitz_drawable_get_width); + +unsigned int +glitz_drawable_get_height (glitz_drawable_t *drawable) +{ + return (unsigned int) drawable->height; +} +slim_hidden_def(glitz_drawable_get_height); + +void +glitz_drawable_swap_buffers (glitz_drawable_t *drawable) +{ + if (drawable->format->doublebuffer) + drawable->backend->swap_buffers (drawable); +} +slim_hidden_def(glitz_drawable_swap_buffers); + +void +glitz_drawable_flush (glitz_drawable_t *drawable) +{ + drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT); + drawable->backend->gl.flush (); + drawable->backend->pop_current (drawable); +} +slim_hidden_def(glitz_drawable_flush); + +void +glitz_drawable_finish (glitz_drawable_t *drawable) +{ + drawable->backend->push_current (drawable, NULL, GLITZ_DRAWABLE_CURRENT); + drawable->backend->gl.finish (); + drawable->backend->pop_current (drawable); +} +slim_hidden_def(glitz_drawable_finish); + +unsigned long +glitz_drawable_get_features (glitz_drawable_t *drawable) +{ + return drawable->backend->feature_mask; +} +slim_hidden_def(glitz_drawable_get_features); + +glitz_drawable_format_t * +glitz_drawable_get_format (glitz_drawable_t *drawable) +{ + return drawable->format; +} +slim_hidden_def(glitz_drawable_get_format); diff --git a/src/glitz_format.c b/src/glitz_format.c index e9fc2c0..fd40532 100644 --- a/src/glitz_format.c +++ b/src/glitz_format.c @@ -1,28 +1,26 @@ /* - * Copyright © 2004 David Reveman, Peter Nilsson - * + * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. + * 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 AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. + * 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. * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> + * Author: David Reveman <c99drn@cs.umu.se> */ #ifdef HAVE_CONFIG_H @@ -33,87 +31,115 @@ #include <stdlib.h> -static glitz_format_t _texture_formats[] = { - { - GLITZ_GL_ALPHA4, 0, 0, 0, 4, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_ALPHA8, 0, 0, 0, 8, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_ALPHA12, 0, 0, 0, 12, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_ALPHA16, 0, 0, 0, 16, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_R3_G3_B2, 3, 3, 2, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGB4, 4, 4, 4, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGB5, 5, 5, 5, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGB8, 8, 8, 8, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGB10, 10, 10, 10, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGB12, 12, 12, 12, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGB16, 16, 16, 16, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGBA2, 2, 2, 2, 2, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGB5_A1, 5, 5, 5, 1, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGBA8, 8, 8, 8, 8, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGB10_A2, 10, 10, 10, 2, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGBA12, 12, 12, 12, 12, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - }, { - GLITZ_GL_RGBA16, 16, 16, 16, 16, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 } - } +struct _texture_format { + glitz_gl_int_t texture_format; + glitz_format_t format; +} _texture_formats[] = { + { GLITZ_GL_ALPHA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 4 } } }, + { GLITZ_GL_ALPHA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 8 } } }, + { GLITZ_GL_ALPHA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 12 } } }, + { GLITZ_GL_ALPHA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 0, 0, 0, 16 } } }, + { GLITZ_GL_R3_G3_B2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 3, 3, 2, 0 } } }, + { GLITZ_GL_RGB4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 0 } } }, + { GLITZ_GL_RGB5, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 6, 5, 0 } } }, + { GLITZ_GL_RGB8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 0 } } }, + { GLITZ_GL_RGB10, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 0 } } }, + { GLITZ_GL_RGB12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 0 } } }, + { GLITZ_GL_RGB16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 0 } } }, + { GLITZ_GL_RGBA2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 2, 2, 2, 2 } } }, + { GLITZ_GL_RGB5_A1, { 0, GLITZ_FORMAT_TYPE_COLOR, { 5, 5, 5, 1 } } }, + { GLITZ_GL_RGBA4, { 0, GLITZ_FORMAT_TYPE_COLOR, { 4, 4, 4, 4 } } }, + { GLITZ_GL_RGBA8, { 0, GLITZ_FORMAT_TYPE_COLOR, { 8, 8, 8, 8 } } }, + { GLITZ_GL_RGB10_A2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10, 2 } } }, + { GLITZ_GL_RGBA12, { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 12 } } }, + { GLITZ_GL_RGBA16, { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 16 } } } }; +static void +_glitz_add_texture_format (glitz_format_t **formats, + glitz_gl_int_t **texture_formats, + int *n_formats, + glitz_gl_int_t texture_format, + glitz_format_t *format) +{ + *formats = realloc (*formats, sizeof (glitz_format_t) * (*n_formats + 1)); + *texture_formats = realloc (*texture_formats, + sizeof (glitz_gl_enum_t) * (*n_formats + 1)); + + if (*formats && *texture_formats) { + (*texture_formats)[*n_formats] = texture_format; + (*formats)[*n_formats] = *format; + (*formats)[*n_formats].id = *n_formats; + (*n_formats)++; + } else + *n_formats = 0; +} + void -glitz_format_for_each_texture_format (glitz_format_call_back_t call_back, - glitz_gl_proc_address_list_t *gl, - void *ptr) +glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl, + glitz_format_t **formats, + glitz_gl_int_t **texture_formats, + int *n_formats) { glitz_gl_int_t value; - int i, n_texture_formats = - sizeof (_texture_formats) / sizeof (glitz_format_t); - + int i, n_texture_formats; + + n_texture_formats = + sizeof (_texture_formats) / sizeof (struct _texture_format); + for (i = 0; i < n_texture_formats; i++) { gl->tex_image_2d (GLITZ_GL_PROXY_TEXTURE_2D, 0, - _texture_formats[i].id, 1, 1, - 0, GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL); - gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, - GLITZ_GL_TEXTURE_RED_SIZE, &value); - if (value != _texture_formats[i].red_size) - continue; + _texture_formats[i].texture_format, 1, 1, 0, + GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL); - gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, - GLITZ_GL_TEXTURE_GREEN_SIZE, &value); - if (value != _texture_formats[i].green_size) - continue; + switch (_texture_formats[i].format.type) { + case GLITZ_FORMAT_TYPE_COLOR: + if (_texture_formats[i].format.color.red_size) { + gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, + GLITZ_GL_TEXTURE_RED_SIZE, &value); + if (value != _texture_formats[i].format.color.red_size) + continue; + } + + if (_texture_formats[i].format.color.green_size) { + gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, + GLITZ_GL_TEXTURE_GREEN_SIZE, &value); + if (value != _texture_formats[i].format.color.green_size) + continue; + } - gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, - GLITZ_GL_TEXTURE_BLUE_SIZE, &value); - if (value != _texture_formats[i].blue_size) - continue; + if (_texture_formats[i].format.color.blue_size) { + gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, + GLITZ_GL_TEXTURE_BLUE_SIZE, &value); + if (value != _texture_formats[i].format.color.blue_size) + continue; + } - gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, - GLITZ_GL_TEXTURE_ALPHA_SIZE, &value); - if (value != _texture_formats[i].alpha_size) + if (_texture_formats[i].format.color.alpha_size) { + gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0, + GLITZ_GL_TEXTURE_ALPHA_SIZE, &value); + if (value != _texture_formats[i].format.color.alpha_size) + continue; + } + break; + default: continue; - - call_back (&_texture_formats[i], ptr); + } + + _glitz_add_texture_format (formats, + texture_formats, + n_formats, + _texture_formats[i].texture_format, + &_texture_formats[i].format); } } -glitz_format_t * -glitz_format_find (glitz_format_t *formats, - int n_formats, - unsigned long mask, - const glitz_format_t *templ, - int count) +glitz_drawable_format_t * +glitz_drawable_format_find (glitz_drawable_format_t *formats, + int n_formats, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count) { for (; n_formats; n_formats--, formats++) { if (mask & GLITZ_FORMAT_ID_MASK) @@ -121,19 +147,19 @@ glitz_format_find (glitz_format_t *formats, continue; if (mask & GLITZ_FORMAT_RED_SIZE_MASK) - if (templ->red_size != formats->red_size) + if (templ->color.red_size != formats->color.red_size) continue; if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK) - if (templ->green_size != formats->green_size) + if (templ->color.green_size != formats->color.green_size) continue; if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK) - if (templ->blue_size != formats->blue_size) + if (templ->color.blue_size != formats->color.blue_size) continue; if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK) - if (templ->alpha_size != formats->alpha_size) + if (templ->color.alpha_size != formats->color.alpha_size) continue; if (mask & GLITZ_FORMAT_DEPTH_SIZE_MASK) @@ -148,28 +174,55 @@ glitz_format_find (glitz_format_t *formats, if (templ->doublebuffer != formats->doublebuffer) continue; - if (mask & GLITZ_FORMAT_MULTISAMPLE_MASK) - if (templ->multisample.supported != formats->multisample.supported) + if (mask & GLITZ_FORMAT_SAMPLES_MASK) + if (templ->samples != formats->samples) continue; - if (mask & GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK) - if (templ->multisample.samples != formats->multisample.samples) + if (mask & GLITZ_FORMAT_WINDOW_MASK) + if (templ->types.window != formats->types.window) continue; - if (mask & GLITZ_FORMAT_READ_ONSCREEN_MASK) - if (templ->read.onscreen != formats->read.onscreen) + if (mask & GLITZ_FORMAT_PBUFFER_MASK) + if (templ->types.pbuffer != formats->types.pbuffer) continue; - if (mask & GLITZ_FORMAT_READ_OFFSCREEN_MASK) - if (templ->read.offscreen != formats->read.offscreen) + if (count-- == 0) + return formats; + } + + return NULL; +} + +static glitz_format_t * +_glitz_format_find (glitz_format_t *formats, + int n_formats, + unsigned long mask, + const glitz_format_t *templ, + int count) +{ + for (; n_formats; n_formats--, formats++) { + if (mask & GLITZ_FORMAT_ID_MASK) + if (templ->id != formats->id) continue; - if (mask & GLITZ_FORMAT_DRAW_ONSCREEN_MASK) - if (templ->draw.onscreen != formats->draw.onscreen) + if (mask & GLITZ_FORMAT_TYPE_MASK) + if (templ->type != formats->type) continue; - - if (mask & GLITZ_FORMAT_DRAW_OFFSCREEN_MASK) - if (templ->draw.offscreen != formats->draw.offscreen) + + if (mask & GLITZ_FORMAT_RED_SIZE_MASK) + if (templ->color.red_size != formats->color.red_size) + continue; + + if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK) + if (templ->color.green_size != formats->color.green_size) + continue; + + if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK) + if (templ->color.blue_size != formats->color.blue_size) + continue; + + if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK) + if (templ->color.alpha_size != formats->color.alpha_size) continue; if (count-- == 0) @@ -180,91 +233,53 @@ glitz_format_find (glitz_format_t *formats, } glitz_format_t * -glitz_format_find_standard (glitz_format_t *formats, - int n_formats, +glitz_find_format (glitz_drawable_t *drawable, + unsigned long mask, + const glitz_format_t *templ, + int count) +{ + return _glitz_format_find (drawable->backend->formats, + drawable->backend->n_formats, + mask, templ, count); +} + +glitz_format_t * +glitz_find_standard_format (glitz_drawable_t *drawable, glitz_format_name_t format_name) { glitz_format_t templ; unsigned long mask = GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK | GLITZ_FORMAT_BLUE_SIZE_MASK | - GLITZ_FORMAT_ALPHA_SIZE_MASK | GLITZ_FORMAT_READ_OFFSCREEN_MASK; + GLITZ_FORMAT_ALPHA_SIZE_MASK | GLITZ_FORMAT_TYPE_MASK; - /* only pick offscreen formats */ - templ.read.offscreen = 1; + templ.type = GLITZ_FORMAT_TYPE_COLOR; switch (format_name) { case GLITZ_STANDARD_ARGB32: - templ.red_size = 8; - templ.green_size = 8; - templ.blue_size = 8; - templ.alpha_size = 8; + templ.color.red_size = 8; + templ.color.green_size = 8; + templ.color.blue_size = 8; + templ.color.alpha_size = 8; break; case GLITZ_STANDARD_RGB24: - templ.red_size = 8; - templ.green_size = 8; - templ.blue_size = 8; - templ.alpha_size = 0; + templ.color.red_size = 8; + templ.color.green_size = 8; + templ.color.blue_size = 8; + templ.color.alpha_size = 0; break; case GLITZ_STANDARD_A8: - templ.red_size = 0; - templ.green_size = 0; - templ.blue_size = 0; - templ.alpha_size = 8; + templ.color.red_size = 0; + templ.color.green_size = 0; + templ.color.blue_size = 0; + templ.color.alpha_size = 8; break; case GLITZ_STANDARD_A1: - templ.red_size = 0; - templ.green_size = 0; - templ.blue_size = 0; - templ.alpha_size = 1; + templ.color.red_size = 0; + templ.color.green_size = 0; + templ.color.blue_size = 0; + templ.color.alpha_size = 1; break; } - return glitz_format_find (formats, n_formats, mask, &templ, 0); -} - -glitz_gl_int_t -glitz_format_get_best_texture_format (glitz_format_t *formats, - int n_formats, - glitz_format_t *format) -{ - glitz_format_t templ; - unsigned long mask; - glitz_format_t *best_format, *texture_format; - int n_texture_formats = - sizeof (_texture_formats) / sizeof (glitz_format_t); - - if (format->draw.offscreen || format->draw.onscreen) { - unsigned int i = 0; - - templ.draw.offscreen = templ.draw.onscreen = 0; - templ.read.offscreen = 1; - mask = GLITZ_FORMAT_READ_OFFSCREEN_MASK | GLITZ_FORMAT_DRAW_ONSCREEN_MASK | - GLITZ_FORMAT_DRAW_OFFSCREEN_MASK; - - do { - best_format = glitz_format_find (formats, n_formats, mask, &templ, i++); - if (best_format && - best_format->red_size >= format->red_size && - best_format->green_size >= format->green_size && - best_format->blue_size >= format->blue_size && - best_format->alpha_size >= format->alpha_size) - break; - } while (best_format); - - if (!best_format) - return GLITZ_GL_RGBA; - } else - best_format = format; - - mask = GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK | - GLITZ_FORMAT_BLUE_SIZE_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK; - - texture_format = - glitz_format_find (_texture_formats, n_texture_formats, - mask, best_format, 0); - - if (!texture_format) - return GLITZ_GL_RGBA; - - return (glitz_gl_int_t) texture_format->id; + return glitz_find_format (drawable, mask, &templ, 0); } diff --git a/src/glitz_geometry.c b/src/glitz_geometry.c index 6952de5..733ccb6 100644 --- a/src/glitz_geometry.c +++ b/src/glitz_geometry.c @@ -99,25 +99,38 @@ static glitz_sample_info_t _1x_sample = { }; void -glitz_set_geometry (glitz_surface_t *dst, - int x_dst, - int y_dst, +glitz_set_geometry (glitz_surface_t *dst, + glitz_fixed16_16_t x_dst, + glitz_fixed16_16_t y_dst, glitz_geometry_format_t *format, - glitz_buffer_t *buffer) + glitz_buffer_t *buffer) { - if (dst->geometry.buffer) { - glitz_buffer_destroy (dst->geometry.buffer); - dst->geometry.buffer = NULL; - } + glitz_drawable_t *drawable = (dst->attached)? dst->attached: dst->drawable; if (buffer) { - dst->geometry.buffer = buffer; glitz_buffer_reference (buffer); - dst->geometry.x_offset = x_dst; - dst->geometry.y_offset = y_dst; + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); + + dst->geometry.buffer = buffer; + + dst->geometry.x_offset = FIXED_TO_FLOAT (x_dst); + dst->geometry.y_offset = FIXED_TO_FLOAT (y_dst); switch (format->primitive) { + case GLITZ_GEOMETRY_PRIMITIVE_POINTS: + dst->geometry.primitive = GLITZ_GL_POINTS; + break; + case GLITZ_GEOMETRY_PRIMITIVE_LINES: + dst->geometry.primitive = GLITZ_GL_LINES; + break; + case GLITZ_GEOMETRY_PRIMITIVE_LINE_STRIP: + dst->geometry.primitive = GLITZ_GL_LINE_STRIP; + break; + case GLITZ_GEOMETRY_PRIMITIVE_LINE_LOOP: + dst->geometry.primitive = GLITZ_GL_LINE_LOOP; + break; case GLITZ_GEOMETRY_PRIMITIVE_TRIANGLES: dst->geometry.primitive = GLITZ_GL_TRIANGLES; break; @@ -156,7 +169,7 @@ glitz_set_geometry (glitz_surface_t *dst, dst->geometry.first = format->first; dst->geometry.count = format->count; - if (dst->format->multisample.samples > 1) { + if (drawable->format->samples > 1) { if (format->edge_hint != GLITZ_GEOMETRY_EDGE_HINT_SHARP) { dst->flags |= GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK; @@ -164,29 +177,25 @@ glitz_set_geometry (glitz_surface_t *dst, dst->flags |= GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK; else dst->flags &= ~GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK; - - dst->update_mask |= GLITZ_UPDATE_MULTISAMPLE_MASK; - } else { + } else dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK; - dst->update_mask |= GLITZ_UPDATE_MULTISAMPLE_MASK; - } } else { if (format->mode == GLITZ_GEOMETRY_MODE_INDIRECT) { switch (format->edge_hint) { case GLITZ_GEOMETRY_EDGE_HINT_BEST_SMOOTH: - if (dst->format->stencil_size >= 4) { + if (drawable->format->stencil_size >= 4) { dst->indirect = &_8x_multi_sample; break; } /* fall-through */ case GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH: - if (dst->format->stencil_size >= 3) { + if (drawable->format->stencil_size >= 3) { dst->indirect = &_4x_multi_sample; break; } /* fall-through */ case GLITZ_GEOMETRY_EDGE_HINT_FAST_SMOOTH: - if (dst->format->stencil_size >= 2) { + if (drawable->format->stencil_size >= 2) { dst->indirect = &_2x_multi_sample; break; } @@ -200,19 +209,20 @@ glitz_set_geometry (glitz_surface_t *dst, dst->indirect = NULL; } } else { - if (dst->format->multisample.samples > 1) { - dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK; - dst->update_mask |= GLITZ_UPDATE_MULTISAMPLE_MASK; - } else - dst->indirect = NULL; + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); + + dst->geometry.buffer = NULL; + dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK; + dst->indirect = NULL; } } slim_hidden_def(glitz_set_geometry); void glitz_geometry_enable_default (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_bounding_box_t *box) + glitz_surface_t *dst, + glitz_box_t *box) { dst->geometry.data[0] = box->x1; dst->geometry.data[1] = box->y1; @@ -228,11 +238,11 @@ glitz_geometry_enable_default (glitz_gl_proc_address_list_t *gl, void glitz_geometry_enable (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_gl_enum_t *primitive, - glitz_gl_int_t *first, - glitz_gl_sizei_t *count, - glitz_bounding_box_t *box) + glitz_surface_t *dst, + glitz_gl_enum_t *primitive, + glitz_gl_int_t *first, + glitz_gl_sizei_t *count, + glitz_box_t *box) { if (dst->geometry.buffer) { void *ptr; @@ -257,9 +267,10 @@ glitz_geometry_enable (glitz_gl_proc_address_list_t *gl, void glitz_geometry_disable (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst) + glitz_surface_t *dst) { if (dst->geometry.buffer && - (dst->backend->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK)) + (dst->drawable->backend->feature_mask & + GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK)) gl->bind_buffer (GLITZ_GL_ARRAY_BUFFER, 0); } diff --git a/src/glitz_gl.h b/src/glitz_gl.h index 952cde3..4bdb544 100644 --- a/src/glitz_gl.h +++ b/src/glitz_gl.h @@ -53,6 +53,9 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_NO_ERROR 0x0 #define GLITZ_GL_INVALID_OPERATION 0x0502 +#define GLITZ_GL_VERSION 0x1F02 +#define GLITZ_GL_EXTENSIONS 0x1F03 + #define GLITZ_GL_UNSIGNED_BYTE 0x1401 #define GLITZ_GL_FLOAT 0x1406 #define GLITZ_GL_UNSIGNED_BYTE_3_3_2 0x8032 @@ -75,6 +78,10 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_FLOAT 0x1406 #define GLITZ_GL_DOUBLE 0x140A +#define GLITZ_GL_POINTS 0x0000 +#define GLITZ_GL_LINES 0x0001 +#define GLITZ_GL_LINE_LOOP 0x0002 +#define GLITZ_GL_LINE_STRIP 0x0003 #define GLITZ_GL_TRIANGLES 0x0004 #define GLITZ_GL_TRIANGLE_STRIP 0x0005 #define GLITZ_GL_TRIANGLE_FAN 0x0006 @@ -88,6 +95,9 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_FRONT 0x0404 #define GLITZ_GL_BACK 0x0405 #define GLITZ_GL_CULL_FACE 0x0B44 + +#define GLITZ_GL_POINT_SMOOTH 0x0B10 +#define GLITZ_GL_LINE_SMOOTH 0x0B20 #define GLITZ_GL_POLYGON_SMOOTH 0x0B41 #define GLITZ_GL_SCISSOR_TEST 0x0C11 @@ -297,6 +307,8 @@ typedef glitz_gl_void_t (* glitz_gl_disable_t) (glitz_gl_enum_t cap); typedef glitz_gl_enum_t (* glitz_gl_get_error_t) (glitz_gl_void_t); +typedef glitz_gl_ubyte_t *(* glitz_gl_get_string_t) + (glitz_gl_enum_t); typedef glitz_gl_void_t (* glitz_gl_enable_client_state_t) (glitz_gl_enum_t cap); typedef glitz_gl_void_t (* glitz_gl_disable_client_state_t) diff --git a/src/glitz_glx_context.c b/src/glitz_glx_context.c deleted file mode 100644 index 24c086d..0000000 --- a/src/glitz_glx_context.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_glxint.h" - -#include <stdlib.h> - -extern glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address; - -static void -_glitz_glx_context_create (glitz_glx_screen_info_t *screen_info, - XID visualid, - GLXContext share_list, - glitz_glx_context_t *context) -{ - int vis_info_count, i; - XVisualInfo *vis_infos; - - vis_infos = XGetVisualInfo (screen_info->display_info->display, - 0, NULL, &vis_info_count); - for (i = 0; i < vis_info_count; i++) { - if (vis_infos[i].visual->visualid == visualid) - break; - } - - context->context = glXCreateContext (screen_info->display_info->display, - &vis_infos[i], share_list, - GLITZ_GL_TRUE); - context->id = visualid; - context->fbconfig = (XID) 0; - - XFree (vis_infos); -} - -static void -_glitz_glx_context_create_fbconfig (glitz_glx_screen_info_t *screen_info, - XID fbconfigid, - GLXContext share_list, - glitz_glx_context_t *context) -{ - GLXFBConfig *fbconfigs; - int i, n_fbconfigs; - XVisualInfo *vinfo = NULL; - glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; - - fbconfigs = glx->get_fbconfigs (screen_info->display_info->display, - screen_info->screen, &n_fbconfigs); - for (i = 0; i < n_fbconfigs; i++) { - int value; - - glx->get_fbconfig_attrib (screen_info->display_info->display, fbconfigs[i], - GLX_FBCONFIG_ID, &value); - if (value == (int) fbconfigid) - break; - } - - if (i < n_fbconfigs) - vinfo = glx->get_visual_from_fbconfig (screen_info->display_info->display, - fbconfigs[i]); - - context->id = fbconfigid; - if (vinfo) { - context->context = glXCreateContext (screen_info->display_info->display, - vinfo, share_list, GLITZ_GL_TRUE); - XFree (vinfo); - } else if (glx->create_new_context) - context->context = - glx->create_new_context (screen_info->display_info->display, - fbconfigs[i], GLX_RGBA_TYPE, share_list, - GLITZ_GL_TRUE); - - if (context->context) - context->fbconfig = fbconfigs[i]; - else - context->fbconfig = NULL; - - if (fbconfigs) - XFree (fbconfigs); -} - -int -glitz_glx_ensure_pbuffer_support (glitz_glx_screen_info_t *screen_info, - XID fbconfigid) -{ - GLXFBConfig *fbconfigs; - int i, n_fbconfigs; - glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; - int status = 1; - - fbconfigs = glx->get_fbconfigs (screen_info->display_info->display, - screen_info->screen, &n_fbconfigs); - for (i = 0; i < n_fbconfigs; i++) { - int value; - - glx->get_fbconfig_attrib (screen_info->display_info->display, fbconfigs[i], - GLX_FBCONFIG_ID, &value); - if (value == (int) fbconfigid) - break; - } - - if (i < n_fbconfigs) { - GLXPbuffer pbuffer; - glitz_texture_t texture; - - texture.width = texture.height = 1; - pbuffer = glitz_glx_pbuffer_create (screen_info, fbconfigs[i], &texture); - if (pbuffer) { - glitz_glx_pbuffer_destroy (screen_info, pbuffer); - - status = 0; - } - } - - if (fbconfigs) - XFree (fbconfigs); - - return status; -} - -glitz_glx_context_t * -glitz_glx_context_get (glitz_glx_screen_info_t *screen_info, - glitz_format_t *format) -{ - glitz_glx_context_t *context; - glitz_glx_context_t **contexts = screen_info->contexts; - int index, n_contexts = screen_info->n_contexts; - - if (screen_info->format_ids[format->id] == (XID) 0) - return &screen_info->root_context; - - for (; n_contexts; n_contexts--, contexts++) - if ((*contexts)->id == screen_info->format_ids[format->id]) - return *contexts; - - index = screen_info->n_contexts++; - - screen_info->contexts = - realloc (screen_info->contexts, - sizeof (glitz_glx_context_t *) * screen_info->n_contexts); - - context = malloc (sizeof (glitz_glx_context_t)); - screen_info->contexts[index] = context; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GLX_FBCONFIG_MASK) - _glitz_glx_context_create_fbconfig (screen_info, - screen_info->format_ids[format->id], - screen_info->root_context.context, - context); - else - _glitz_glx_context_create (screen_info, - screen_info->format_ids[format->id], - screen_info->root_context.context, - context); - - glitz_glx_surface_backend_init (&context->backend); - - memcpy (&context->backend.gl, - &_glitz_glx_gl_proc_address, - sizeof (glitz_gl_proc_address_list_t)); - - context->backend.formats = screen_info->formats; - context->backend.n_formats = screen_info->n_formats; - context->backend.program_map = &screen_info->program_map; - context->backend.feature_mask = screen_info->feature_mask; - - context->backend.gl.need_lookup = 1; - - return context; -} - -void -glitz_glx_context_destroy (glitz_glx_screen_info_t *screen_info, - glitz_glx_context_t *context) -{ - glXDestroyContext (screen_info->display_info->display, - context->context); - free (context); -} - -void -glitz_glx_context_proc_address_lookup (glitz_glx_screen_info_t *screen_info, - glitz_glx_context_t *context) -{ - if (screen_info->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) { - if (screen_info->gl_version >= 1.4f) { - context->backend.gl.blend_color = (glitz_gl_blend_color_t) - glitz_glx_get_proc_address (screen_info, "glBlendColor"); - } else { - context->backend.gl.blend_color = (glitz_gl_blend_color_t) - glitz_glx_get_proc_address (screen_info, "glBlendColorEXT"); - } - - if (!context->backend.gl.blend_color) - context->backend.feature_mask &= ~GLITZ_FEATURE_BLEND_COLOR_MASK; - } - - if (screen_info->feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK) { - if (screen_info->gl_version >= 1.3f) { - context->backend.gl.active_texture = (glitz_gl_active_texture_t) - glitz_glx_get_proc_address (screen_info, "glActiveTexture"); - } else { - context->backend.gl.active_texture = (glitz_gl_active_texture_t) - glitz_glx_get_proc_address (screen_info, "glActiveTextureARB"); - } - - if (!context->backend.gl.active_texture) { - context->backend.feature_mask &= ~GLITZ_FEATURE_MULTITEXTURE_MASK; - context->backend.feature_mask &= - ~GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; - } - } - - if (screen_info->feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) { - context->backend.gl.gen_programs = (glitz_gl_gen_programs_t) - glitz_glx_get_proc_address (screen_info, "glGenProgramsARB"); - context->backend.gl.delete_programs = (glitz_gl_delete_programs_t) - glitz_glx_get_proc_address (screen_info, "glDeleteProgramsARB"); - context->backend.gl.program_string = (glitz_gl_program_string_t) - glitz_glx_get_proc_address (screen_info, "glProgramStringARB"); - context->backend.gl.bind_program = (glitz_gl_bind_program_t) - glitz_glx_get_proc_address (screen_info, "glBindProgramARB"); - context->backend.gl.program_local_param_4fv = - (glitz_gl_program_local_param_4fv_t) - glitz_glx_get_proc_address (screen_info, - "glProgramLocalParameter4fvARB"); - context->backend.gl.get_program_iv = (glitz_gl_get_program_iv_t) - glitz_glx_get_proc_address (screen_info, "glGetProgramivARB"); - - if ((!context->backend.gl.gen_programs) || - (!context->backend.gl.delete_programs) || - (!context->backend.gl.program_string) || - (!context->backend.gl.bind_program) || - (!context->backend.gl.program_local_param_4fv)) - context->backend.feature_mask &= ~GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK; - } - - if ((screen_info->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) || - (screen_info->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)) { - if (screen_info->gl_version >= 1.5f) { - context->backend.gl.gen_buffers = (glitz_gl_gen_buffers_t) - glitz_glx_get_proc_address (screen_info, "glGenBuffers"); - context->backend.gl.delete_buffers = (glitz_gl_delete_buffers_t) - glitz_glx_get_proc_address (screen_info, "glDeleteBuffers"); - context->backend.gl.bind_buffer = (glitz_gl_bind_buffer_t) - glitz_glx_get_proc_address (screen_info, "glBindBuffer"); - context->backend.gl.buffer_data = (glitz_gl_buffer_data_t) - glitz_glx_get_proc_address (screen_info, "glBufferData"); - context->backend.gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t) - glitz_glx_get_proc_address (screen_info, "glBufferSubData"); - context->backend.gl.get_buffer_sub_data = - (glitz_gl_get_buffer_sub_data_t) - glitz_glx_get_proc_address (screen_info, "glGetBufferSubData"); - context->backend.gl.map_buffer = (glitz_gl_map_buffer_t) - glitz_glx_get_proc_address (screen_info, "glMapBuffer"); - context->backend.gl.unmap_buffer = (glitz_gl_unmap_buffer_t) - glitz_glx_get_proc_address (screen_info, "glUnmapBuffer"); - } else { - context->backend.gl.gen_buffers = (glitz_gl_gen_buffers_t) - glitz_glx_get_proc_address (screen_info, "glGenBuffersARB"); - context->backend.gl.delete_buffers = (glitz_gl_delete_buffers_t) - glitz_glx_get_proc_address (screen_info, "glDeleteBuffersARB"); - context->backend.gl.bind_buffer = (glitz_gl_bind_buffer_t) - glitz_glx_get_proc_address (screen_info, "glBindBufferARB"); - context->backend.gl.buffer_data = (glitz_gl_buffer_data_t) - glitz_glx_get_proc_address (screen_info, "glBufferDataARB"); - context->backend.gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t) - glitz_glx_get_proc_address (screen_info, "glBufferSubDataARB"); - context->backend.gl.get_buffer_sub_data = - (glitz_gl_get_buffer_sub_data_t) - glitz_glx_get_proc_address (screen_info, "glGetBufferSubDataARB"); - context->backend.gl.map_buffer = (glitz_gl_map_buffer_t) - glitz_glx_get_proc_address (screen_info, "glMapBufferARB"); - context->backend.gl.unmap_buffer = (glitz_gl_unmap_buffer_t) - glitz_glx_get_proc_address (screen_info, "glUnmapBufferARB"); - } - - if ((!context->backend.gl.gen_buffers) || - (!context->backend.gl.delete_buffers) || - (!context->backend.gl.bind_buffer) || - (!context->backend.gl.buffer_data) || - (!context->backend.gl.buffer_sub_data) || - (!context->backend.gl.get_buffer_sub_data) || - (!context->backend.gl.map_buffer) || - (!context->backend.gl.unmap_buffer)) { - context->backend.feature_mask &= - ~GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK; - context->backend.feature_mask &= ~GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK; - } - } - - context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS, - context->max_viewport_dims); - context->backend.gl.get_integer_v (GLITZ_GL_MAX_TEXTURE_SIZE, - &context->max_texture_2d_size); - - if (screen_info->feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) - context->backend.gl.get_integer_v (GLITZ_GL_MAX_RECTANGLE_TEXTURE_SIZE, - &context->max_texture_rect_size); - else - context->max_texture_rect_size = 0; - - context->backend.gl.need_lookup = 0; -} - -void -glitz_glx_context_make_current (glitz_glx_surface_t *surface, - GLXContext context, - glitz_bool_t flush) -{ - Drawable drawable; - - if (flush) - glFlush (); - - if (!surface->drawable) { - drawable = surface->screen_info->root_drawable; - context = surface->screen_info->root_context.context; - } else { - drawable = surface->drawable; - surface->base.update_mask |= GLITZ_UPDATE_ALL_MASK; - } - - glXMakeCurrent (surface->screen_info->display_info->display, - drawable, context); - - if (surface->context->backend.gl.need_lookup) - glitz_glx_context_proc_address_lookup (surface->screen_info, - surface->context); -} - -static void -glitz_glx_context_update (glitz_glx_surface_t *surface, - glitz_constraint_t constraint) -{ - GLXContext context = glXGetCurrentContext (); - GLXContext newcontext; - - if (surface->context->context) - newcontext = surface->context->context; - else - newcontext = surface->screen_info->root_context.context; - - switch (constraint) { - case GLITZ_CN_NONE: - break; - case GLITZ_CN_ANY_CONTEXT_CURRENT: - if (context == NULL) - glitz_glx_context_make_current (surface, newcontext, 0); - break; - case GLITZ_CN_SURFACE_CONTEXT_CURRENT: - if (context != newcontext) - glitz_glx_context_make_current (surface, newcontext, (context)? 1: 0); - break; - case GLITZ_CN_SURFACE_DRAWABLE_CURRENT: - if ((context != newcontext) || - (glXGetCurrentDrawable () != surface->drawable)) - glitz_glx_context_make_current (surface, newcontext, (context)? 1: 0); - break; - } -} - -glitz_glx_surface_t * -glitz_glx_context_push_current (glitz_glx_surface_t *surface, - glitz_constraint_t constraint) -{ - glitz_glx_screen_info_t *screen_info; - glitz_glx_context_info_t *context_info; - int index; - - screen_info = surface->screen_info; - - index = screen_info->context_stack_size++; - - context_info = &screen_info->context_stack[index]; - context_info->surface = surface; - context_info->constraint = constraint; - - glitz_glx_context_update (context_info->surface, constraint); - - if (context_info->constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT) - return context_info->surface; - - return NULL; -} - -glitz_glx_surface_t * -glitz_glx_context_pop_current (glitz_glx_surface_t *surface) -{ - glitz_glx_screen_info_t *screen_info; - glitz_glx_context_info_t *context_info = NULL; - int index; - - screen_info = surface->screen_info; - - screen_info->context_stack_size--; - index = screen_info->context_stack_size - 1; - - context_info = &screen_info->context_stack[index]; - - if (context_info->surface) - glitz_glx_context_update (context_info->surface, context_info->constraint); - - if (context_info->constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT) - return context_info->surface; - - return NULL; -} diff --git a/src/glitz_glx_extension.c b/src/glitz_glx_extension.c deleted file mode 100644 index 9f3ed50..0000000 --- a/src/glitz_glx_extension.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_glxint.h" - -static glitz_extension_map glx_extensions[] = { - { 0.0, "GLX_SGIX_fbconfig", GLITZ_GLX_FEATURE_GLX_FBCONFIG_MASK }, - { 0.0, "GLX_SGIX_pbuffer", GLITZ_GLX_FEATURE_GLX_PBUFFER_MASK }, - { 0.0, "GLX_SGI_make_current_read", - GLITZ_GLX_FEATURE_GLX_MAKE_CURRENT_READ_MASK }, - { 0.0, "GLX_ARB_multisample", GLITZ_GLX_FEATURE_GLX_MULTISAMPLE_MASK }, - { 0.0, NULL, 0 } -}, gl_extensions[] = { - { 0.0, "GL_ARB_texture_rectangle", - GLITZ_GLX_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_EXT_texture_rectangle", - GLITZ_GLX_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_NV_texture_rectangle", GLITZ_GLX_FEATURE_TEXTURE_RECTANGLE_MASK }, - { 0.0, "GL_ARB_texture_non_power_of_two", - GLITZ_GLX_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK }, - { 0.0, "GL_ARB_texture_mirrored_repeat", - GLITZ_GLX_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK }, - { 0.0, "GL_ARB_texture_border_clamp", - GLITZ_GLX_FEATURE_TEXTURE_BORDER_CLAMP_MASK }, - { 0.0, "GL_ARB_texture_env_combine", - GLITZ_GLX_FEATURE_TEXTURE_ENV_COMBINE_MASK }, - { 0.0, "GL_EXT_texture_env_combine", - GLITZ_GLX_FEATURE_TEXTURE_ENV_COMBINE_MASK }, - { 0.0, "GL_ARB_texture_env_dot3", GLITZ_GLX_FEATURE_TEXTURE_ENV_DOT3_MASK }, - { 0.0, "GL_ARB_multisample", GLITZ_GLX_FEATURE_MULTISAMPLE_MASK }, - { 0.0, "GL_NV_multisample_filter_hint", - GLITZ_GLX_FEATURE_MULTISAMPLE_FILTER_HINT_MASK }, - { 0.0, "GL_ARB_multitexture", GLITZ_GLX_FEATURE_MULTITEXTURE_MASK }, - { 0.0, "GL_ARB_fragment_program", GLITZ_GLX_FEATURE_FRAGMENT_PROGRAM_MASK }, - { 0.0, "GL_ARB_vertex_buffer_object", - GLITZ_GLX_FEATURE_VERTEX_BUFFER_OBJECT_MASK }, - { 0.0, "GL_EXT_pixel_buffer_object", - GLITZ_GLX_FEATURE_PIXEL_BUFFER_OBJECT_MASK }, - { 0.0, "GL_EXT_blend_color", - GLITZ_GLX_FEATURE_BLEND_COLOR_MASK }, - { 0.0, "GL_ARB_imaging", - GLITZ_GLX_FEATURE_BLEND_COLOR_MASK }, - { 0.0, NULL, 0 } -}; - -static unsigned long -_glitz_glx_extension_query_glx (Display *display, - int screen, - glitz_gl_float_t glx_version) -{ - const char *glx_extensions_string; - - glx_extensions_string = glXQueryExtensionsString (display, screen); - - return glitz_extensions_query (glx_version, - glx_extensions_string, - glx_extensions); -} - -static unsigned long -_glitz_glx_extension_query_gl (glitz_gl_float_t gl_version) -{ - const char *gl_extensions_string; - - gl_extensions_string = (const char *) glGetString (GL_EXTENSIONS); - - return glitz_extensions_query (gl_version, - gl_extensions_string, - gl_extensions); -} - -glitz_status_t -glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info) -{ - screen_info->gl_version = atof ((const char *) glGetString (GL_VERSION)); - if (screen_info->gl_version < 1.2f) - return GLITZ_STATUS_NOT_SUPPORTED; - - screen_info->glx_feature_mask |= - _glitz_glx_extension_query_glx (screen_info->display_info->display, - screen_info->screen, - screen_info->glx_version); - - screen_info->glx_feature_mask |= - _glitz_glx_extension_query_gl (screen_info->gl_version); - - if ((screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_GLX_MULTISAMPLE_MASK) && - (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK)) { - const glitz_gl_ubyte_t *renderer = glGetString (GL_RENDERER); - - screen_info->feature_mask |= GLITZ_FEATURE_MULTISAMPLE_MASK; - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_MULTISAMPLE_FILTER_HINT_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK; - - if (renderer) { - /* All geforce and quadro cards seems to support multisample with - pbuffers */ - if (!strncmp ("GeForce", renderer, 7)) - screen_info->feature_mask |= GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK; - else if (!strncmp ("Quadro", renderer, 6)) - screen_info->feature_mask |= GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK; - } - } - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_TEXTURE_RECTANGLE_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK; - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK; - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK; - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_TEXTURE_BORDER_CLAMP_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTITEXTURE_MASK) { - screen_info->feature_mask |= GLITZ_FEATURE_MULTITEXTURE_MASK; - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_TEXTURE_ENV_COMBINE_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK; - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_TEXTURE_ENV_DOT3_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK; - - if ((screen_info->feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) && - (screen_info->feature_mask & GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK)) { - glitz_gl_int_t max_texture_units; - - glGetIntegerv (GLITZ_GL_MAX_TEXTURE_UNITS, &max_texture_units); - if (max_texture_units >= 3) - screen_info->feature_mask |= - GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; - } - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_FRAGMENT_PROGRAM_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK; - } - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_VERTEX_BUFFER_OBJECT_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK; - - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_PIXEL_BUFFER_OBJECT_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_BLEND_COLOR_MASK) - screen_info->feature_mask |= GLITZ_FEATURE_BLEND_COLOR_MASK; - - return GLITZ_STATUS_SUCCESS; -} diff --git a/src/glitz_glx_format.c b/src/glitz_glx_format.c deleted file mode 100644 index 7858e04..0000000 --- a/src/glitz_glx_format.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_glxint.h" - -#include <stdlib.h> -#include <string.h> - -static int -_glitz_glx_format_compare (const void *elem1, - const void *elem2) -{ - int i, score[2]; - glitz_format_t *format[2]; - - format[0] = (glitz_format_t *) elem1; - format[1] = (glitz_format_t *) elem2; - i = score[0] = score[1] = 0; - - for (; i < 2; i++) { - if (format[i]->red_size) - score[i] += 10; - if (format[i]->alpha_size) - score[i] += 10; - if (format[i]->stencil_size) - score[i] += (10 + format[i]->stencil_size); - if (format[i]->doublebuffer) - score[i] -= 10; - if (format[i]->draw.onscreen) - score[i] += 5; - if (format[i]->draw.offscreen) - score[i] += 5; - if (format[i]->draw.offscreen && format[i]->draw.onscreen) - score[i] += 5; - if (format[i]->multisample.supported) - score[i] -= (10 - format[i]->multisample.samples); - } - - return score[1] - score[0]; -} - -static void -_glitz_add_format (glitz_glx_screen_info_t *screen_info, - glitz_format_t *format) -{ - if (!glitz_format_find (screen_info->formats, screen_info->n_formats, - GLITZ_FORMAT_ALL_EXCEPT_ID_MASK, format, 0)) { - int index = screen_info->n_formats++; - - screen_info->formats = - realloc (screen_info->formats, - sizeof (glitz_format_t) * screen_info->n_formats); - - screen_info->formats[index] = *format; - } -} - -static void -_glitz_move_out_ids (glitz_glx_screen_info_t *screen_info) -{ - int i; - glitz_format_t *formats = screen_info->formats; - int n_formats = screen_info->n_formats; - - screen_info->format_ids = malloc (sizeof (XID) * n_formats); - - for (i = 0; n_formats; n_formats--, formats++) { - screen_info->format_ids[i] = formats->id; - formats->id = i++; - } -} - -static void -_glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info) -{ - Display *display; - glitz_format_t format; - XVisualInfo visual_templ; - XVisualInfo *visuals; - int i, num_visuals; - - display = screen_info->display_info->display; - - visual_templ.screen = screen_info->screen; - visuals = XGetVisualInfo (display, VisualScreenMask, - &visual_templ, &num_visuals); - - /* Offscreen drawing never supported without fbconfigs */ - format.draw.offscreen = format.read.offscreen = 0; - format.draw.onscreen = format.read.onscreen = 1; - - for (i = 0; i < num_visuals; i++) { - int value; - - if ((glXGetConfig (display, &visuals[i], GLX_USE_GL, &value) != 0) || - (value == 0)) - continue; - - glXGetConfig (display, &visuals[i], GLX_RGBA, &value); - if (value == 0) - continue; - - /* Stereo is not supported yet */ - glXGetConfig (display, &visuals[i], GLX_STEREO, &value); - if (value != 0) - continue; - - format.id = visuals[i].visualid; - glXGetConfig (display, &visuals[i], GLX_RED_SIZE, &value); - format.red_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_GREEN_SIZE, &value); - format.green_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_BLUE_SIZE, &value); - format.blue_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_ALPHA_SIZE, &value); - format.alpha_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_DEPTH_SIZE, &value); - format.depth_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_STENCIL_SIZE, &value); - format.stencil_size = (unsigned short) value; - glXGetConfig (display, &visuals[i], GLX_DOUBLEBUFFER, &value); - format.doublebuffer = (value) ? 1: 0; - - if (screen_info->feature_mask & GLITZ_FEATURE_MULTISAMPLE_MASK) { - glXGetConfig (display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &value); - format.multisample.supported = (value) ? 1: 0; - glXGetConfig (display, &visuals[i], GLX_SAMPLES_ARB, &value); - format.multisample.samples = (unsigned short) value; - } else { - format.multisample.supported = 0; - format.multisample.samples = 0; - } - - if (format.red_size || format.green_size || format.blue_size || - format.alpha_size) - _glitz_add_format (screen_info, &format); - } - - if (visuals) - XFree (visuals); -} - -static glitz_bool_t -_glitz_glx_query_formats_fbconfig (glitz_glx_screen_info_t *screen_info) -{ - Display *display; - glitz_format_t format; - GLXFBConfig *fbconfigs; - int i, num_configs, pbuffer_support, pbuffer_check = 1; - glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; - - display = screen_info->display_info->display; - - fbconfigs = glx->get_fbconfigs (display, screen_info->screen, &num_configs); - if (!fbconfigs) { - /* fbconfigs are not support, falling back to visuals */ - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_GLX_FBCONFIG_MASK; - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_GLX_PBUFFER_MASK; - return 1; - } - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GLX_PBUFFER_MASK) - pbuffer_support = 1; - else - pbuffer_support = 0; - - for (i = 0; i < num_configs; i++) { - int value; - - if ((glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_RENDER_TYPE, &value) != 0) || - (!(value & GLX_RGBA_BIT))) - continue; - - /* Stereo is not supported yet */ - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STEREO, &value); - if (value != 0) - continue; - - glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_DRAWABLE_TYPE, &value); - if (!((value & GLX_WINDOW_BIT) || (value & GLX_PBUFFER_BIT))) - continue; - - format.read.onscreen = format.draw.onscreen = - (value & GLX_WINDOW_BIT)? 1: 0; - format.read.offscreen = format.draw.offscreen = - (pbuffer_support && (value & GLX_PBUFFER_BIT))? 1: 0; - - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_FBCONFIG_ID, &value); - format.id = (XID) value; - - if (pbuffer_check && format.draw.offscreen) { - if (glitz_glx_ensure_pbuffer_support (screen_info, format.id)) { - pbuffer_support = 0; - format.draw.offscreen = 0; - } - pbuffer_check = 0; - } - - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_RED_SIZE, &value); - format.red_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_GREEN_SIZE, &value); - format.green_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_BLUE_SIZE, &value); - format.blue_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_ALPHA_SIZE, &value); - format.alpha_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DEPTH_SIZE, &value); - format.depth_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STENCIL_SIZE, &value); - format.stencil_size = (unsigned short) value; - glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DOUBLEBUFFER, &value); - format.doublebuffer = (value)? 1: 0; - - if (screen_info->feature_mask & GLITZ_FEATURE_MULTISAMPLE_MASK) { - glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_SAMPLE_BUFFERS_ARB, &value); - format.multisample.supported = (value)? 1: 0; - glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_SAMPLES_ARB, &value); - format.multisample.samples = (unsigned short) value; - } else { - format.multisample.supported = 0; - format.multisample.samples = 0; - } - - if (format.red_size || format.green_size || format.blue_size || - format.alpha_size) - _glitz_add_format (screen_info, &format); - } - - if (fbconfigs) - XFree (fbconfigs); - - return 0; -} - -static void -_glitz_glx_add_texture_format (glitz_format_t *texture_format, void *ptr) -{ - glitz_glx_screen_info_t *screen_info = (glitz_glx_screen_info_t *) ptr; - glitz_format_t format; - - format = *texture_format; - format.id = 0; - - _glitz_add_format (screen_info, &format); -} - -void -glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info) -{ - glitz_bool_t status = 1; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GLX_FBCONFIG_MASK) - status = _glitz_glx_query_formats_fbconfig (screen_info); - - if (status) - _glitz_glx_query_formats (screen_info); - - qsort (screen_info->formats, screen_info->n_formats, - sizeof (glitz_format_t), _glitz_glx_format_compare); - - glitz_format_for_each_texture_format (&_glitz_glx_add_texture_format, - &screen_info->root_context.backend.gl, - (void *) screen_info); - - _glitz_move_out_ids (screen_info); -} - -glitz_format_t * -glitz_glx_find_format (Display *display, - int screen, - unsigned long mask, - const glitz_format_t *templ, - int count) -{ - glitz_glx_screen_info_t *screen_info = - glitz_glx_screen_info_get (display, screen); - - return glitz_format_find (screen_info->formats, screen_info->n_formats, - mask, templ, count); -} -slim_hidden_def(glitz_glx_find_format); - -glitz_format_t * -glitz_glx_find_standard_format (Display *display, - int screen, - glitz_format_name_t format_name) -{ - glitz_glx_screen_info_t *screen_info = - glitz_glx_screen_info_get (display, screen); - - return - glitz_format_find_standard (screen_info->formats, screen_info->n_formats, - format_name); -} -slim_hidden_def(glitz_glx_find_standard_format); - -XVisualInfo * -glitz_glx_get_visual_info_from_format (Display *display, - int screen, - glitz_format_t *format) -{ - XVisualInfo *vinfo = NULL; - glitz_glx_screen_info_t *screen_info = - glitz_glx_screen_info_get (display, screen); - glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; - - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GLX_FBCONFIG_MASK) { - GLXFBConfig *fbconfigs; - int i, n_fbconfigs; - int fbconfigid = screen_info->format_ids[format->id]; - - fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs); - for (i = 0; i < n_fbconfigs; i++) { - int value; - - glx->get_fbconfig_attrib (display, fbconfigs[i], - GLX_FBCONFIG_ID, &value); - if (value == fbconfigid) - break; - } - - if (i < n_fbconfigs) - vinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]); - - if (fbconfigs) - XFree (fbconfigs); - - } else { - XVisualInfo templ; - int n_items; - - templ.visualid = screen_info->format_ids[format->id]; - - vinfo = XGetVisualInfo (display, VisualIDMask, &templ, &n_items); - } - - return vinfo; -} -slim_hidden_def(glitz_glx_get_visual_info_from_format); diff --git a/src/glitz_glx_pbuffer.c b/src/glitz_glx_pbuffer.c deleted file mode 100644 index e311473..0000000 --- a/src/glitz_glx_pbuffer.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_glxint.h" - -GLXPbuffer -glitz_glx_pbuffer_create (glitz_glx_screen_info_t *screen_info, - GLXFBConfig fbconfig, - glitz_texture_t *texture) -{ - if (fbconfig) { - int pbuffer_attr[13], i = 0; - - pbuffer_attr[i++] = GLX_PBUFFER_WIDTH; - pbuffer_attr[i++] = texture->width; - pbuffer_attr[i++] = GLX_PBUFFER_HEIGHT; - pbuffer_attr[i++] = texture->height; - pbuffer_attr[i++] = GLX_PRESERVED_CONTENTS; - pbuffer_attr[i++] = 1; - pbuffer_attr[i++] = GLX_LARGEST_PBUFFER; - pbuffer_attr[i++] = 0; - pbuffer_attr[i++] = 0; - - return - screen_info->glx.create_pbuffer (screen_info->display_info->display, - fbconfig, pbuffer_attr); - } else - return (GLXPbuffer) 0; -} - -void -glitz_glx_pbuffer_destroy (glitz_glx_screen_info_t *screen_info, - GLXPbuffer pbuffer) -{ - screen_info->glx.destroy_pbuffer (screen_info->display_info->display, - pbuffer); -} diff --git a/src/glitz_glx_surface.c b/src/glitz_glx_surface.c deleted file mode 100644 index e4d4f93..0000000 --- a/src/glitz_glx_surface.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifdef HAVE_CONFIG_H -# include "../config.h" -#endif - -#include "glitz_glxint.h" - -static glitz_bool_t -_glitz_glx_surface_push_current (void *abstract_surface, - glitz_constraint_t constraint) -{ - glitz_glx_surface_t *surface = (glitz_glx_surface_t *) abstract_surface; - glitz_bool_t success = 1; - - if (constraint == GLITZ_CN_SURFACE_DRAWABLE_CURRENT && - (!surface->drawable)) { - if (surface->base.format->draw.offscreen) { - surface->drawable = surface->pbuffer = - glitz_glx_pbuffer_create (surface->screen_info, - surface->context->fbconfig, - &surface->base.texture); - } else { - constraint = GLITZ_CN_ANY_CONTEXT_CURRENT; - success = 0; - } - } - - surface = glitz_glx_context_push_current (surface, constraint); - - if (surface) { - glitz_surface_update_state (&surface->base); - return 1; - } - - return success; -} - -static void -_glitz_glx_surface_pop_current (void *abstract_surface) -{ - glitz_glx_surface_t *surface = (glitz_glx_surface_t *) abstract_surface; - - surface = glitz_glx_context_pop_current (surface); - - if (surface) - glitz_surface_update_state (&surface->base); -} - -static glitz_bool_t -_glitz_glx_surface_make_current_read (void *abstract_surface) -{ - /* This doesn't seem to work. - glitz_glx_surface_t *surface = (glitz_glx_surface_t *) abstract_surface; - glitz_glx_static_proc_address_list_t *glx = - &surface->screen_info->display_info->thread_info->glx; - - if ((screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_GLX_MAKE_CURRENT_READ_MASK) && surface->drawable) { - GLXContext context = glXGetCurrentContext (); - - if (context == surface->context->context) - return - glx->make_context_current (surface->screen_info->display_info->display, - glXGetCurrentDrawable (), - surface->drawable, - context); - } - */ - - return 0; -} - -static glitz_texture_t * -_glitz_glx_surface_get_texture (void *abstract_surface, - glitz_bool_t allocate) -{ - glitz_glx_surface_t *surface = (glitz_glx_surface_t *) abstract_surface; - - if (surface->base.flags & GLITZ_SURFACE_FLAG_DIRTY_MASK) { - glitz_bounding_box_t copy_box; - - copy_box.x1 = copy_box.y1 = 0; - copy_box.x2 = surface->base.width; - copy_box.y2 = surface->base.height; - glitz_intersect_bounding_box (&surface->base.dirty_box, - ©_box, ©_box); - - if (!(TEXTURE_ALLOCATED (&surface->base.texture))) - glitz_texture_allocate (&surface->base.backend->gl, - &surface->base.texture); - - glitz_texture_copy_surface (&surface->base.texture, &surface->base, - copy_box.x1, - copy_box.y1, - copy_box.x2 - copy_box.x1, - copy_box.y2 - copy_box.y1, - copy_box.x1, - copy_box.y1); - - surface->base.flags &= ~GLITZ_SURFACE_FLAG_DIRTY_MASK; - } - - if (allocate) { - if (!(TEXTURE_ALLOCATED (&surface->base.texture))) - glitz_texture_allocate (&surface->base.backend->gl, - &surface->base.texture); - } - - if (TEXTURE_ALLOCATED (&surface->base.texture)) - return &surface->base.texture; - else - return NULL; -} - -static glitz_surface_t * -_glitz_glx_surface_create (glitz_glx_screen_info_t *screen_info, - glitz_format_t *format, - int width, - int height) -{ - glitz_glx_surface_t *surface; - glitz_glx_context_t *context; - - if (width <= 0 || height <= 0) - return NULL; - - context = glitz_glx_context_get (screen_info, format); - if (!context) - return NULL; - - surface = (glitz_glx_surface_t *) calloc (1, sizeof (glitz_glx_surface_t)); - if (surface == NULL) - return NULL; - - glitz_surface_init (&surface->base, - &context->backend, - format, - width, - height); - - surface->screen_info = screen_info; - surface->context = context; - - surface->base.flags |= GLITZ_SURFACE_FLAG_OFFSCREEN_MASK; - - if (format->draw.offscreen) - surface->base.flags |= GLITZ_SURFACE_FLAG_DRAWABLE_MASK; - - if (surface->context->backend.gl.need_lookup) { - glitz_glx_context_push_current (surface, GLITZ_CN_SURFACE_CONTEXT_CURRENT); - glitz_glx_context_pop_current (surface); - } - - if (width > 64 || height > 64) { - glitz_glx_context_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT); - glitz_texture_size_check (&surface->base.backend->gl, - &surface->base.texture, - context->max_texture_2d_size, - context->max_texture_rect_size); - glitz_glx_context_pop_current (surface); - if (TEXTURE_INVALID_SIZE (&surface->base.texture) || - (format->draw.offscreen && - ((width > context->max_viewport_dims[0]) || - (height > context->max_viewport_dims[1])))) { - glitz_surface_destroy (&surface->base); - return NULL; - } - } - - return &surface->base; -} - -glitz_surface_t * -glitz_glx_surface_create (Display *display, - int screen, - glitz_format_t *format, - int width, - int height) -{ - glitz_glx_screen_info_t *screen_info; - - screen_info = glitz_glx_screen_info_get (display, screen); - if (!screen_info) - return NULL; - - return _glitz_glx_surface_create (screen_info, format, width, height); -} -slim_hidden_def(glitz_glx_surface_create); - -glitz_surface_t * -glitz_glx_surface_create_for_window (Display *display, - int screen, - glitz_format_t *format, - Window window, - int width, - int height) -{ - glitz_glx_surface_t *surface; - glitz_glx_context_t *context; - glitz_glx_screen_info_t *screen_info; - - if (width <= 0 || height <= 0) - return NULL; - - screen_info = glitz_glx_screen_info_get (display, screen); - if (!screen_info) - return NULL; - - context = glitz_glx_context_get (screen_info, format); - if (!context) - return NULL; - - surface = (glitz_glx_surface_t *) calloc (1, sizeof (glitz_glx_surface_t)); - if (surface == NULL) - return NULL; - - glitz_surface_init (&surface->base, - &context->backend, - format, - width, - height); - - surface->screen_info = screen_info; - surface->context = context; - surface->drawable = window; - - surface->base.flags |= GLITZ_SURFACE_FLAG_DRAWABLE_MASK; - - if (surface->context->backend.gl.need_lookup) { - glitz_glx_context_push_current (surface, GLITZ_CN_SURFACE_CONTEXT_CURRENT); - glitz_glx_context_pop_current (surface); - } - - if (width > 64 || height > 64) { - glitz_glx_context_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT); - glitz_texture_size_check (&surface->base.backend->gl, - &surface->base.texture, - context->max_texture_2d_size, - context->max_texture_rect_size); - glitz_glx_context_pop_current (surface); - if (TEXTURE_INVALID_SIZE (&surface->base.texture) || - (width > context->max_viewport_dims[0]) || - (height > context->max_viewport_dims[1])) { - glitz_surface_destroy (&surface->base); - return NULL; - } - } - - return &surface->base; -} -slim_hidden_def(glitz_glx_surface_create_for_window); - -static glitz_surface_t * -_glitz_glx_surface_create_similar (void *abstract_templ, - glitz_format_t *format, - int width, - int height) -{ - glitz_glx_surface_t *templ = (glitz_glx_surface_t *) abstract_templ; - - if (!format->read.offscreen) - return NULL; - - return _glitz_glx_surface_create (templ->screen_info, format, width, height); -} - -static void -_glitz_glx_surface_destroy (void *abstract_surface) -{ - glitz_glx_surface_t *surface = (glitz_glx_surface_t *) abstract_surface; - - glitz_surface_fini (&surface->base); - - if (surface->drawable && - (glXGetCurrentDrawable () == surface->drawable)) { - surface->drawable = None; - glitz_glx_context_make_current (surface, (GLXContext) 0, 0); - } - - if (surface->pbuffer) - glitz_glx_pbuffer_destroy (surface->screen_info, surface->pbuffer); - - free (surface); -} - -static void -_glitz_glx_surface_swap_buffers (void *abstract_surface) -{ - glitz_glx_surface_t *surface = (glitz_glx_surface_t *) abstract_surface; - - if (surface->pbuffer || (!surface->drawable)) - return; - - glitz_glx_context_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT); - - glXSwapBuffers (surface->screen_info->display_info->display, - surface->drawable); - - glitz_glx_context_pop_current (surface); -} - -void -glitz_glx_surface_backend_init (glitz_surface_backend_t *backend) -{ - backend->create_similar = _glitz_glx_surface_create_similar; - backend->destroy = _glitz_glx_surface_destroy; - backend->push_current = _glitz_glx_surface_push_current; - backend->pop_current = _glitz_glx_surface_pop_current; - backend->get_texture = _glitz_glx_surface_get_texture; - backend->swap_buffers = _glitz_glx_surface_swap_buffers; - backend->make_current_read = _glitz_glx_surface_make_current_read; -} diff --git a/src/glitz_glxint.h b/src/glitz_glxint.h deleted file mode 100644 index 5160aa1..0000000 --- a/src/glitz_glxint.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright © 2004 David Reveman, Peter Nilsson - * - * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. - * - * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. - * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> - */ - -#ifndef GLITZ_GLXINT_H_INCLUDED -#define GLITZ_GLXINT_H_INCLUDED - -#include "glitzint.h" - -#include "glitz-glx.h" - -#include <GL/gl.h> -#include <GL/glx.h> - -#include "glitz_glxext.h" - -#define GLITZ_GLX_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 0) -#define GLITZ_GLX_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK (1L << 1) -#define GLITZ_GLX_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 2) -#define GLITZ_GLX_FEATURE_TEXTURE_BORDER_CLAMP_MASK (1L << 3) -#define GLITZ_GLX_FEATURE_MULTISAMPLE_MASK (1L << 4) -#define GLITZ_GLX_FEATURE_MULTISAMPLE_FILTER_HINT_MASK (1L << 5) -#define GLITZ_GLX_FEATURE_MULTITEXTURE_MASK (1L << 6) -#define GLITZ_GLX_FEATURE_TEXTURE_ENV_COMBINE_MASK (1L << 7) -#define GLITZ_GLX_FEATURE_TEXTURE_ENV_DOT3_MASK (1L << 8) -#define GLITZ_GLX_FEATURE_FRAGMENT_PROGRAM_MASK (1L << 9) -#define GLITZ_GLX_FEATURE_VERTEX_BUFFER_OBJECT_MASK (1L << 10) -#define GLITZ_GLX_FEATURE_PIXEL_BUFFER_OBJECT_MASK (1L << 11) -#define GLITZ_GLX_FEATURE_BLEND_COLOR_MASK (1L << 12) -#define GLITZ_GLX_FEATURE_GLX_FBCONFIG_MASK (1L << 13) -#define GLITZ_GLX_FEATURE_GLX_PBUFFER_MASK (1L << 14) -#define GLITZ_GLX_FEATURE_GLX_MAKE_CURRENT_READ_MASK (1L << 15) -#define GLITZ_GLX_FEATURE_GLX_GET_PROC_ADDRESS_MASK (1L << 16) -#define GLITZ_GLX_FEATURE_GLX_MULTISAMPLE_MASK (1L << 17) - -typedef struct _glitz_glx_surface glitz_glx_surface_t; -typedef struct _glitz_glx_screen_info_t glitz_glx_screen_info_t; -typedef struct _glitz_glx_display_info_t glitz_glx_display_info_t; - -typedef struct _glitz_glx_static_proc_address_list_t { - glitz_glx_get_proc_address_t get_proc_address; - glitz_glx_get_fbconfigs_t get_fbconfigs; - glitz_glx_get_fbconfig_attrib_t get_fbconfig_attrib; - glitz_glx_get_visual_from_fbconfig_t get_visual_from_fbconfig; - glitz_glx_create_pbuffer_t create_pbuffer; - glitz_glx_destroy_pbuffer_t destroy_pbuffer; - glitz_glx_make_context_current_t make_context_current; - glitz_glx_create_new_context_t create_new_context; -} glitz_glx_static_proc_address_list_t; - -typedef struct _glitz_glx_thread_info_t { - glitz_glx_display_info_t **displays; - int n_displays; - char *gl_library; - void *dlhand; -} glitz_glx_thread_info_t; - -struct _glitz_glx_display_info_t { - glitz_glx_thread_info_t *thread_info; - Display *display; - glitz_glx_screen_info_t **screens; - int n_screens; -}; - -typedef struct _glitz_glx_context_info_t { - glitz_glx_surface_t *surface; - glitz_constraint_t constraint; -} glitz_glx_context_info_t; - -typedef struct _glitz_glx_context_t { - GLXContext context; - XID id; - GLXFBConfig fbconfig; - glitz_surface_backend_t backend; - glitz_gl_int_t max_viewport_dims[2]; - glitz_gl_int_t max_texture_2d_size; - glitz_gl_int_t max_texture_rect_size; -} glitz_glx_context_t; - -struct _glitz_glx_screen_info_t { - glitz_glx_display_info_t *display_info; - int screen; - - glitz_format_t *formats; - XID *format_ids; - int n_formats; - - glitz_glx_context_t **contexts; - int n_contexts; - - glitz_glx_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; - int context_stack_size; - - glitz_glx_context_t root_context; - GLXDrawable root_drawable; - Colormap root_colormap; - - unsigned long feature_mask; - unsigned long glx_feature_mask; - glitz_gl_float_t gl_version; - glitz_gl_float_t glx_version; - - glitz_glx_static_proc_address_list_t glx; - - glitz_program_map_t program_map; -}; - -struct _glitz_glx_surface { - glitz_surface_t base; - - glitz_glx_screen_info_t *screen_info; - glitz_glx_context_t *context; - GLXDrawable drawable; - GLXDrawable pbuffer; -}; - -extern glitz_status_t __internal_linkage -glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info); - -extern glitz_glx_screen_info_t *__internal_linkage -glitz_glx_screen_info_get (Display *display, - int screen); - -extern glitz_function_pointer_t __internal_linkage -glitz_glx_get_proc_address (glitz_glx_screen_info_t *screen_info, - const char *name); - -extern glitz_glx_context_t *__internal_linkage -glitz_glx_context_get (glitz_glx_screen_info_t *screen_info, - glitz_format_t *format); - -extern void __internal_linkage -glitz_glx_context_destroy (glitz_glx_screen_info_t *screen_info, - glitz_glx_context_t *context); - -extern int __internal_linkage -glitz_glx_ensure_pbuffer_support (glitz_glx_screen_info_t *screen_info, - XID fbconfigid); - -extern glitz_glx_context_t *__internal_linkage -glitz_glx_context_get_default (glitz_glx_screen_info_t *screen_info); - -extern void __internal_linkage -glitz_glx_context_make_current (glitz_glx_surface_t *surface, - GLXContext context, - glitz_bool_t flush); - -extern glitz_glx_surface_t *__internal_linkage -glitz_glx_context_push_current (glitz_glx_surface_t *surface, - glitz_constraint_t constraint); - -extern glitz_glx_surface_t *__internal_linkage -glitz_glx_context_pop_current (glitz_glx_surface_t *surface); - -extern void __internal_linkage -glitz_glx_context_proc_address_lookup (glitz_glx_screen_info_t *screen_info, - glitz_glx_context_t *context); - -extern void __internal_linkage -glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info); - -extern GLXPbuffer __internal_linkage -glitz_glx_pbuffer_create (glitz_glx_screen_info_t *screen_info, - GLXFBConfig fbconfig, - glitz_texture_t *texture); - -extern void __internal_linkage -glitz_glx_pbuffer_destroy (glitz_glx_screen_info_t *screen_info, - GLXPbuffer pbuffer); - -extern void __internal_linkage -glitz_glx_surface_backend_init (glitz_surface_backend_t *backend); - -/* Avoid unnecessary PLT entries. */ - -slim_hidden_proto(glitz_glx_init) -slim_hidden_proto(glitz_glx_fini) -slim_hidden_proto(glitz_glx_find_format) -slim_hidden_proto(glitz_glx_find_standard_format) -slim_hidden_proto(glitz_glx_get_visual_info_from_format) -slim_hidden_proto(glitz_glx_surface_create) -slim_hidden_proto(glitz_glx_surface_create_for_window) - -#endif /* GLITZ_GLXINT_H_INCLUDED */ diff --git a/src/glitz_operator.c b/src/glitz_operator.c index 6d9975b..223b7ad 100644 --- a/src/glitz_operator.c +++ b/src/glitz_operator.c @@ -86,13 +86,5 @@ glitz_set_operator (glitz_gl_proc_address_list_t *gl, glitz_operator_t op) { gl->enable (GLITZ_GL_BLEND); gl->blend_func (GLITZ_GL_ONE, GLITZ_GL_ONE); break; - case GLITZ_OPERATOR_SATURATE: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_SRC_ALPHA_SATURATE, GLITZ_GL_ONE); - break; - default: - gl->enable (GLITZ_GL_BLEND); - gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ONE); - break; } } diff --git a/src/glitz_pixel.c b/src/glitz_pixel.c index 564ac05..9af952d 100644 --- a/src/glitz_pixel.c +++ b/src/glitz_pixel.c @@ -31,13 +31,15 @@ #include <string.h> -typedef struct _glitz_gl_pixel_format glitz_gl_pixel_format_t; - -static struct _glitz_gl_pixel_format { +#include <stdio.h> + +typedef struct _glitz_gl_pixel_format { glitz_pixel_format_t pixel; - glitz_gl_enum_t format; - glitz_gl_enum_t type; -} _gl_format_map[] = { + glitz_gl_enum_t format; + glitz_gl_enum_t type; +} glitz_gl_pixel_format_t; + +static glitz_gl_pixel_format_t _gl_pixel_formats[] = { { { { @@ -55,8 +57,8 @@ static struct _glitz_gl_pixel_format { }, { { { - 24, - 0x00000000, + 32, + 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff @@ -64,41 +66,41 @@ static struct _glitz_gl_pixel_format { 0, 0, 0, GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP }, + GLITZ_GL_BGRA, -#if IMAGE_BYTE_ORDER == MSBFirst - GLITZ_GL_RGB, +#if IMAGE_BYTE_ORDER == MSBFirst + GLITZ_GL_UNSIGNED_INT_8_8_8_8_REV #else - GLITZ_GL_BGR, + GLITZ_GL_UNSIGNED_BYTE #endif - GLITZ_GL_UNSIGNED_BYTE - }, { + } +}; + +static glitz_gl_pixel_format_t _gl_packed_pixel_formats[] = { + { { { - 32, - 0xff000000, - 0x00ff0000, - 0x0000ff00, - 0x000000ff + 16, + 0x00000000, + 0x0000f800, + 0x000007e0, + 0x0000001f }, 0, 0, 0, GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP }, - GLITZ_GL_BGRA, + GLITZ_GL_BGR, #if IMAGE_BYTE_ORDER == MSBFirst - GLITZ_GL_UNSIGNED_INT_8_8_8_8_REV + GLITZ_GL_UNSIGNED_SHORT_5_6_5_REV #else - GLITZ_GL_UNSIGNED_BYTE + GLITZ_GL_UNSIGNED_SHORT_5_6_5 #endif } }; -#define GLITZ_GL_FORMAT_A 0 -#define GLITZ_GL_FORMAT_RGB 1 -#define GLITZ_GL_FORMAT_ARGB 2 - typedef struct _glitz_pixel_color { uint32_t r, g, b, a; } glitz_pixel_color_t; @@ -286,10 +288,12 @@ static void _glitz_pixel_transform (unsigned long transform, glitz_image_t *src, glitz_image_t *dst, - int x_src, - int x_dst, - int width, - int height) + int x_src, + int y_src, + int x_dst, + int y_dst, + int width, + int height) { int src_stride, dst_stride; int x, y, bytes_per_pixel = 0; @@ -352,11 +356,11 @@ _glitz_pixel_transform (unsigned long transform, for (y = 0; y < height; y++) { if (src->format->scanline_order != dst->format->scanline_order) - src_op.line = &src->data[(src->height - y - 1) * src_stride]; + src_op.line = &src->data[(src->height - (y + y_src) - 1) * src_stride]; else - src_op.line = &src->data[y * src_stride]; + src_op.line = &src->data[(y + y_src) * src_stride]; - dst_op.line = &dst->data[y * dst_stride]; + dst_op.line = &dst->data[(y + y_dst) * dst_stride]; if (transform & GLITZ_TRANSFORM_PIXELS_MASK) { for (x = 0; x < width; x++) { @@ -371,7 +375,7 @@ _glitz_pixel_transform (unsigned long transform, it will never be used for bitmaps */ if (bytes_per_pixel == 0) bytes_per_pixel = src->format->masks.bpp / 8; - + memcpy (&dst_op.line[x_dst * bytes_per_pixel], &src_op.line[x_src * bytes_per_pixel], width * bytes_per_pixel); @@ -379,49 +383,174 @@ _glitz_pixel_transform (unsigned long transform, } } +static glitz_bool_t +_glitz_format_match (glitz_pixel_masks_t *masks1, + glitz_pixel_masks_t *masks2, + glitz_color_format_t *internal_color) +{ + if (masks1->bpp != masks2->bpp) + return 0; + + if (internal_color->red_size) + if (masks1->red_mask != masks2->red_mask) + return 0; + + if (internal_color->green_size) + if (masks1->green_mask != masks2->green_mask) + return 0; + + if (internal_color->blue_size) + if (masks1->blue_mask != masks2->blue_mask) + return 0; + + if (internal_color->alpha_size) + if (masks1->alpha_mask != masks2->alpha_mask) + return 0; + + return 1; +} + static glitz_gl_pixel_format_t * -_glitz_find_gl_pixel_format (glitz_pixel_format_t *format) +_glitz_find_gl_pixel_format (glitz_pixel_format_t *format, + glitz_color_format_t *internal_color, + unsigned long feature_mask) { int i, n_formats; - n_formats = sizeof (_gl_format_map) / sizeof (glitz_gl_pixel_format_t); + n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t); for (i = 0; i < n_formats; i++) { - if (memcmp (&_gl_format_map[i].pixel.masks, &format->masks, - sizeof (glitz_pixel_masks_t)) == 0) - return &_gl_format_map[i]; + if (_glitz_format_match (&_gl_pixel_formats[i].pixel.masks, &format->masks, + internal_color)) + return &_gl_pixel_formats[i]; + } + + if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK) { + n_formats = sizeof (_gl_packed_pixel_formats) / + sizeof (glitz_gl_pixel_format_t); + + for (i = 0; i < n_formats; i++) { + if (_glitz_format_match (&_gl_packed_pixel_formats[i].pixel.masks, + &format->masks, + internal_color)) + return &_gl_packed_pixel_formats[i]; + } } return NULL; } +static int +_component_size (unsigned long mask) +{ + unsigned long y; + + /* HACKMEM 169 */ + y = (mask >> 1) & 033333333333; + y = mask - y - ((y >> 1) & 033333333333); + return (((y + (y >> 3)) & 030707070707) % 077); +} + +static glitz_bool_t +_glitz_format_diff (glitz_pixel_masks_t *masks, + glitz_color_format_t *pixel_color, + glitz_color_format_t *internal_color, + int *diff) +{ + int size; + + *diff = 0; + + size = _component_size (masks->red_mask); + if (size < pixel_color->red_size && size < internal_color->red_size) + return 0; + + *diff += abs (size - internal_color->red_size); + + size = _component_size (masks->green_mask); + if (size < pixel_color->green_size && size < internal_color->green_size) + return 0; + + *diff += abs (size - internal_color->green_size); + + size = _component_size (masks->blue_mask); + if (size < pixel_color->blue_size && size < internal_color->blue_size) + return 0; + + *diff += abs (size - internal_color->blue_size); + + size = _component_size (masks->alpha_mask); + if (size < pixel_color->alpha_size && size < internal_color->alpha_size) + return 0; + + *diff += abs (size - internal_color->alpha_size); + + return 1; +} + static glitz_gl_pixel_format_t * -_glitz_best_gl_pixel_format (glitz_format_t *format) +_glitz_find_best_gl_pixel_format (glitz_pixel_format_t *format, + glitz_color_format_t *internal_color, + unsigned long feature_mask) { - if (format->red_size) { - if (format->alpha_size) - return &_gl_format_map[GLITZ_GL_FORMAT_ARGB]; - else - return &_gl_format_map[GLITZ_GL_FORMAT_RGB]; - } else - return &_gl_format_map[GLITZ_GL_FORMAT_A]; + glitz_gl_pixel_format_t *best = NULL; + glitz_color_format_t color; + int i, n_formats, diff, best_diff = MAXSHORT; + + color.red_size = _component_size (format->masks.red_mask); + color.green_size = _component_size (format->masks.green_mask); + color.blue_size = _component_size (format->masks.blue_mask); + color.alpha_size = _component_size (format->masks.alpha_mask); + + n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t); + for (i = 0; best_diff > 0 && i < n_formats; i++) { + if (_glitz_format_diff (&_gl_pixel_formats[i].pixel.masks, + &color, + internal_color, + &diff)) { + if (diff < best_diff) { + best = &_gl_pixel_formats[i]; + best_diff = diff; + } + } + } + + if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK) { + n_formats = sizeof (_gl_packed_pixel_formats) / + sizeof (glitz_gl_pixel_format_t); + + for (i = 0; best_diff > 0 && i < n_formats; i++) { + if (_glitz_format_diff (&_gl_packed_pixel_formats[i].pixel.masks, + &color, + internal_color, + &diff)) { + if (diff < best_diff) { + best = &_gl_packed_pixel_formats[i]; + best_diff = diff; + } + } + } + } + + return best; } void -glitz_set_pixels (glitz_surface_t *dst, - int x_dst, - int y_dst, - int width, - int height, +glitz_set_pixels (glitz_surface_t *dst, + int x_dst, + int y_dst, + int width, + int height, glitz_pixel_format_t *format, - glitz_buffer_t *buffer) + glitz_buffer_t *buffer) { - glitz_gl_proc_address_list_t *gl; - glitz_bool_t to_drawable; glitz_texture_t *texture; char *pixels, *data = NULL; glitz_gl_pixel_format_t *gl_format = NULL; unsigned long transform = 0; int xoffset, bytes_per_line, bpp; + glitz_box_t box; + + GLITZ_GL_SURFACE (dst); if (x_dst < 0 || x_dst > (dst->width - width) || y_dst < 0 || y_dst > (dst->height - height)) { @@ -429,28 +558,24 @@ glitz_set_pixels (glitz_surface_t *dst, return; } - gl = &dst->backend->gl; - - if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) - transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK; - /* find direct format */ - gl_format = _glitz_find_gl_pixel_format (format); + gl_format = + _glitz_find_gl_pixel_format (format, + &dst->format->color, + dst->drawable->backend->feature_mask); if (gl_format == NULL) { transform |= GLITZ_TRANSFORM_PIXELS_MASK; - gl_format = _glitz_best_gl_pixel_format (dst->format); + gl_format = + _glitz_find_best_gl_pixel_format (format, + &dst->format->color, + dst->drawable->backend->feature_mask); } - if (SURFACE_DRAWABLE (dst)) - to_drawable = 1; - else - to_drawable = 0; - - if (to_drawable) { - if (!glitz_surface_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) - to_drawable = 0; - } else - glitz_surface_push_current (dst, GLITZ_CN_ANY_CONTEXT_CURRENT); + /* should not happen */ + if (gl_format == NULL) + return; + + glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); texture = glitz_surface_get_texture (dst, 1); if (!texture) { @@ -458,6 +583,11 @@ glitz_set_pixels (glitz_surface_t *dst, return; } + if (height > 1) { + if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) + transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK; + } + glitz_texture_bind (gl, texture); if (transform) { @@ -488,8 +618,8 @@ glitz_set_pixels (glitz_surface_t *dst, _glitz_pixel_transform (transform, &src_image, &dst_image, - format->xoffset, - 0, + format->xoffset, 0, + 0, 0, width, height); glitz_buffer_unmap (buffer); @@ -534,42 +664,17 @@ glitz_set_pixels (glitz_surface_t *dst, if (transform == 0) glitz_buffer_unbind (buffer); - - if (to_drawable) { - glitz_bounding_box_t box; - - box.x1 = x_dst; - box.y1 = y_dst; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - - glitz_texture_set_tex_gen (gl, texture, 0, 0, 0); - - gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); - gl->color_4us (0x0, 0x0, 0x0, 0xffff); - - glitz_texture_ensure_wrap (gl, texture, GLITZ_GL_CLAMP_TO_EDGE); - glitz_texture_ensure_filter (gl, texture, GLITZ_GL_NEAREST); - - glitz_set_operator (gl, GLITZ_OPERATOR_SRC); - - gl->scissor (box.x1, - dst->height - box.y2, - width, height); - - glitz_geometry_enable_default (gl, dst, &box); - - gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); - - if (x_dst == 0 && y_dst == 0 && - width == dst->width && height == dst->height) - dst->flags &= ~GLITZ_SURFACE_FLAG_DIRTY_MASK; - } glitz_texture_unbind (gl, texture); - dst->flags |= GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK; + box.x1 = x_dst; + box.y1 = y_dst; + box.x2 = box.x1 + width; + box.y2 = box.y1 + height; + + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_DRAWABLE_MASK | + GLITZ_DAMAGE_SOLID_MASK); glitz_surface_pop_current (dst); @@ -578,15 +683,14 @@ glitz_set_pixels (glitz_surface_t *dst, } void -glitz_get_pixels (glitz_surface_t *src, - int x_src, - int y_src, - int width, - int height, +glitz_get_pixels (glitz_surface_t *src, + int x_src, + int y_src, + int width, + int height, glitz_pixel_format_t *format, - glitz_buffer_t *buffer) + glitz_buffer_t *buffer) { - glitz_gl_proc_address_list_t *gl; glitz_bool_t from_drawable; glitz_texture_t *texture = NULL; char *pixels, *data = NULL; @@ -594,6 +698,9 @@ glitz_get_pixels (glitz_surface_t *src, unsigned long transform = 0; int src_x = 0, src_y = 0, src_w = width, src_h = height; int xoffset, bytes_per_line, bpp; + glitz_color_format_t *color; + + GLITZ_GL_SURFACE (src); if (x_src < 0 || x_src > (src->width - width) || y_src < 0 || y_src > (src->height - height)) { @@ -601,12 +708,12 @@ glitz_get_pixels (glitz_surface_t *src, return; } - gl = &src->backend->gl; - - if (glitz_surface_push_current (src, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) { + if (glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT)) { from_drawable = 1; + color = &src->attached->format->color; } else { from_drawable = 0; + color = &src->format->color; texture = glitz_surface_get_texture (src, 0); if (!texture) { @@ -614,17 +721,31 @@ glitz_get_pixels (glitz_surface_t *src, return; } - transform |= GLITZ_TRANSFORM_COPY_BOX_MASK; + if (texture->width > width || texture->height > height) + transform |= GLITZ_TRANSFORM_COPY_BOX_MASK; } - if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) - transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK; - + if (transform || height > 1) { + if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) + transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK; + } + /* find direct format */ - gl_format = _glitz_find_gl_pixel_format (format); + gl_format = + _glitz_find_gl_pixel_format (format, color, + src->drawable->backend->feature_mask); if (gl_format == NULL) { transform |= GLITZ_TRANSFORM_PIXELS_MASK; - gl_format = _glitz_best_gl_pixel_format (src->format); + + gl_format = + _glitz_find_best_gl_pixel_format (format, color, + src->drawable->backend->feature_mask); + } + + /* should not happen */ + if (gl_format == NULL) { + glitz_surface_pop_current (src); + return; } if (transform) { @@ -675,21 +796,18 @@ glitz_get_pixels (glitz_surface_t *src, gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, 0); } - if (from_drawable) { - if (SURFACE_OFFSCREEN (src)) { - x_src += src->texture.box.x1; - y_src += src->texture.box.y1; - } - - if (src->format->doublebuffer) - gl->read_buffer (src->read_buffer); + if (from_drawable) { + gl->read_buffer (src->buffer); + + gl->disable (GLITZ_GL_SCISSOR_TEST); - gl->scissor (0, 0, src->width, src->height); - - gl->read_pixels (x_src, src->height - y_src - height, + gl->read_pixels (x_src + src->x, + src->attached->height - (y_src + src->y) - height, width, height, gl_format->format, gl_format->type, pixels); + + gl->enable (GLITZ_GL_SCISSOR_TEST); } else { glitz_texture_bind (gl, texture); gl->get_tex_image (texture->target, 0, @@ -700,29 +818,22 @@ glitz_get_pixels (glitz_surface_t *src, if (transform) { glitz_image_t src_image, dst_image; - int stride; - src_image.data = data + src_y * bytes_per_line; + src_image.data = data; src_image.format = &gl_format->pixel; src_image.width = src_w; src_image.height = src_h; - if (format->bytes_per_line) - stride = format->bytes_per_line; - else - stride = (((width * format->masks.bpp) / 8) + 3) & -4; - dst_image.data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); - dst_image.data += format->skip_lines * stride; dst_image.format = format; dst_image.width = width; dst_image.height = height; - + _glitz_pixel_transform (transform, &src_image, &dst_image, - src_x, - format->xoffset, + src_x, src_y, + format->xoffset, format->skip_lines, width, height); glitz_buffer_unmap (buffer); diff --git a/src/glitz_program.c b/src/glitz_program.c index 6930ab2..01f6bae 100644 --- a/src/glitz_program.c +++ b/src/glitz_program.c @@ -346,9 +346,9 @@ _string_array_to_char_array (char *dst, const char *src[]) #define GRADIENT_STOP_SIZE 256 static glitz_gl_uint_t -_glitz_create_fragment_program (glitz_composite_op_t *op, - int fp_type, - int id, +_glitz_create_fragment_program (glitz_composite_op_t *op, + int fp_type, + int id, const glitz_program_expand_t *expand) { char buffer[1024], *program = NULL, *tex, *p = NULL; @@ -481,7 +481,7 @@ glitz_program_map_init (glitz_program_map_t *map) void glitz_program_map_fini (glitz_gl_proc_address_list_t *gl, - glitz_program_map_t *map) + glitz_program_map_t *map) { glitz_gl_uint_t program; int i, j, k, x, y; @@ -518,15 +518,16 @@ glitz_program_map_fini (glitz_gl_proc_address_list_t *gl, glitz_gl_uint_t glitz_get_fragment_program (glitz_composite_op_t *op, - int fp_type, - int id) + int fp_type, + int id) { + glitz_program_map_t *map; glitz_program_t *program; int t0 = TEXTURE_INDEX (op->src); int t1 = TEXTURE_INDEX (op->mask); - program = - &op->dst->backend->program_map->filters[op->type][fp_type].fp[t0][t1]; + map = op->dst->drawable->backend->program_map; + program = &map->filters[op->type][fp_type].fp[t0][t1]; if (program->size < id) { int old_size; @@ -544,7 +545,7 @@ glitz_get_fragment_program (glitz_composite_op_t *op, } if (program->name[id - 1] == 0) { - glitz_surface_push_current (op->dst, GLITZ_CN_SURFACE_CONTEXT_CURRENT); + glitz_surface_push_current (op->dst, GLITZ_CONTEXT_CURRENT); program->name[id - 1] = _glitz_create_fragment_program (op, fp_type, id, diff --git a/src/glitz_rect.c b/src/glitz_rect.c index 22a8aa3..233fd4c 100644 --- a/src/glitz_rect.c +++ b/src/glitz_rect.c @@ -37,8 +37,8 @@ static void glitz_rectangle_bounds (const glitz_rectangle_t *rects, - int n_rects, - glitz_bounding_box_t *box) + int n_rects, + glitz_box_t *box) { box->x1 = MAXSHORT; box->x2 = MINSHORT; @@ -58,31 +58,34 @@ glitz_rectangle_bounds (const glitz_rectangle_t *rects, } void -glitz_set_rectangles (glitz_surface_t *dst, - const glitz_color_t *color, +glitz_set_rectangles (glitz_surface_t *dst, + const glitz_color_t *color, const glitz_rectangle_t *rects, - int n_rects) + int n_rects) { - glitz_bounding_box_t bounds; - glitz_gl_proc_address_list_t *gl = &dst->backend->gl; + glitz_box_t bounds; + + GLITZ_GL_SURFACE (dst); glitz_rectangle_bounds (rects, n_rects, &bounds); if (bounds.x1 > dst->width || bounds.y1 > dst->height || bounds.x2 < 0 || bounds.y2 < 0) return; - if (SURFACE_SOLID (dst) && SURFACE_OFFSCREEN (dst) && + if (SURFACE_SOLID (dst) && (bounds.x2 - bounds.x1) > 0 && (bounds.y2 - bounds.y1) > 0) { - STORE_16 (dst->solid.red, dst->format->red_size, color->red); - STORE_16 (dst->solid.green, dst->format->green_size, color->green); - STORE_16 (dst->solid.blue, dst->format->blue_size, color->blue); - STORE_16 (dst->solid.alpha, dst->format->alpha_size, color->alpha); - - dst->flags |= GLITZ_SURFACE_FLAG_DRAWABLE_DIRTY_MASK; + STORE_16 (dst->solid.red, dst->format->color.red_size, color->red); + STORE_16 (dst->solid.green, dst->format->color.green_size, color->green); + STORE_16 (dst->solid.blue, dst->format->color.blue_size, color->blue); + STORE_16 (dst->solid.alpha, dst->format->color.alpha_size, color->alpha); + + glitz_surface_damage (dst, &bounds, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_DRAWABLE_MASK); return; } - if (glitz_surface_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) { + if (glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) { gl->clear_color (color->red / (glitz_gl_clampf_t) 0xffff, color->green / (glitz_gl_clampf_t) 0xffff, color->blue / (glitz_gl_clampf_t) 0xffff, @@ -90,12 +93,14 @@ glitz_set_rectangles (glitz_surface_t *dst, for (; n_rects; n_rects--, rects++) { gl->scissor (rects->x, - dst->height - rects->y - rects->height, + dst->attached->height - dst->y - rects->y - rects->height, rects->width, rects->height); gl->clear (GLITZ_GL_COLOR_BUFFER_BIT); } - glitz_surface_dirty (dst, &bounds); + glitz_surface_damage (dst, &bounds, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); } else { static glitz_pixel_format_t pf = { { @@ -154,12 +159,12 @@ glitz_set_rectangles (glitz_surface_t *dst, slim_hidden_def(glitz_set_rectangles); void -glitz_set_rectangle (glitz_surface_t *dst, +glitz_set_rectangle (glitz_surface_t *dst, const glitz_color_t *color, - int x, - int y, - unsigned int width, - unsigned int height) + int x, + int y, + unsigned int width, + unsigned int height) { glitz_rectangle_t rect; diff --git a/src/glitz_region.c b/src/glitz_region.c new file mode 100644 index 0000000..253ad31 --- /dev/null +++ b/src/glitz_region.c @@ -0,0 +1,166 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitzint.h" + +#define REGION_ALLOC_CHUNK 16 + +#define BOX_SUBSUMS_BOX(b1, b2) \ + ((b2)->x1 >= (b1)->x1 && \ + (b2)->x2 <= (b1)->x2 && \ + (b2)->y1 >= (b1)->y1 && \ + (b2)->y2 <= (b1)->y2) + +#define BOX_INTERSECTS_BOX(b1, b2) \ + ((b1)->x1 < (b2)->x2 && \ + (b1)->x2 > (b2)->x1 && \ + (b1)->y1 < (b2)->y2 && \ + (b1)->y2 > (b2)->y1) + +#define BOX_CLOSE_TO_BOX(b1, b2) \ + ((b1)->x1 < ((b2)->x2 + 1) && \ + (b1)->x2 > ((b2)->x1 - 1) && \ + (b1)->y1 < ((b2)->y2 + 1) && \ + (b1)->y2 > ((b2)->y1 - 1)) + +#define BOX_NEXT_TO_BOX(b1, b2) \ + ((((b1)->x1 == (b2)->x2 || \ + (b1)->x2 == (b2)->x1) && \ + (b1)->y1 == (b2)->y1 && \ + (b1)->y2 == (b2)->y2) || \ + (((b1)->y1 == (b2)->y2 || \ + (b1)->y2 == (b2)->y1) && \ + (b1)->x1 == (b2)->x1 && \ + (b1)->x2 == (b2)->x2)) + +#define MERGE_BOXES(d, b1, b2) \ + { \ + (d)->x1 = MIN ((b1)->x1, (b2)->x1); \ + (d)->y1 = MIN ((b1)->y1, (b2)->y1); \ + (d)->x2 = MAX ((b1)->x2, (b2)->x2); \ + (d)->y2 = MAX ((b1)->y2, (b2)->y2); \ + } + +/* + * No real union, boxes that intersect are just joined into bigger boxes. + * This is OK for our needs and it keeps the number of boxes down to a + * minimum and makes it faster. + */ +glitz_status_t +glitz_region_union (glitz_region_t *region, + glitz_box_t *ubox) +{ + if (region->n_box == 0) { + region->extents = *ubox; + region->box = ®ion->extents; + region->n_box = 1; + + return GLITZ_STATUS_SUCCESS; + } + + if (BOX_CLOSE_TO_BOX (ubox, ®ion->extents)) { + glitz_box_t *box, *new_box, *dst_box; + int n_box; + + box = region->box; + n_box = region->n_box; + + while (n_box--) { + if (BOX_SUBSUMS_BOX (box, ubox)) + return GLITZ_STATUS_SUCCESS; + + box++; + } + + box = region->box; + n_box = region->n_box; + + new_box = ubox; + dst_box = NULL; + while (n_box--) { + + if (BOX_INTERSECTS_BOX (box, new_box) || + BOX_NEXT_TO_BOX (box, new_box)) { + + if (dst_box) { + /* + * Remove box from region + */ + region->n_box--; + if (region->n_box == 1) { + MERGE_BOXES (®ion->extents, box, new_box); + region->box = ®ion->extents; + + return GLITZ_STATUS_SUCCESS; + } else { + MERGE_BOXES (dst_box, box, new_box); + if (n_box) + memmove (box, box + 1, n_box * sizeof (glitz_box_t)); + } + continue; + } else { + dst_box = box; + MERGE_BOXES (dst_box, box, new_box); + new_box = dst_box; + } + } + box++; + } + + if (dst_box) { + if (region->n_box > 1) + MERGE_BOXES (®ion->extents, ®ion->extents, ubox); + + return GLITZ_STATUS_SUCCESS; + } + } + + /* + * Add box to region + */ + if (region->size < (region->n_box + 1)) { + region->size += REGION_ALLOC_CHUNK; + region->data = (void *) realloc (region->data, + sizeof (glitz_box_t) * region->size); + if (!region->data) + return GLITZ_STATUS_NO_MEMORY; + } + + region->box = (glitz_box_t *) region->data; + + region->box[region->n_box] = *ubox; + if (region->n_box == 1) + region->box[0] = region->extents; + + region->n_box++; + + MERGE_BOXES (®ion->extents, ®ion->extents, ubox); + + return GLITZ_STATUS_SUCCESS; +} diff --git a/src/glitz_surface.c b/src/glitz_surface.c index f765b83..74c73af 100644 --- a/src/glitz_surface.c +++ b/src/glitz_surface.c @@ -32,94 +32,92 @@ #include <stdlib.h> #include <string.h> -void -glitz_surface_init (glitz_surface_t *surface, - glitz_surface_backend_t *backend, - glitz_format_t *format, - int width, - int height) +glitz_surface_t * +glitz_surface_create (glitz_drawable_t *drawable, + glitz_format_t *format, + unsigned int width, + unsigned int height) { - surface->backend = backend; + glitz_surface_t *surface; + + if (width == 0 || height == 0) + return NULL; - surface->ref_count = 1; + surface = (glitz_surface_t *) calloc (1, sizeof (glitz_surface_t)); + if (surface == NULL) + return NULL; - surface->filter = GLITZ_FILTER_NEAREST; + surface->drawable = drawable; + glitz_drawable_reference (drawable); + surface->ref_count = 1; + surface->filter = GLITZ_FILTER_NEAREST; surface->format = format; - surface->width = width; - surface->height = height; - surface->update_mask = GLITZ_UPDATE_ALL_MASK; + surface->width = (int) width; + surface->height = (int) height; + surface->buffer = GLITZ_GL_FRONT; - if (format->doublebuffer) - surface->draw_buffer = surface->read_buffer = GLITZ_GL_BACK; - else - surface->draw_buffer = surface->read_buffer = GLITZ_GL_FRONT; + REGION_INIT (&surface->texture_damage, NULL_BOX); + REGION_INIT (&surface->drawable_damage, NULL_BOX); if (width == 1 && height == 1) { surface->flags |= GLITZ_SURFACE_FLAG_SOLID_MASK; - surface->solid.red = surface->solid.green = surface->solid.blue = 0x0; surface->solid.alpha = 0xffff; } - - glitz_texture_init (&surface->texture, - width, height, - glitz_format_get_best_texture_format (backend->formats, - backend->n_formats, - format), - backend->feature_mask); + + glitz_texture_init (&surface->texture, width, height, + drawable->backend->texture_formats[format->id], + drawable->backend->feature_mask); + + if (width > 64 || height > 64) { + glitz_surface_push_current (surface, GLITZ_CONTEXT_CURRENT); + glitz_texture_size_check (&drawable->backend->gl, &surface->texture, + drawable->backend->max_texture_2d_size, + drawable->backend->max_texture_rect_size); + glitz_surface_pop_current (surface); + if (TEXTURE_INVALID_SIZE (&surface->texture)) { + glitz_surface_destroy (surface); + return NULL; + } + } + + return surface; } void -glitz_surface_fini (glitz_surface_t *surface) +glitz_surface_destroy (glitz_surface_t *surface) { - if (surface->geometry.buffer) - glitz_buffer_destroy (surface->geometry.buffer); - + if (!surface) + return; + + surface->ref_count--; + if (surface->ref_count) + return; + if (surface->texture.name) { - glitz_surface_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT); - glitz_texture_fini (&surface->backend->gl, &surface->texture); + glitz_surface_push_current (surface, GLITZ_ANY_CONTEXT_CURRENT); + glitz_texture_fini (&surface->drawable->backend->gl, &surface->texture); glitz_surface_pop_current (surface); } + + REGION_UNINIT (&surface->texture_damage); + REGION_UNINIT (&surface->drawable_damage); + + if (surface->geometry.buffer) + glitz_buffer_destroy (surface->geometry.buffer); if (surface->transform) free (surface->transform); if (surface->filter_params) glitz_filter_params_destroy (surface->filter_params); -} - -glitz_format_t * -glitz_surface_find_similar_standard_format (glitz_surface_t *surface, - glitz_format_name_t format_name) -{ - return - glitz_format_find_standard (surface->backend->formats, - surface->backend->n_formats, - format_name); -} -slim_hidden_def(glitz_surface_find_similar_standard_format); - -glitz_format_t * -glitz_surface_find_similar_format (glitz_surface_t *surface, - unsigned long mask, - const glitz_format_t *templ, - int count) -{ - return glitz_format_find (surface->backend->formats, - surface->backend->n_formats, - mask, templ, count); -} -glitz_surface_t * -glitz_surface_create_similar (glitz_surface_t *templ, - glitz_format_t *format, - int width, - int height) -{ - if (width < 1 || height < 1) - return NULL; + if (surface->attached) + glitz_drawable_destroy (surface->attached); - return templ->backend->create_similar (templ, format, width, height); + glitz_drawable_destroy (surface->drawable); + + free (surface); } void @@ -131,70 +129,161 @@ glitz_surface_reference (glitz_surface_t *surface) surface->ref_count++; } -void -glitz_surface_destroy (glitz_surface_t *surface) +static void +_glitz_surface_sync_texture (glitz_surface_t *surface) { - if (!surface) - return; + if (REGION_NOTEMPTY (&surface->texture_damage)) { + glitz_box_t *box; + int n_box; - surface->ref_count--; - if (surface->ref_count) - return; + GLITZ_GL_SURFACE (surface); + + if (!(TEXTURE_ALLOCATED (&surface->texture))) + glitz_texture_allocate (gl, &surface->texture); + + if (SURFACE_SOLID (surface) && (!SURFACE_SOLID_DAMAGE (surface))) { + glitz_gl_float_t color[4]; + + if (TEXTURE_ALLOCATED (&surface->texture)) { + color[0] = surface->solid.red / 65535.0f; + color[1] = surface->solid.green / 65535.0f; + color[2] = surface->solid.blue / 65535.0f; + color[3] = surface->solid.alpha / 65535.0f; + + glitz_texture_bind (gl, &surface->texture); + gl->tex_sub_image_2d (surface->texture.target, 0, + surface->texture.box.x1, surface->texture.box.y1, + 1, 1, GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color); + glitz_texture_unbind (gl, &surface->texture); + } + REGION_EMPTY (&surface->texture_damage); + return; + } + + glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); + + gl->read_buffer (surface->buffer); + + gl->disable (GLITZ_GL_SCISSOR_TEST); + + glitz_texture_bind (gl, &surface->texture); + + box = REGION_RECTS (&surface->texture_damage); + n_box = REGION_NUM_RECTS (&surface->texture_damage); - surface->backend->destroy (surface); + while (n_box--) { + glitz_texture_copy_drawable (gl, + &surface->texture, + surface->attached, + box->x1 + surface->x, + box->y1 + surface->y, + box->x2 - box->x1, + box->y2 - box->y1, + box->x1, + box->y1); + + box++; + } + + REGION_EMPTY (&surface->texture_damage); + + glitz_texture_unbind (gl, &surface->texture); + + gl->enable (GLITZ_GL_SCISSOR_TEST); + + glitz_surface_pop_current (surface); + } } static void -_glitz_surface_solid_store (glitz_surface_t *surface) { - glitz_gl_proc_address_list_t *gl = &surface->backend->gl; - - if (SURFACE_DRAWABLE (surface)) { - glitz_bounding_box_t box; +_glitz_surface_sync_drawable (glitz_surface_t *surface) +{ + if (REGION_NOTEMPTY (&surface->drawable_damage)) { + glitz_texture_t *texture; + glitz_box_t *box, *ext; + int n_box; + + GLITZ_GL_SURFACE (surface); - box.x1 = box.y1 = 0; - box.x2 = box.y2 = 1; + texture = glitz_surface_get_texture (surface, 0); + if (!texture) + return; - gl->color_4us (surface->solid.red, - surface->solid.green, - surface->solid.blue, - surface->solid.alpha); + box = REGION_RECTS (&surface->drawable_damage); + ext = REGION_EXTENTS (&surface->drawable_damage); + n_box = REGION_NUM_RECTS (&surface->drawable_damage); + + glitz_texture_bind (gl, texture); + + glitz_texture_set_tex_gen (gl, texture, 0, 0, 0); - glitz_set_operator (gl, GLITZ_OPERATOR_SRC); + gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_REPLACE); + gl->color_4us (0x0, 0x0, 0x0, 0xffff); - glitz_geometry_enable_default (gl, surface, &box); + glitz_texture_ensure_wrap (gl, texture, GLITZ_GL_CLAMP_TO_EDGE); + glitz_texture_ensure_filter (gl, texture, GLITZ_GL_NEAREST); - gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); + glitz_set_operator (gl, GLITZ_OPERATOR_SRC); - glitz_geometry_disable (gl, surface); - } else { - glitz_gl_float_t color[4]; + gl->scissor (surface->x + ext->x1, + surface->attached->height - surface->y - ext->y2, + ext->x2 - ext->x1, + ext->y2 - ext->y1); + + if (n_box > 1) { + glitz_float_t *data; + void *ptr; + int vertices; + + ptr = malloc (n_box * 8 * sizeof (glitz_float_t)); + if (!ptr) { + glitz_surface_status_add (surface, GLITZ_STATUS_NO_MEMORY_MASK); + return; + } - if (TEXTURE_ALLOCATED (&surface->texture)) { - color[0] = surface->solid.red / 65535.0f; - color[1] = surface->solid.green / 65535.0f; - color[2] = surface->solid.blue / 65535.0f; - color[3] = surface->solid.alpha / 65535.0f; - - glitz_texture_bind (gl, &surface->texture); - gl->tex_sub_image_2d (surface->texture.target, 0, - surface->texture.box.x1, surface->texture.box.y1, - 1, 1, GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color); - glitz_texture_unbind (gl, &surface->texture); + data = (glitz_float_t *) ptr; + vertices = n_box << 2; + + while (n_box--) { + *data++ = (glitz_float_t) box->x1; + *data++ = (glitz_float_t) box->y1; + *data++ = (glitz_float_t) box->x2; + *data++ = (glitz_float_t) box->y1; + *data++ = (glitz_float_t) box->x2; + *data++ = (glitz_float_t) box->y2; + *data++ = (glitz_float_t) box->x1; + *data++ = (glitz_float_t) box->y2; + + box++; + } + + gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr); + gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices); + + free (ptr); + } else { + glitz_geometry_enable_default (gl, surface, ext); + gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); } + + glitz_texture_unbind (gl, texture); + + REGION_EMPTY (&surface->drawable_damage); } - surface->flags &= ~GLITZ_SURFACE_FLAG_DRAWABLE_DIRTY_MASK; } void -glitz_surface_ensure_solid (glitz_surface_t *surface) +glitz_surface_sync_solid (glitz_surface_t *surface) { - if (SURFACE_DIRTY (surface) || SURFACE_SOLID_DIRTY (surface)) { - glitz_gl_proc_address_list_t *gl = &surface->backend->gl; + if (SURFACE_SOLID_DAMAGE (surface)) { glitz_gl_float_t *c, color[64]; glitz_texture_t *texture; - texture = glitz_surface_get_texture (surface, 0); + GLITZ_GL_SURFACE (surface); + texture = glitz_surface_get_texture (surface, 0); + c = &color[(texture->box.y1 * texture->width + texture->box.x1) * 4]; if (texture) { glitz_texture_bind (gl, texture); @@ -205,37 +294,257 @@ glitz_surface_ensure_solid (glitz_surface_t *surface) c[0] = c[1] = c[2] = 0.0f; c[3] = 1.0f; } - + surface->solid.red = c[0] * 65535.0f; surface->solid.green = c[1] * 65535.0f; surface->solid.blue = c[2] * 65535.0f; surface->solid.alpha = c[3] * 65535.0f; - surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK; + surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; } } -glitz_bool_t -glitz_surface_push_current (glitz_surface_t *surface, - glitz_constraint_t constraint) +glitz_texture_t * +glitz_surface_get_texture (glitz_surface_t *surface, + glitz_bool_t allocate) +{ + GLITZ_GL_SURFACE (surface); + + if (REGION_NOTEMPTY (&surface->texture_damage)) { + _glitz_surface_sync_texture (surface); + } else if (allocate) { + if (!(TEXTURE_ALLOCATED (&surface->texture))) + glitz_texture_allocate (gl, &surface->texture); + } + + if (TEXTURE_ALLOCATED (&surface->texture)) + return &surface->texture; + + return NULL; +} + +void +glitz_surface_damage (glitz_surface_t *surface, + glitz_box_t *box, + int what) +{ + glitz_box_t b; + + if (box) { + b.x1 = MAX (0, box->x1); + b.y1 = MAX (0, box->y1); + b.x2 = MIN (surface->width, box->x2); + b.y2 = MIN (surface->height, box->y2); + + if (b.x1 >= b.x2 || b.y1 >= b.y2) + return; + + if (what & GLITZ_DAMAGE_DRAWABLE_MASK) + REGION_UNION (&surface->drawable_damage, &b); + + if (what & GLITZ_DAMAGE_TEXTURE_MASK) + REGION_UNION (&surface->texture_damage, &b); + } else { + b.x1 = b.y1 = 0; + b.x2 = surface->width; + b.y2 = surface->height; + + if (what & GLITZ_DAMAGE_DRAWABLE_MASK) { + REGION_EMPTY (&surface->drawable_damage); + REGION_INIT (&surface->drawable_damage, &b); + } + + if (what & GLITZ_DAMAGE_TEXTURE_MASK) { + REGION_EMPTY (&surface->texture_damage); + REGION_INIT (&surface->texture_damage, &b); + } + } + + if (what & GLITZ_DAMAGE_SOLID_MASK) + surface->flags |= GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; +} + +void +glitz_surface_status_add (glitz_surface_t *surface, int flags) +{ + surface->status_mask |= flags; +} + +static void +_glitz_surface_update_state (glitz_surface_t *surface) { - if (!surface->backend->push_current (surface, constraint)) - return 0; + glitz_rectangle_t *viewport; + + GLITZ_GL_SURFACE (surface); + + viewport = &surface->attached->viewport; + + if (surface->attached->update_all || + viewport->x != surface->x || + viewport->y != surface->y || + viewport->width != surface->width || + viewport->height != surface->height) { + gl->viewport (surface->x, + surface->attached->height - surface->y - surface->height, + surface->width, + surface->height); + gl->matrix_mode (GLITZ_GL_PROJECTION); + gl->load_identity (); + gl->ortho (0.0, + surface->width, + surface->attached->height - surface->height, + surface->attached->height, + -1.0, 1.0); + gl->matrix_mode (GLITZ_GL_MODELVIEW); + gl->load_identity (); + gl->scale_f (1.0f, -1.0f, 1.0f); + gl->translate_f (0.0f, -surface->attached->height, 0.0f); + + viewport->x = surface->x; + viewport->y = surface->y; + viewport->width = surface->width; + viewport->height = surface->height; + + surface->attached->update_all = 0; + } + + gl->draw_buffer (surface->buffer); - if (SURFACE_SOLID (surface) && SURFACE_DRAWABLE_DIRTY (surface)) - _glitz_surface_solid_store (surface); + if (SURFACE_DITHER (surface)) + gl->enable (GLITZ_GL_DITHER); + else + gl->disable (GLITZ_GL_DITHER); + if (surface->attached->format->samples > 1) { + if (SURFACE_MULTISAMPLE (surface)) { + gl->enable (GLITZ_GL_MULTISAMPLE); + + if (surface->attached->backend->feature_mask & + GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK) { + if (SURFACE_NICEST_MULTISAMPLE (surface)) + gl->hint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_NICEST); + else + gl->hint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_FASTEST); + } + } else + gl->disable (GLITZ_GL_MULTISAMPLE); + } +} + +void +glitz_surface_attach (glitz_surface_t *surface, + glitz_drawable_t *drawable, + glitz_drawable_buffer_t buffer, + int x, + int y) +{ + glitz_drawable_reference (drawable); + + if (surface->attached) + glitz_drawable_destroy (surface->attached); + + surface->attached = drawable; + surface->x = x; + surface->y = y; + + switch (buffer) { + case GLITZ_DRAWABLE_BUFFER_FRONT_COLOR: + surface->buffer = GLITZ_GL_FRONT; + break; + case GLITZ_DRAWABLE_BUFFER_BACK_COLOR: + surface->buffer = GLITZ_GL_BACK; + break; + } + + if ((!SURFACE_SOLID (surface)) || SURFACE_SOLID_DAMAGE (surface)) + REGION_EMPTY (&surface->texture_damage); +} + +void +glitz_surface_detach (glitz_surface_t *surface) +{ + glitz_box_t box; + + if (!surface->attached) + return; + + if (REGION_NOTEMPTY (&surface->texture_damage)) { + glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); + _glitz_surface_sync_texture (surface); + glitz_surface_pop_current (surface); + } + + glitz_drawable_destroy (surface->attached); + surface->attached = NULL; + + box.x1 = box.y1 = 0; + box.x2 = surface->width; + box.y2 = surface->height; + + REGION_EMPTY (&surface->drawable_damage); + REGION_INIT (&surface->drawable_damage, &box); +} + +glitz_drawable_t * +glitz_surface_get_drawable (glitz_surface_t *surface) +{ + return surface->drawable; +} +slim_hidden_def(glitz_surface_get_drawable); + +glitz_drawable_t * +glitz_surface_get_attached_drawable (glitz_surface_t *surface) +{ + return surface->attached; +} +slim_hidden_def(glitz_surface_get_attached_drawable); + +glitz_bool_t +glitz_surface_push_current (glitz_surface_t *surface, + glitz_constraint_t constraint) +{ + if (surface->attached) { + surface->attached->backend->push_current (surface->attached, surface, + constraint); + if (constraint == GLITZ_DRAWABLE_CURRENT) { + _glitz_surface_update_state (surface); + _glitz_surface_sync_drawable (surface); + } + } else { + surface->drawable->backend->push_current (surface->drawable, NULL, + constraint); + if (constraint == GLITZ_DRAWABLE_CURRENT) + return 0; + } + return 1; } void glitz_surface_pop_current (glitz_surface_t *surface) { - surface->backend->pop_current (surface); + glitz_surface_t *other; + + if (surface->attached) + other = surface->attached->backend->pop_current (surface->attached); + else + other = surface->drawable->backend->pop_current (surface->drawable); + + if (other) + _glitz_surface_update_state (other); +} + +glitz_status_t +glitz_surface_make_current_read (glitz_surface_t *surface) +{ + if (surface->attached) + return surface->attached->backend->make_current_read (surface->attached); + else + return surface->drawable->backend->make_current_read (surface->drawable); } void -glitz_surface_set_transform (glitz_surface_t *surface, +glitz_surface_set_transform (glitz_surface_t *surface, glitz_transform_t *transform) { static glitz_transform_t identity = { @@ -357,7 +666,7 @@ slim_hidden_def(glitz_surface_set_transform); void glitz_surface_set_fill (glitz_surface_t *surface, - glitz_fill_t fill) + glitz_fill_t fill) { switch (fill) { case GLITZ_FILL_TRANSPARENT: @@ -388,9 +697,9 @@ slim_hidden_def(glitz_surface_set_fill); void glitz_surface_set_component_alpha (glitz_surface_t *surface, - glitz_bool_t component_alpha) + glitz_bool_t component_alpha) { - if (component_alpha && surface->format->red_size) + if (component_alpha && surface->format->color.red_size) surface->flags |= GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK; else surface->flags &= ~GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK; @@ -398,10 +707,10 @@ glitz_surface_set_component_alpha (glitz_surface_t *surface, slim_hidden_def(glitz_surface_set_component_alpha); void -glitz_surface_set_filter (glitz_surface_t *surface, - glitz_filter_t filter, +glitz_surface_set_filter (glitz_surface_t *surface, + glitz_filter_t filter, glitz_fixed16_16_t *params, - int n_params) + int n_params) { glitz_status_t status; @@ -442,143 +751,40 @@ glitz_surface_set_filter (glitz_surface_t *surface, } slim_hidden_def(glitz_surface_set_filter); -int -glitz_surface_get_width (glitz_surface_t *surface) -{ - return surface->width; -} -slim_hidden_def(glitz_surface_get_width); - -int -glitz_surface_get_height (glitz_surface_t *surface) -{ - return surface->height; -} -slim_hidden_def(glitz_surface_get_height); - -glitz_texture_t * -glitz_surface_get_texture (glitz_surface_t *surface, - glitz_bool_t allocate) -{ - glitz_texture_t *texture; - - if (SURFACE_SOLID (surface) && SURFACE_DRAWABLE_DIRTY (surface)) { - texture = surface->backend->get_texture (surface, 1); - _glitz_surface_solid_store (surface); - } else - texture = surface->backend->get_texture (surface, allocate); - - return texture; -} - -static glitz_gl_enum_t -_gl_color_buffer (glitz_color_buffer_t buffer) -{ - switch (buffer) { - case GLITZ_COLOR_BUFFER_FRONT: - return GLITZ_GL_FRONT; - case GLITZ_COLOR_BUFFER_BACK: - return GLITZ_GL_BACK; - default: - return GLITZ_GL_BACK; - } -} - -void -glitz_surface_set_read_color_buffer (glitz_surface_t *surface, - glitz_color_buffer_t buffer) -{ - glitz_gl_enum_t mode; - - if (!surface->format->doublebuffer) - return; - - mode = _gl_color_buffer (buffer); - if (mode != surface->read_buffer) { - surface->read_buffer = mode; - glitz_surface_dirty (surface, NULL); - } -} -slim_hidden_def(glitz_surface_set_read_color_buffer); - void -glitz_surface_set_draw_color_buffer (glitz_surface_t *surface, - glitz_color_buffer_t buffer) +glitz_surface_set_dither (glitz_surface_t *surface, + glitz_bool_t dither) { - if (!surface->format->doublebuffer) - return; - - surface->draw_buffer = _gl_color_buffer (buffer); - - surface->update_mask |= GLITZ_UPDATE_DRAW_BUFFER_MASK; -} -slim_hidden_def(glitz_surface_set_draw_color_buffer); - -void -glitz_surface_swap_buffers (glitz_surface_t *surface) -{ - if (!surface->format->doublebuffer) - return; - - surface->backend->swap_buffers (surface); + if (dither) + surface->flags |= GLITZ_SURFACE_FLAG_DITHER_MASK; + else + surface->flags &= ~GLITZ_SURFACE_FLAG_DITHER_MASK; } -slim_hidden_def(glitz_surface_swap_buffers); +slim_hidden_def(glitz_surface_set_dither); void glitz_surface_flush (glitz_surface_t *surface) { - if (glitz_surface_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) - surface->backend->gl.flush (); - - glitz_surface_pop_current (surface); + if (surface->attached && REGION_NOTEMPTY (&surface->drawable_damage)) { + glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT); + glitz_surface_pop_current (surface); + } } slim_hidden_def(glitz_surface_flush); -void -glitz_surface_finish (glitz_surface_t *surface) -{ - if (glitz_surface_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) - surface->backend->gl.finish (); - - glitz_surface_pop_current (surface); -} -slim_hidden_def(glitz_surface_finish); - -glitz_bool_t -glitz_surface_make_current_read (glitz_surface_t *surface) +unsigned int +glitz_surface_get_width (glitz_surface_t *surface) { - return surface->backend->make_current_read (surface); -} - -void -glitz_surface_dirty (glitz_surface_t *surface, - glitz_bounding_box_t *box) -{ - if (surface->draw_buffer != surface->read_buffer) - return; - - if (!box) { - surface->dirty_box.x1 = surface->dirty_box.y1 = 0; - surface->dirty_box.x2 = surface->width; - surface->dirty_box.y2 = surface->height; - } else { - if (!SURFACE_DIRTY (surface)) { - surface->dirty_box = *box; - } else - glitz_union_bounding_box (box, - &surface->dirty_box, - &surface->dirty_box); - } - - surface->flags |= - (GLITZ_SURFACE_FLAG_DIRTY_MASK | GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK); + return (unsigned int) surface->width; } +slim_hidden_def(glitz_surface_get_width); -void -glitz_surface_status_add (glitz_surface_t *surface, int flags) +unsigned int +glitz_surface_get_height (glitz_surface_t *surface) { - surface->status_mask |= flags; + return (unsigned int) surface->height; } +slim_hidden_def(glitz_surface_get_height); glitz_status_t glitz_surface_get_status (glitz_surface_t *surface) @@ -587,72 +793,6 @@ glitz_surface_get_status (glitz_surface_t *surface) } slim_hidden_def(glitz_surface_get_status); -void -glitz_surface_update_state (glitz_surface_t *surface) -{ - glitz_gl_proc_address_list_t *gl = &surface->backend->gl; - - if (surface->update_mask & GLITZ_UPDATE_VIEWPORT_MASK) { - gl->viewport (0, 0, surface->width, surface->height); - gl->matrix_mode (GLITZ_GL_PROJECTION); - gl->load_identity (); - gl->ortho (0.0, surface->width, 0.0, surface->height, -1.0, 1.0); - gl->matrix_mode (GLITZ_GL_MODELVIEW); - gl->load_identity (); - gl->scale_f (1.0f, -1.0f, 1.0f); - gl->translate_f (0.0f, -surface->height, 0.0f); - gl->disable (GLITZ_GL_DEPTH_TEST); - gl->hint (GLITZ_GL_PERSPECTIVE_CORRECTION_HINT, GLITZ_GL_FASTEST); - gl->disable (GLITZ_GL_CULL_FACE); - gl->depth_mask (GLITZ_GL_FALSE); - gl->polygon_mode (GLITZ_GL_FRONT_AND_BACK, GLITZ_GL_FILL); - gl->disable (GLITZ_GL_POLYGON_SMOOTH); - gl->shade_model (GLITZ_GL_FLAT); - gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE, - GLITZ_GL_TRUE); - gl->disable (GLITZ_GL_DITHER); - gl->enable (GLITZ_GL_SCISSOR_TEST); - gl->scissor (0, 0, surface->width, surface->height); - gl->disable (GLITZ_GL_STENCIL_TEST); - gl->enable_client_state (GLITZ_GL_VERTEX_ARRAY); - - surface->update_mask &= ~GLITZ_UPDATE_VIEWPORT_MASK; - } - - if (surface->update_mask & GLITZ_UPDATE_DRAW_BUFFER_MASK) { - if (surface->format->doublebuffer) - gl->draw_buffer (surface->draw_buffer); - - surface->update_mask &= ~GLITZ_UPDATE_DRAW_BUFFER_MASK; - } - - if (surface->update_mask & GLITZ_UPDATE_MULTISAMPLE_MASK) { - if (surface->format->multisample.samples) { - if (SURFACE_MULTISAMPLE (surface)) { - gl->enable (GLITZ_GL_MULTISAMPLE); - - if (surface->backend->feature_mask & - GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK) { - if (SURFACE_NICEST_MULTISAMPLE (surface)) - gl->hint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_NICEST); - else - gl->hint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_FASTEST); - } - } else - gl->disable (GLITZ_GL_MULTISAMPLE); - } - - surface->update_mask &= ~GLITZ_UPDATE_MULTISAMPLE_MASK; - } -} - -unsigned long -glitz_surface_get_features (glitz_surface_t *surface) -{ - return surface->backend->feature_mask; -} -slim_hidden_def(glitz_surface_get_features); - glitz_format_t * glitz_surface_get_format (glitz_surface_t *surface) { diff --git a/src/glitz_texture.c b/src/glitz_texture.c index 321be90..f4f25b2 100644 --- a/src/glitz_texture.c +++ b/src/glitz_texture.c @@ -1,28 +1,26 @@ /* - * Copyright © 2004 David Reveman, Peter Nilsson - * + * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. + * 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 AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. + * 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. * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> + * Author: David Reveman <c99drn@cs.umu.se> */ #ifdef HAVE_CONFIG_H @@ -33,10 +31,10 @@ void glitz_texture_init (glitz_texture_t *texture, - unsigned int width, - unsigned int height, - unsigned int texture_format, - unsigned long feature_mask) + int width, + int height, + glitz_gl_int_t texture_format, + unsigned long feature_mask) { texture->filter = 0; texture->wrap = 0; @@ -89,9 +87,9 @@ glitz_texture_init (glitz_texture_t *texture, void glitz_texture_size_check (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_int_t max_2d, - glitz_gl_int_t max_rect) { + glitz_texture_t *texture, + glitz_gl_int_t max_2d, + glitz_gl_int_t max_rect) { glitz_gl_enum_t proxy_target; glitz_gl_int_t value, max; @@ -126,7 +124,7 @@ glitz_texture_size_check (glitz_gl_proc_address_list_t *gl, void glitz_texture_allocate (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture) + glitz_texture_t *texture) { char *data = NULL; @@ -162,7 +160,7 @@ glitz_texture_allocate (glitz_gl_proc_address_list_t *gl, void glitz_texture_fini (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture) + glitz_texture_t *texture) { if (texture->name) gl->delete_textures (1, &texture->name); @@ -170,8 +168,8 @@ glitz_texture_fini (glitz_gl_proc_address_list_t *gl, void glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_enum_t filter) + glitz_texture_t *texture, + glitz_gl_enum_t filter) { if (!texture->name) return; @@ -185,8 +183,8 @@ glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl, void glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_enum_t wrap) + glitz_texture_t *texture, + glitz_gl_enum_t wrap) { if (!texture->name) return; @@ -200,7 +198,7 @@ glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl, void glitz_texture_bind (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture) + glitz_texture_t *texture) { gl->disable (GLITZ_GL_TEXTURE_RECTANGLE); gl->disable (GLITZ_GL_TEXTURE_2D); @@ -214,48 +212,37 @@ glitz_texture_bind (glitz_gl_proc_address_list_t *gl, void glitz_texture_unbind (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture) + glitz_texture_t *texture) { gl->bind_texture (texture->target, 0); gl->disable (texture->target); } void -glitz_texture_copy_surface (glitz_texture_t *texture, - glitz_surface_t *surface, - int x_surface, - int y_surface, - int width, - int height, - int x_texture, - int y_texture) +glitz_texture_copy_drawable (glitz_gl_proc_address_list_t *gl, + glitz_texture_t *texture, + glitz_drawable_t *drawable, + int x_drawable, + int y_drawable, + int width, + int height, + int x_texture, + int y_texture) { - glitz_gl_proc_address_list_t *gl = &surface->backend->gl; - - glitz_surface_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT); - - glitz_texture_bind (gl, texture); - - if (surface->format->doublebuffer) - gl->read_buffer (surface->read_buffer); - gl->copy_tex_sub_image_2d (texture->target, 0, texture->box.x1 + x_texture, texture->box.y2 - y_texture - height, - x_surface, - surface->height - y_surface - height, + x_drawable, + drawable->height - y_drawable - height, width, height); - - glitz_texture_unbind (gl, texture); - glitz_surface_pop_current (surface); } void glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - int x_src, - int y_src, - unsigned long flags) + glitz_texture_t *texture, + int x_src, + int y_src, + unsigned long flags) { glitz_vec4_t plane; diff --git a/src/glitz_util.c b/src/glitz_util.c index 5cbee66..853eb7c 100644 --- a/src/glitz_util.c +++ b/src/glitz_util.c @@ -1,28 +1,26 @@ /* - * Copyright © 2004 David Reveman, Peter Nilsson - * + * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. + * 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 AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. + * 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. * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> + * Author: David Reveman <c99drn@cs.umu.se> */ #ifdef HAVE_CONFIG_H @@ -34,33 +32,35 @@ #include <stdlib.h> #include <string.h> -void -glitz_intersect_bounding_box (glitz_bounding_box_t *box1, - glitz_bounding_box_t *box2, - glitz_bounding_box_t *return_box) -{ - return_box->x1 = (box1->x1 >= box2->x1)? box1->x1: box2->x1; - return_box->x2 = (box1->x2 <= box2->x2)? box1->x2: box2->x2; - return_box->y1 = (box1->y1 >= box2->y1)? box1->y1: box2->y1; - return_box->y2 = (box1->y2 <= box2->y2)? box1->y2: box2->y2; - - if (return_box->x1 >= return_box->x2) - return_box->x1 = return_box->x2 = 0; - - if (return_box->y1 >= return_box->y2) - return_box->y1 = return_box->y2 = 0; -} - -void -glitz_union_bounding_box (glitz_bounding_box_t *box1, - glitz_bounding_box_t *box2, - glitz_bounding_box_t *return_box) -{ - return_box->x1 = (box1->x1 <= box2->x1)? box1->x1: box2->x1; - return_box->x2 = (box1->x2 >= box2->x2)? box1->x2: box2->x2; - return_box->y1 = (box1->y1 <= box2->y1)? box1->y1: box2->y1; - return_box->y2 = (box1->y2 >= box2->y2)? box1->y2: box2->y2; -} +static glitz_extension_map gl_extensions[] = { + { 0.0, "GL_ARB_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_EXT_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_NV_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK }, + { 0.0, "GL_ARB_texture_non_power_of_two", + GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK }, + { 0.0, "GL_ARB_texture_mirrored_repeat", + GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK }, + { 0.0, "GL_ARB_texture_border_clamp", + GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK }, + { 0.0, "GL_ARB_texture_env_combine", + GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK }, + { 0.0, "GL_EXT_texture_env_combine", + GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK }, + { 0.0, "GL_ARB_texture_env_dot3", GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK }, + { 0.0, "GL_ARB_multisample", GLITZ_FEATURE_MULTISAMPLE_MASK }, + { 0.0, "GL_NV_multisample_filter_hint", + GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK }, + { 0.0, "GL_ARB_multitexture", GLITZ_FEATURE_MULTITEXTURE_MASK }, + { 0.0, "GL_ARB_fragment_program", GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK }, + { 0.0, "GL_ARB_vertex_buffer_object", + GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK }, + { 0.0, "GL_EXT_pixel_buffer_object", + GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK }, + { 0.0, "GL_EXT_blend_color", GLITZ_FEATURE_BLEND_COLOR_MASK }, + { 0.0, "GL_ARB_imaging", GLITZ_FEATURE_BLEND_COLOR_MASK }, + { 0.0, "GL_APPLE_packed_pixels", GLITZ_FEATURE_PACKED_PIXELS_MASK }, + { 0.0, NULL, 0 } +}; static glitz_bool_t _glitz_extension_check (const char *extensions, @@ -87,8 +87,8 @@ _glitz_extension_check (const char *extensions, } unsigned long -glitz_extensions_query (glitz_gl_float_t version, - const char *extensions_string, +glitz_extensions_query (glitz_gl_float_t version, + const char *extensions_string, glitz_extension_map *extensions_map) { unsigned long mask = 0; @@ -103,6 +103,167 @@ glitz_extensions_query (glitz_gl_float_t version, return mask; } +static glitz_status_t +_glitz_query_gl_extensions (glitz_gl_proc_address_list_t *gl, + glitz_gl_float_t *gl_version, + unsigned long *feature_mask) +{ + const char *gl_extensions_string; + + *gl_version = atof ((const char *) gl->get_string (GLITZ_GL_VERSION)); + if (*gl_version < 1.2f) + return GLITZ_STATUS_NOT_SUPPORTED; + + gl_extensions_string = (const char *) gl->get_string (GLITZ_GL_EXTENSIONS); + + *feature_mask = glitz_extensions_query (*gl_version, + gl_extensions_string, + gl_extensions); + + if ((*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) && + (*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK)) { + glitz_gl_int_t max_texture_units; + + gl->get_integer_v (GLITZ_GL_MAX_TEXTURE_UNITS, &max_texture_units); + if (max_texture_units >= 3) + *feature_mask |= GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; + } + + return GLITZ_STATUS_SUCCESS; +} + +static void +_glitz_gl_proc_address_lookup (glitz_backend_t *backend, + glitz_get_proc_address_proc_t get_proc_address, + void *closure) +{ + if (backend->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) { + if (backend->gl_version >= 1.4f) { + backend->gl.blend_color = (glitz_gl_blend_color_t) + get_proc_address ("glBlendColor", closure); + } else { + backend->gl.blend_color = (glitz_gl_blend_color_t) + get_proc_address ("glBlendColorEXT", closure); + } + + if (!backend->gl.blend_color) + backend->feature_mask &= ~GLITZ_FEATURE_BLEND_COLOR_MASK; + } + + if (backend->feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK) { + if (backend->gl_version >= 1.3f) { + backend->gl.active_texture = (glitz_gl_active_texture_t) + get_proc_address ("glActiveTexture", closure); + } else { + backend->gl.active_texture = (glitz_gl_active_texture_t) + get_proc_address ("glActiveTextureARB", closure); + } + + if (!backend->gl.active_texture) { + backend->feature_mask &= ~GLITZ_FEATURE_MULTITEXTURE_MASK; + backend->feature_mask &= ~GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; + } + } + + if (backend->feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) { + backend->gl.gen_programs = (glitz_gl_gen_programs_t) + get_proc_address ("glGenProgramsARB", closure); + backend->gl.delete_programs = (glitz_gl_delete_programs_t) + get_proc_address ("glDeleteProgramsARB", closure); + backend->gl.program_string = (glitz_gl_program_string_t) + get_proc_address ("glProgramStringARB", closure); + backend->gl.bind_program = (glitz_gl_bind_program_t) + get_proc_address ("glBindProgramARB", closure); + backend->gl.program_local_param_4fv = (glitz_gl_program_local_param_4fv_t) + get_proc_address ("glProgramLocalParameter4fvARB", closure); + backend->gl.get_program_iv = (glitz_gl_get_program_iv_t) + get_proc_address ("glGetProgramivARB", closure); + + if ((!backend->gl.gen_programs) || + (!backend->gl.delete_programs) || + (!backend->gl.program_string) || + (!backend->gl.bind_program) || + (!backend->gl.program_local_param_4fv)) + backend->feature_mask &= ~GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK; + } + + if ((backend->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) || + (backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)) { + if (backend->gl_version >= 1.5f) { + backend->gl.gen_buffers = (glitz_gl_gen_buffers_t) + get_proc_address ("glGenBuffers", closure); + backend->gl.delete_buffers = (glitz_gl_delete_buffers_t) + get_proc_address ("glDeleteBuffers", closure); + backend->gl.bind_buffer = (glitz_gl_bind_buffer_t) + get_proc_address ("glBindBuffer", closure); + backend->gl.buffer_data = (glitz_gl_buffer_data_t) + get_proc_address ("glBufferData", closure); + backend->gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t) + get_proc_address ("glBufferSubData", closure); + backend->gl.get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t) + get_proc_address ("glGetBufferSubData", closure); + backend->gl.map_buffer = (glitz_gl_map_buffer_t) + get_proc_address ("glMapBuffer", closure); + backend->gl.unmap_buffer = (glitz_gl_unmap_buffer_t) + get_proc_address ("glUnmapBuffer", closure); + } else { + backend->gl.gen_buffers = (glitz_gl_gen_buffers_t) + get_proc_address ("glGenBuffersARB", closure); + backend->gl.delete_buffers = (glitz_gl_delete_buffers_t) + get_proc_address ("glDeleteBuffersARB", closure); + backend->gl.bind_buffer = (glitz_gl_bind_buffer_t) + get_proc_address ("glBindBufferARB", closure); + backend->gl.buffer_data = (glitz_gl_buffer_data_t) + get_proc_address ("glBufferDataARB", closure); + backend->gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t) + get_proc_address ("glBufferSubDataARB", closure); + backend->gl.get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t) + get_proc_address ("glGetBufferSubDataARB", closure); + backend->gl.map_buffer = (glitz_gl_map_buffer_t) + get_proc_address ("glMapBufferARB", closure); + backend->gl.unmap_buffer = (glitz_gl_unmap_buffer_t) + get_proc_address ("glUnmapBufferARB", closure); + } + + if ((!backend->gl.gen_buffers) || + (!backend->gl.delete_buffers) || + (!backend->gl.bind_buffer) || + (!backend->gl.buffer_data) || + (!backend->gl.buffer_sub_data) || + (!backend->gl.get_buffer_sub_data) || + (!backend->gl.map_buffer) || + (!backend->gl.unmap_buffer)) { + backend->feature_mask &= ~GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK; + backend->feature_mask &= ~GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK; + } + } +} + +void +glitz_backend_init (glitz_backend_t *backend, + glitz_get_proc_address_proc_t get_proc_address, + void *closure) +{ + if (!_glitz_query_gl_extensions (&backend->gl, + &backend->gl_version, + &backend->feature_mask)) { + _glitz_gl_proc_address_lookup (backend, get_proc_address, closure); + glitz_create_surface_formats (&backend->gl, + &backend->formats, + &backend->texture_formats, + &backend->n_formats); + } + + backend->gl.get_integer_v (GLITZ_GL_MAX_TEXTURE_SIZE, + &backend->max_texture_2d_size); + + if (backend->feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) + backend->gl.get_integer_v (GLITZ_GL_MAX_RECTANGLE_TEXTURE_SIZE, + &backend->max_texture_rect_size); + else + backend->max_texture_rect_size = 0; +} + unsigned int glitz_uint_to_power_of_two (unsigned int x) { @@ -117,8 +278,8 @@ glitz_uint_to_power_of_two (unsigned int x) void glitz_set_raster_pos (glitz_gl_proc_address_list_t *gl, - int x, - int y) + int x, + int y) { gl->push_attrib (GLITZ_GL_TRANSFORM_BIT | GLITZ_GL_VIEWPORT_BIT); gl->matrix_mode (GLITZ_GL_PROJECTION); @@ -148,3 +309,22 @@ glitz_clamp_value (glitz_float_t *value, else if (*value > max) *value = max; } + +void +glitz_initiate_state (glitz_gl_proc_address_list_t *gl) +{ + gl->disable (GLITZ_GL_DEPTH_TEST); + gl->hint (GLITZ_GL_PERSPECTIVE_CORRECTION_HINT, GLITZ_GL_FASTEST); + gl->disable (GLITZ_GL_CULL_FACE); + gl->depth_mask (GLITZ_GL_FALSE); + gl->polygon_mode (GLITZ_GL_FRONT_AND_BACK, GLITZ_GL_FILL); + gl->disable (GLITZ_GL_POLYGON_SMOOTH); + gl->disable (GLITZ_GL_LINE_SMOOTH); + gl->disable (GLITZ_GL_POINT_SMOOTH); + gl->shade_model (GLITZ_GL_FLAT); + gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE); + gl->enable (GLITZ_GL_SCISSOR_TEST); + gl->disable (GLITZ_GL_STENCIL_TEST); + gl->enable_client_state (GLITZ_GL_VERTEX_ARRAY); + gl->disable (GLITZ_GL_DEPTH_TEST); +} diff --git a/src/glitzint.h b/src/glitzint.h index 6c177e5..af47e2c 100644 --- a/src/glitzint.h +++ b/src/glitzint.h @@ -67,88 +67,95 @@ #define GLITZ_STATUS_NOT_SUPPORTED_MASK (1L << 2) #define GLITZ_STATUS_CONTENT_DESTROYED_MASK (1L << 3) -#define GLITZ_FORMAT_ALL_EXCEPT_ID_MASK ((1L << 19) - 2) +#define GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK ((1L << 11) - 2) #include "glitz_gl.h" +#define GLITZ_DEFAULT_PBUFFER_WIDTH 512 +#define GLITZ_DEFAULT_PBUFFER_HEIGHT 512 + #define GLITZ_CONTEXT_STACK_SIZE 16 +typedef void (*glitz_function_pointer_t) (void); + typedef struct _glitz_gl_proc_address_list_t { - glitz_gl_enable_t enable; - glitz_gl_disable_t disable; - glitz_gl_get_error_t get_error; - glitz_gl_enable_client_state_t enable_client_state; - glitz_gl_disable_client_state_t disable_client_state; - glitz_gl_vertex_pointer_t vertex_pointer; - glitz_gl_draw_arrays_t draw_arrays; - glitz_gl_tex_env_f_t tex_env_f; - glitz_gl_tex_env_fv_t tex_env_fv; - glitz_gl_tex_gen_i_t tex_gen_i; - glitz_gl_tex_gen_fv_t tex_gen_fv; - glitz_gl_color_4us_t color_4us; - glitz_gl_color_4f_t color_4f; - glitz_gl_scissor_t scissor; - glitz_gl_blend_func_t blend_func; - glitz_gl_clear_t clear; - glitz_gl_clear_color_t clear_color; - glitz_gl_clear_stencil_t clear_stencil; - glitz_gl_stencil_func_t stencil_func; - glitz_gl_stencil_op_t stencil_op; - glitz_gl_push_attrib_t push_attrib; - glitz_gl_pop_attrib_t pop_attrib; - glitz_gl_matrix_mode_t matrix_mode; - glitz_gl_push_matrix_t push_matrix; - glitz_gl_pop_matrix_t pop_matrix; - glitz_gl_load_identity_t load_identity; - glitz_gl_load_matrix_f_t load_matrix_f; - glitz_gl_depth_range_t depth_range; - glitz_gl_viewport_t viewport; - glitz_gl_raster_pos_2f_t raster_pos_2f; - glitz_gl_bitmap_t bitmap; - glitz_gl_read_buffer_t read_buffer; - glitz_gl_draw_buffer_t draw_buffer; - glitz_gl_copy_pixels_t copy_pixels; - glitz_gl_flush_t flush; - glitz_gl_finish_t finish; - glitz_gl_pixel_store_i_t pixel_store_i; - glitz_gl_ortho_t ortho; - glitz_gl_scale_f_t scale_f; - glitz_gl_translate_f_t translate_f; - glitz_gl_hint_t hint; - glitz_gl_depth_mask_t depth_mask; - glitz_gl_polygon_mode_t polygon_mode; - glitz_gl_shade_model_t shade_model; - glitz_gl_color_mask_t color_mask; - glitz_gl_read_pixels_t read_pixels; - glitz_gl_get_tex_image_t get_tex_image; - glitz_gl_tex_sub_image_2d_t tex_sub_image_2d; - glitz_gl_gen_textures_t gen_textures; - glitz_gl_delete_textures_t delete_textures; - glitz_gl_bind_texture_t bind_texture; - glitz_gl_tex_image_2d_t tex_image_2d; - glitz_gl_tex_parameter_i_t tex_parameter_i; - glitz_gl_get_tex_level_parameter_iv_t get_tex_level_parameter_iv; - glitz_gl_copy_tex_sub_image_2d_t copy_tex_sub_image_2d; - glitz_gl_get_integer_v_t get_integer_v; - - glitz_gl_blend_color_t blend_color; - glitz_gl_active_texture_t active_texture; - glitz_gl_gen_programs_t gen_programs; - glitz_gl_delete_programs_t delete_programs; - glitz_gl_program_string_t program_string; - glitz_gl_bind_program_t bind_program; - glitz_gl_program_local_param_4fv_t program_local_param_4fv; - glitz_gl_get_program_iv_t get_program_iv; - glitz_gl_gen_buffers_t gen_buffers; - glitz_gl_delete_buffers_t delete_buffers; - glitz_gl_bind_buffer_t bind_buffer; - glitz_gl_buffer_data_t buffer_data; - glitz_gl_buffer_sub_data_t buffer_sub_data; - glitz_gl_get_buffer_sub_data_t get_buffer_sub_data; - glitz_gl_map_buffer_t map_buffer; - glitz_gl_unmap_buffer_t unmap_buffer; - glitz_bool_t need_lookup; + /* core */ + glitz_gl_enable_t enable; + glitz_gl_disable_t disable; + glitz_gl_get_error_t get_error; + glitz_gl_get_string_t get_string; + glitz_gl_enable_client_state_t enable_client_state; + glitz_gl_disable_client_state_t disable_client_state; + glitz_gl_vertex_pointer_t vertex_pointer; + glitz_gl_draw_arrays_t draw_arrays; + glitz_gl_tex_env_f_t tex_env_f; + glitz_gl_tex_env_fv_t tex_env_fv; + glitz_gl_tex_gen_i_t tex_gen_i; + glitz_gl_tex_gen_fv_t tex_gen_fv; + glitz_gl_color_4us_t color_4us; + glitz_gl_color_4f_t color_4f; + glitz_gl_scissor_t scissor; + glitz_gl_blend_func_t blend_func; + glitz_gl_clear_t clear; + glitz_gl_clear_color_t clear_color; + glitz_gl_clear_stencil_t clear_stencil; + glitz_gl_stencil_func_t stencil_func; + glitz_gl_stencil_op_t stencil_op; + glitz_gl_push_attrib_t push_attrib; + glitz_gl_pop_attrib_t pop_attrib; + glitz_gl_matrix_mode_t matrix_mode; + glitz_gl_push_matrix_t push_matrix; + glitz_gl_pop_matrix_t pop_matrix; + glitz_gl_load_identity_t load_identity; + glitz_gl_load_matrix_f_t load_matrix_f; + glitz_gl_depth_range_t depth_range; + glitz_gl_viewport_t viewport; + glitz_gl_raster_pos_2f_t raster_pos_2f; + glitz_gl_bitmap_t bitmap; + glitz_gl_read_buffer_t read_buffer; + glitz_gl_draw_buffer_t draw_buffer; + glitz_gl_copy_pixels_t copy_pixels; + glitz_gl_flush_t flush; + glitz_gl_finish_t finish; + glitz_gl_pixel_store_i_t pixel_store_i; + glitz_gl_ortho_t ortho; + glitz_gl_scale_f_t scale_f; + glitz_gl_translate_f_t translate_f; + glitz_gl_hint_t hint; + glitz_gl_depth_mask_t depth_mask; + glitz_gl_polygon_mode_t polygon_mode; + glitz_gl_shade_model_t shade_model; + glitz_gl_color_mask_t color_mask; + glitz_gl_read_pixels_t read_pixels; + glitz_gl_get_tex_image_t get_tex_image; + glitz_gl_tex_sub_image_2d_t tex_sub_image_2d; + glitz_gl_gen_textures_t gen_textures; + glitz_gl_delete_textures_t delete_textures; + glitz_gl_bind_texture_t bind_texture; + glitz_gl_tex_image_2d_t tex_image_2d; + glitz_gl_tex_parameter_i_t tex_parameter_i; + glitz_gl_get_tex_level_parameter_iv_t get_tex_level_parameter_iv; + glitz_gl_copy_tex_sub_image_2d_t copy_tex_sub_image_2d; + glitz_gl_get_integer_v_t get_integer_v; + + /* extensions */ + glitz_gl_blend_color_t blend_color; + glitz_gl_active_texture_t active_texture; + glitz_gl_gen_programs_t gen_programs; + glitz_gl_delete_programs_t delete_programs; + glitz_gl_program_string_t program_string; + glitz_gl_bind_program_t bind_program; + glitz_gl_program_local_param_4fv_t program_local_param_4fv; + glitz_gl_get_program_iv_t get_program_iv; + glitz_gl_gen_buffers_t gen_buffers; + glitz_gl_delete_buffers_t delete_buffers; + glitz_gl_bind_buffer_t bind_buffer; + glitz_gl_buffer_data_t buffer_data; + glitz_gl_buffer_sub_data_t buffer_sub_data; + glitz_gl_get_buffer_sub_data_t get_buffer_sub_data; + glitz_gl_map_buffer_t map_buffer; + glitz_gl_unmap_buffer_t unmap_buffer; } glitz_gl_proc_address_list_t; typedef int glitz_surface_type_t; @@ -164,8 +171,7 @@ typedef int glitz_surface_type_t; typedef int glitz_combine_type_t; -#define GLITZ_COMBINE_TYPE_NA -1 -#define GLITZ_COMBINE_TYPE_INTERMEDIATE 0 +#define GLITZ_COMBINE_TYPE_NA 0 #define GLITZ_COMBINE_TYPE_ARGB 1 #define GLITZ_COMBINE_TYPE_ARGB_ARGB 2 #define GLITZ_COMBINE_TYPE_ARGB_ARGBC 3 @@ -201,7 +207,7 @@ typedef int glitz_combine_type_t; typedef struct _glitz_program_t { glitz_gl_int_t *name; - unsigned int size; + unsigned int size; } glitz_program_t; typedef struct _glitz_filter_map_t { @@ -213,15 +219,133 @@ typedef struct _glitz_program_map_t { } glitz_program_map_t; typedef enum { - GLITZ_CN_NONE, - GLITZ_CN_ANY_CONTEXT_CURRENT, - GLITZ_CN_SURFACE_CONTEXT_CURRENT, - GLITZ_CN_SURFACE_DRAWABLE_CURRENT + GLITZ_NONE, + GLITZ_ANY_CONTEXT_CURRENT, + GLITZ_CONTEXT_CURRENT, + GLITZ_DRAWABLE_CURRENT } glitz_constraint_t; -typedef struct _glitz_bounding_box_t { - int x1, x2, y1, y2; -} glitz_bounding_box_t; +typedef struct _glitz_box_t { + short x1, y1, x2, y2; +} glitz_box_t; + +typedef struct _glitz_region_t { + glitz_box_t extents; + glitz_box_t *box; + int n_box; + void *data; + int size; +} glitz_region_t; + +#define NULL_BOX ((glitz_box_t *) 0) + +#define REGION_INIT(region, __box) \ + { \ + if (__box) { \ + (region)->extents = *(__box); \ + (region)->box = &(region)->extents; \ + (region)->n_box = 1; \ + } else { \ + (region)->extents.x1 = 0; \ + (region)->extents.y1 = 0; \ + (region)->extents.x2 = 0; \ + (region)->extents.y2 = 0; \ + (region)->box = NULL; \ + (region)->n_box = 0; \ + } \ + } + +#define REGION_EMPTY(region) \ + { \ + (region)->extents.x1 = 0; \ + (region)->extents.y1 = 0; \ + (region)->extents.x2 = 0; \ + (region)->extents.y2 = 0; \ + (region)->box = NULL; \ + (region)->n_box = 0; \ + } + +#define REGION_UNINIT(region) \ + { \ + REGION_EMPTY (region); \ + if ((region)->data) \ + free ((region)->data); \ + (region)->data = NULL; \ + (region)->size = 0; \ + } + +#define REGION_NOTEMPTY(region) \ + ((region)->n_box) + +#define REGION_RECTS(region) \ + ((region)->box) + +#define REGION_NUM_RECTS(region) \ + ((region)->n_box) + +#define REGION_EXTENTS(region) \ + (&(region)->extents) + +#define REGION_UNION(region, box) \ + glitz_region_union (region, box) + +extern glitz_status_t __internal_linkage +glitz_region_union (glitz_region_t *region, + glitz_box_t *box); + +typedef struct glitz_backend { + glitz_drawable_t * + (*create_pbuffer) (void *drawable, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask); + + void + (*destroy) (void *drawable); + + void + (*push_current) (void *drawable, + glitz_surface_t *surface, + glitz_constraint_t constraint); + + glitz_surface_t * + (*pop_current) (void *drawable); + + void + (*swap_buffers) (void *drawable); + + glitz_status_t + (*make_current_read) (void *drawable); + + glitz_gl_proc_address_list_t gl; + + glitz_drawable_format_t *drawable_formats; + int n_drawable_formats; + + glitz_gl_int_t *texture_formats; + glitz_format_t *formats; + int n_formats; + + glitz_gl_float_t gl_version; + glitz_gl_int_t max_texture_2d_size; + glitz_gl_int_t max_texture_rect_size; + unsigned long feature_mask; + + glitz_program_map_t *program_map; +} glitz_backend_t; + +struct _glitz_drawable { + glitz_backend_t *backend; + + int ref_count; + glitz_drawable_format_t *format; + int width, height; + glitz_rectangle_t viewport; + glitz_bool_t update_all; +}; + +#define GLITZ_GL_DRAWABLE(drawable) \ + glitz_gl_proc_address_list_t *gl = &(drawable)->backend->gl; typedef struct _glitz_point_t { glitz_float_t x, y; @@ -251,96 +375,56 @@ typedef struct _glitz_vec_t { typedef struct _glitz_texture { glitz_gl_uint_t name; glitz_gl_enum_t target; - glitz_gl_enum_t format; - unsigned long flags; + glitz_gl_int_t format; + unsigned long flags; glitz_gl_enum_t filter; glitz_gl_enum_t wrap; - unsigned int width; - unsigned int height; + int width; + int height; - glitz_bounding_box_t box; + glitz_box_t box; - glitz_float_t texcoord_width_unit; - glitz_float_t texcoord_height_unit; + glitz_float_t texcoord_width_unit; + glitz_float_t texcoord_height_unit; } glitz_texture_t; struct _glitz_buffer { - glitz_gl_uint_t name; - glitz_gl_enum_t target; - void *data; - int owns_data; - int ref_count; - glitz_surface_t *surface; + glitz_gl_uint_t name; + glitz_gl_enum_t target; + void *data; + int owns_data; + int ref_count; + glitz_drawable_t *drawable; }; typedef struct _glitz_geometry { - glitz_gl_enum_t primitive; - glitz_gl_enum_t type; - glitz_gl_int_t first; + glitz_gl_enum_t primitive; + glitz_gl_enum_t type; + glitz_gl_int_t first; glitz_gl_sizei_t count; - glitz_buffer_t *buffer; - glitz_float_t x_offset; - glitz_float_t y_offset; + glitz_buffer_t *buffer; + glitz_float_t x_offset; + glitz_float_t y_offset; glitz_gl_float_t data[8]; } glitz_geometry_t; -typedef struct glitz_surface_backend { - glitz_surface_t * - (*create_similar) (void *surface, - glitz_format_t *format, - int width, - int height); - - void - (*destroy) (void *surface); - - glitz_bool_t - (*push_current) (void *surface, - glitz_constraint_t constraint); - - void - (*pop_current) (void *surface); - - glitz_texture_t * - (*get_texture) (void *surface, - glitz_bool_t allocate); - - void - (*swap_buffers) (void *surface); - - glitz_bool_t - (*make_current_read) (void *surface); - - glitz_gl_proc_address_list_t gl; - glitz_format_t *formats; - int n_formats; - glitz_program_map_t *program_map; - unsigned long feature_mask; -} glitz_surface_backend_t; - #define GLITZ_SURFACE_FLAG_SOLID_MASK (1L << 0) -#define GLITZ_SURFACE_FLAG_OFFSCREEN_MASK (1L << 1) -#define GLITZ_SURFACE_FLAG_REPEAT_MASK (1L << 2) -#define GLITZ_SURFACE_FLAG_MIRRORED_MASK (1L << 3) -#define GLITZ_SURFACE_FLAG_PAD_MASK (1L << 4) -#define GLITZ_SURFACE_FLAG_DIRTY_MASK (1L << 5) -#define GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK (1L << 6) -#define GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK (1L << 7) -#define GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK (1L << 8) -#define GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK (1L << 9) -#define GLITZ_SURFACE_FLAG_DRAWABLE_DIRTY_MASK (1L << 10) -#define GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK (1L << 11) -#define GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK (1L << 12) -#define GLITZ_SURFACE_FLAG_DRAWABLE_MASK (1L << 13) -#define GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK (1L << 14) -#define GLITZ_SURFACE_FLAG_EYE_COORDS_MASK (1L << 15) -#define GLITZ_SURFACE_FLAG_TRANSFORM_MASK (1L << 16) -#define GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK (1L << 17) - -#define SURFACE_OFFSCREEN(surface) \ - ((surface)->flags & GLITZ_SURFACE_FLAG_OFFSCREEN_MASK) +#define GLITZ_SURFACE_FLAG_REPEAT_MASK (1L << 1) +#define GLITZ_SURFACE_FLAG_MIRRORED_MASK (1L << 2) +#define GLITZ_SURFACE_FLAG_PAD_MASK (1L << 3) +#define GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK (1L << 4) +#define GLITZ_SURFACE_FLAG_DITHER_MASK (1L << 5) +#define GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK (1L << 6) +#define GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK (1L << 7) +#define GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK (1L << 8) +#define GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK (1L << 9) +#define GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK (1L << 10) +#define GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK (1L << 11) +#define GLITZ_SURFACE_FLAG_EYE_COORDS_MASK (1L << 12) +#define GLITZ_SURFACE_FLAG_TRANSFORM_MASK (1L << 13) +#define GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK (1L << 14) #define SURFACE_SOLID(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_MASK) @@ -356,23 +440,20 @@ typedef struct glitz_surface_backend { (((surface)->flags & GLITZ_SURFACE_FLAG_PAD_MASK) && \ (!((surface)->flags & GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK))) -#define SURFACE_DIRTY(surface) \ - ((surface)->flags & GLITZ_SURFACE_FLAG_DIRTY_MASK) - #define SURFACE_COMPONENT_ALPHA(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK) +#define SURFACE_DITHER(surface) \ + ((surface)->flags & GLITZ_SURFACE_FLAG_DITHER_MASK) + #define SURFACE_MULTISAMPLE(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK) #define SURFACE_NICEST_MULTISAMPLE(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK) -#define SURFACE_SOLID_DIRTY(surface) \ - ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK) - -#define SURFACE_DRAWABLE_DIRTY(surface) \ - ((surface)->flags & GLITZ_SURFACE_FLAG_DRAWABLE_DIRTY_MASK) +#define SURFACE_SOLID_DAMAGE(surface) \ + ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK) #define SURFACE_FRAGMENT_FILTER(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK) @@ -380,9 +461,6 @@ typedef struct glitz_surface_backend { #define SURFACE_LINEAR_TRANSFORM_FILTER(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK) -#define SURFACE_DRAWABLE(surface) \ - ((surface)->flags & GLITZ_SURFACE_FLAG_DRAWABLE_MASK) - #define SURFACE_EYE_COORDS(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) @@ -399,8 +477,8 @@ typedef struct _glitz_sample_offset { typedef struct _glitz_multi_sample_info { glitz_sample_offset_t *offsets; - unsigned short *weights; - int n_samples; + unsigned short *weights; + int n_samples; } glitz_sample_info_t; typedef struct _glitz_filter_params_t glitz_filter_params_t; @@ -410,186 +488,194 @@ typedef struct _glitz_matrix { glitz_float_t m[16]; } glitz_matrix_t; -#define GLITZ_UPDATE_VIEWPORT_MASK (1L << 0) -#define GLITZ_UPDATE_DRAW_BUFFER_MASK (1L << 1) -#define GLITZ_UPDATE_MULTISAMPLE_MASK (1L << 2) -#define GLITZ_UPDATE_ALL_MASK ((1L << 3) - 1) +#define GLITZ_DAMAGE_TEXTURE_MASK (1 << 0) +#define GLITZ_DAMAGE_DRAWABLE_MASK (1 << 1) +#define GLITZ_DAMAGE_SOLID_MASK (1 << 2) struct _glitz_surface { - glitz_surface_backend_t *backend; - - int ref_count; - glitz_format_t *format; - glitz_texture_t texture; - unsigned long status_mask; - unsigned long update_mask; - glitz_filter_t filter; + int ref_count; + glitz_format_t *format; + glitz_texture_t texture; + glitz_drawable_t *drawable; + glitz_drawable_t *attached; + unsigned long status_mask; + glitz_filter_t filter; glitz_filter_params_t *filter_params; - glitz_matrix_t *transform; - int width, height; - glitz_bounding_box_t dirty_box; - unsigned long flags; - glitz_gl_enum_t draw_buffer; - glitz_gl_enum_t read_buffer; - glitz_sample_info_t *indirect; - glitz_color_t solid; - glitz_geometry_t geometry; + glitz_matrix_t *transform; + int x, y; + int width, height; + glitz_gl_enum_t buffer; + unsigned long flags; + glitz_sample_info_t *indirect; + glitz_color_t solid; + glitz_geometry_t geometry; + glitz_region_t texture_damage; + glitz_region_t drawable_damage; }; +#define GLITZ_GL_SURFACE(surface) \ + glitz_gl_proc_address_list_t *gl = &(surface)->drawable->backend->gl; + typedef struct _glitz_composite_op_t glitz_composite_op_t; typedef void (*glitz_combine_function_t) (glitz_composite_op_t *); typedef struct _glitz_combine_t { - glitz_combine_type_t type; + glitz_combine_type_t type; glitz_combine_function_t enable; - int texture_units; - int fragment_processing; + int texture_units; + int fragment_processing; } glitz_combine_t; struct _glitz_composite_op_t { - glitz_combine_type_t type; - glitz_combine_t *combine; + glitz_combine_type_t type; + glitz_combine_t *combine; glitz_gl_proc_address_list_t *gl; - glitz_operator_t render_op; - glitz_surface_t *src; - glitz_surface_t *mask; - glitz_surface_t *dst; - glitz_color_t *solid; - glitz_color_t alpha_mask; - int per_component; - glitz_gl_uint_t fp; - int count; + glitz_operator_t render_op; + glitz_surface_t *src; + glitz_surface_t *mask; + glitz_surface_t *dst; + glitz_color_t *solid; + glitz_color_t alpha_mask; + int per_component; + glitz_gl_uint_t fp; + int count; }; typedef struct _glitz_extension_map { glitz_gl_float_t version; - char *name; - int mask; + char *name; + int mask; } glitz_extension_map; extern void __internal_linkage -glitz_set_operator (glitz_gl_proc_address_list_t *gl, glitz_operator_t op); - -void -glitz_intersect_bounding_box (glitz_bounding_box_t *box1, - glitz_bounding_box_t *box2, - glitz_bounding_box_t *return_box); - -extern void __internal_linkage -glitz_union_bounding_box (glitz_bounding_box_t *box1, - glitz_bounding_box_t *box2, - glitz_bounding_box_t *return_box); +glitz_set_operator (glitz_gl_proc_address_list_t *gl, + glitz_operator_t op); unsigned long -glitz_extensions_query (glitz_gl_float_t version, - const char *extensions_string, +glitz_extensions_query (glitz_gl_float_t version, + const char *extensions_string, glitz_extension_map *extensions_map); +typedef glitz_function_pointer_t (* glitz_get_proc_address_proc_t) + (const char *name, void *closure); + +void +glitz_backend_init (glitz_backend_t *backend, + glitz_get_proc_address_proc_t get_proc_address, + void *closure); + extern unsigned int __internal_linkage glitz_uint_to_power_of_two (unsigned int x); extern void __internal_linkage glitz_set_raster_pos (glitz_gl_proc_address_list_t *gl, - int x, - int y); + int x, + int y); extern void __internal_linkage glitz_clamp_value (glitz_float_t *value, - glitz_float_t min, glitz_float_t max); + glitz_float_t min, + glitz_float_t max); + +void +glitz_initiate_state (glitz_gl_proc_address_list_t *gl); + +void +glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl, + glitz_format_t **formats, + glitz_gl_int_t **texture_formats, + int *n_formats); + +glitz_drawable_format_t * +glitz_drawable_format_find (glitz_drawable_format_t *formats, + int n_formats, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count); void glitz_texture_init (glitz_texture_t *texture, - unsigned int width, - unsigned int height, - unsigned int texture_format, - unsigned long feature_mask); + int width, + int height, + glitz_gl_int_t texture_format, + unsigned long feature_mask); void glitz_texture_fini (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture); + glitz_texture_t *texture); void glitz_texture_size_check (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_int_t max_2d, - glitz_gl_int_t max_rect); + glitz_texture_t *texture, + glitz_gl_int_t max_2d, + glitz_gl_int_t max_rect); void glitz_texture_allocate (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture); + glitz_texture_t *texture); extern void __internal_linkage glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_filter_t filter); + glitz_texture_t *texture, + glitz_filter_t filter); extern void __internal_linkage glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - glitz_gl_enum_t wrap); + glitz_texture_t *texture, + glitz_gl_enum_t wrap); void glitz_texture_bind (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture); + glitz_texture_t *texture); void glitz_texture_unbind (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture); + glitz_texture_t *texture); void -glitz_texture_copy_surface (glitz_texture_t *texture, - glitz_surface_t *surface, - int x_surface, - int y_surface, - int width, - int height, - int x_texture, - int y_texture); +glitz_texture_copy_drawable (glitz_gl_proc_address_list_t *gl, + glitz_texture_t *texture, + glitz_drawable_t *drawable, + int x_drawable, + int y_drawable, + int width, + int height, + int x_texture, + int y_texture); void glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl, - glitz_texture_t *texture, - int x_src, - int y_src, - unsigned long flags); - -void -glitz_surface_init (glitz_surface_t *surface, - glitz_surface_backend_t *backend, - glitz_format_t *format, - int width, - int height); - -void -glitz_surface_fini (glitz_surface_t *surface); + glitz_texture_t *texture, + int x_src, + int y_src, + unsigned long flags); extern glitz_texture_t *__internal_linkage glitz_surface_get_texture (glitz_surface_t *surface, - glitz_bool_t allocate); + glitz_bool_t allocate); extern void __internal_linkage -glitz_surface_ensure_solid (glitz_surface_t *surface); +glitz_surface_sync_solid (glitz_surface_t *surface); -glitz_bool_t -glitz_surface_push_current (glitz_surface_t *surface, +extern glitz_bool_t __internal_linkage +glitz_surface_push_current (glitz_surface_t *surface, glitz_constraint_t constraint); -void +extern void __internal_linkage glitz_surface_pop_current (glitz_surface_t *surface); -extern glitz_bool_t __internal_linkage +extern glitz_status_t __internal_linkage glitz_surface_make_current_read (glitz_surface_t *surface); extern void __internal_linkage -glitz_surface_dirty (glitz_surface_t *surface, - glitz_bounding_box_t *box); +glitz_surface_damage (glitz_surface_t *surface, + glitz_box_t *box, + int what); extern void __internal_linkage -glitz_surface_status_add (glitz_surface_t *surface, int flags); - -void -glitz_surface_update_state (glitz_surface_t *surface); +glitz_surface_status_add (glitz_surface_t *surface, + int flags); extern unsigned long __internal_linkage glitz_status_to_status_mask (glitz_status_t status); @@ -597,48 +683,24 @@ glitz_status_to_status_mask (glitz_status_t status); extern glitz_status_t __internal_linkage glitz_status_pop_from_mask (unsigned long *mask); -typedef void (*glitz_format_call_back_t) (glitz_format_t *, void *ptr); - -void -glitz_format_for_each_texture_format (glitz_format_call_back_t call_back, - glitz_gl_proc_address_list_t *gl, - void *ptr); - -glitz_format_t * -glitz_format_find (glitz_format_t *formats, - int n_formats, - unsigned long mask, - const glitz_format_t *templ, - int count); - -glitz_format_t * -glitz_format_find_standard (glitz_format_t *formats, - int n_formats, - glitz_format_name_t format_name); - -extern glitz_gl_int_t __internal_linkage -glitz_format_get_best_texture_format (glitz_format_t *formats, - int n_formats, - glitz_format_t *format); - void glitz_program_map_init (glitz_program_map_t *map); void glitz_program_map_fini (glitz_gl_proc_address_list_t *gl, - glitz_program_map_t *map); + glitz_program_map_t *map); extern glitz_gl_uint_t __internal_linkage glitz_get_fragment_program (glitz_composite_op_t *op, - int fp_type, - int id); + int fp_type, + int id); extern void __internal_linkage glitz_composite_op_init (glitz_composite_op_t *op, - glitz_operator_t render_op, - glitz_surface_t *src, - glitz_surface_t *mask, - glitz_surface_t *dst); + glitz_operator_t render_op, + glitz_surface_t *src, + glitz_surface_t *mask, + glitz_surface_t *dst); extern void __internal_linkage glitz_composite_enable (glitz_composite_op_t *op); @@ -647,53 +709,54 @@ extern void __internal_linkage glitz_composite_disable (glitz_composite_op_t *op); extern void *__internal_linkage -glitz_buffer_bind (glitz_buffer_t *buffer, +glitz_buffer_bind (glitz_buffer_t *buffer, glitz_gl_enum_t target); extern void __internal_linkage glitz_buffer_unbind (glitz_buffer_t *buffer); extern glitz_status_t __internal_linkage -glitz_filter_set_params (glitz_surface_t *surface, - glitz_filter_t filter, +glitz_filter_set_params (glitz_surface_t *surface, + glitz_filter_t filter, glitz_fixed16_16_t *params, - int n_params); + int n_params); extern void __internal_linkage glitz_filter_set_type (glitz_surface_t *surface, - glitz_filter_t filter); + glitz_filter_t filter); extern void __internal_linkage glitz_filter_params_destroy (glitz_filter_params_t *params); extern glitz_gl_uint_t __internal_linkage -glitz_filter_get_vertex_program (glitz_surface_t *surface, +glitz_filter_get_vertex_program (glitz_surface_t *surface, glitz_composite_op_t *op); extern glitz_gl_uint_t __internal_linkage -glitz_filter_get_fragment_program (glitz_surface_t *surface, +glitz_filter_get_fragment_program (glitz_surface_t *surface, glitz_composite_op_t *op); extern void __internal_linkage -glitz_filter_enable (glitz_surface_t *surface, +glitz_filter_enable (glitz_surface_t *surface, glitz_composite_op_t *op); extern void __internal_linkage glitz_geometry_enable_default (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_bounding_box_t *box); + glitz_surface_t *dst, + glitz_box_t *box); extern void __internal_linkage glitz_geometry_enable (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_gl_enum_t *primitive, - glitz_gl_int_t *first, - glitz_gl_sizei_t *count, - glitz_bounding_box_t *box); + glitz_surface_t *dst, + glitz_gl_enum_t *primitive, + glitz_gl_int_t *first, + glitz_gl_sizei_t *count, + glitz_box_t *box); extern void __internal_linkage glitz_geometry_disable (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst); + glitz_surface_t *dst); + #define MAXSHORT SHRT_MAX #define MINSHORT SHRT_MIN @@ -768,26 +831,31 @@ typedef glitz_fixed_16_16 glitz_fixed; #define POWER_OF_TWO(v) ((v & (v - 1)) == 0) -typedef void (*glitz_function_pointer_t) (void); - /* Avoid unnecessary PLT entries. */ -slim_hidden_proto(glitz_surface_find_similar_standard_format) +slim_hidden_proto(glitz_find_similar_drawable_format) +slim_hidden_proto(glitz_create_pbuffer_drawable) +slim_hidden_proto(glitz_drawable_get_width) +slim_hidden_proto(glitz_drawable_get_height) +slim_hidden_proto(glitz_drawable_swap_buffers) +slim_hidden_proto(glitz_drawable_swap_buffers) +slim_hidden_proto(glitz_drawable_flush) +slim_hidden_proto(glitz_drawable_finish) +slim_hidden_proto(glitz_drawable_get_features) +slim_hidden_proto(glitz_drawable_get_format) slim_hidden_proto(glitz_surface_set_transform) slim_hidden_proto(glitz_surface_set_fill) slim_hidden_proto(glitz_surface_set_component_alpha) +slim_hidden_proto(glitz_surface_set_dither) slim_hidden_proto(glitz_surface_set_filter) slim_hidden_proto(glitz_surface_get_width) slim_hidden_proto(glitz_surface_get_height) -slim_hidden_proto(glitz_surface_set_read_color_buffer) -slim_hidden_proto(glitz_surface_set_draw_color_buffer) slim_hidden_proto(glitz_surface_flush) -slim_hidden_proto(glitz_surface_swap_buffers) -slim_hidden_proto(glitz_surface_finish) slim_hidden_proto(glitz_surface_get_status) -slim_hidden_proto(glitz_surface_get_features) slim_hidden_proto(glitz_surface_get_format) +slim_hidden_proto(glitz_surface_get_drawable) +slim_hidden_proto(glitz_surface_get_attached_drawable) 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 new file mode 100644 index 0000000..0fffbc0 --- /dev/null +++ b/src/glx/Makefile.am @@ -0,0 +1,40 @@ +if GLITZ_BUILD_GLX_BACKEND + +INCLUDES = \ + $(GLITZ_INC) \ + $(GLX_CFLAGS) + +lib_LTLIBRARIES = libglitz-glx.la +include_HEADERS = glitz-glx.h + +libglitz_glx_la_SOURCES = \ + glitz-glx.h \ + glitz_glx_drawable.c \ + glitz_glx_format.c \ + glitz_glx_info.c \ + glitz_glx_extension.c \ + glitz_glx_context.c \ + glitz_glx_pbuffer.c \ + glitz_glxext.h \ + glitz_glxint.h + +libglitz_glx_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined +libglitz_glx_la_LIBADD = $(GLITZ_LIB) $(GLX_LIBS) + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = glitz-glx.pc + +endif + +EXTRA_DIST = \ + glitz-glx.h \ + glitz_glx_drawable.c \ + glitz_glx_format.c \ + glitz_glx_info.c \ + glitz_glx_extension.c \ + glitz_glx_context.c \ + glitz_glx_pbuffer.c \ + glitz_glxext.h \ + glitz_glxint.h \ + glitz-glx.pc.in \ + glitz-glx.man diff --git a/src/glx/glitz-glx.h b/src/glx/glitz-glx.h new file mode 100644 index 0000000..818906c --- /dev/null +++ b/src/glx/glitz-glx.h @@ -0,0 +1,84 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifndef GLITZ_GLX_H_INCLUDED +#define GLITZ_GLX_H_INCLUDED + +#include <glitz.h> + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +/* glitz_glx_info.c */ + +void +glitz_glx_init (const char *gl_library); + +void +glitz_glx_fini (void); + + +/* glitz_glx_format.c */ + +glitz_drawable_format_t * +glitz_glx_find_drawable_format (Display *display, + int screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count); + +XVisualInfo * +glitz_glx_get_visual_info_from_format (Display *display, + int screen, + glitz_drawable_format_t *format); + + +/* glitz_glx_drawable.c */ + +glitz_drawable_t * +glitz_glx_create_drawable_for_window (Display *display, + int screen, + glitz_drawable_format_t *format, + Window window, + int width, + int height); + +glitz_drawable_t * +glitz_glx_create_pbuffer_drawable (Display *display, + int screen, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask); + + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* GLITZ_GLX_H_INCLUDED */ diff --git a/src/glx/glitz-glx.man b/src/glx/glitz-glx.man new file mode 100644 index 0000000..4ad99ae --- /dev/null +++ b/src/glx/glitz-glx.man @@ -0,0 +1,26 @@ +.\" +.\" +.de TQ +.br +.ns +.TP +\\$1 +.. +.TH GLITZ-GLX 3 "Version 1.0" + +.SH NAME +GLITZ-GLX \- GLX interface to glitz + +.SH SYNOPSIS +.nf +.B #include <glitz-glx.h> +.fi +.SH DESCRIPTION + +GLX interface to glitz. + +.SH AUTHOR +David Reveman + +.SH "SEE ALSO" +.BR GLITZ (3)
\ No newline at end of file diff --git a/src/glx/glitz-glx.pc.in b/src/glx/glitz-glx.pc.in new file mode 100644 index 0000000..2393cb2 --- /dev/null +++ b/src/glx/glitz-glx.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libglitz-glx +Description: OpenGL compositing library (GLX backend) +Version: @VERSION@ +Requires: glitz +Libs: -L${libdir} -lglitz-glx @GLX_LIBS@ +Cflags: -I${includedir} @GLX_CFLAGS@ diff --git a/src/glx/glitz_glx_context.c b/src/glx/glitz_glx_context.c new file mode 100644 index 0000000..b251ee2 --- /dev/null +++ b/src/glx/glitz_glx_context.c @@ -0,0 +1,291 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitz_glxint.h" + +#include <stdlib.h> + +extern glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address; + +static void +_glitz_glx_context_create (glitz_glx_screen_info_t *screen_info, + XID visualid, + GLXContext share_list, + glitz_glx_context_t *context) +{ + int vis_info_count, i; + XVisualInfo *vis_infos; + + vis_infos = XGetVisualInfo (screen_info->display_info->display, + 0, NULL, &vis_info_count); + for (i = 0; i < vis_info_count; i++) { + if (vis_infos[i].visual->visualid == visualid) + break; + } + + context->context = glXCreateContext (screen_info->display_info->display, + &vis_infos[i], share_list, + GLITZ_GL_TRUE); + context->id = visualid; + context->fbconfig = (GLXFBConfig) 0; + + XFree (vis_infos); +} + +static void +_glitz_glx_context_create_using_fbconfig (glitz_glx_screen_info_t *screen_info, + XID fbconfigid, + GLXContext share_list, + glitz_glx_context_t *context) +{ + GLXFBConfig *fbconfigs; + int i, n_fbconfigs; + XVisualInfo *vinfo = NULL; + glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; + + fbconfigs = glx->get_fbconfigs (screen_info->display_info->display, + screen_info->screen, &n_fbconfigs); + for (i = 0; i < n_fbconfigs; i++) { + int value; + + glx->get_fbconfig_attrib (screen_info->display_info->display, fbconfigs[i], + GLX_FBCONFIG_ID, &value); + if (value == (int) fbconfigid) + break; + } + + if (i < n_fbconfigs) + vinfo = glx->get_visual_from_fbconfig (screen_info->display_info->display, + fbconfigs[i]); + + context->id = fbconfigid; + if (vinfo) { + context->context = glXCreateContext (screen_info->display_info->display, + vinfo, share_list, GLITZ_GL_TRUE); + XFree (vinfo); + } else if (glx->create_new_context) + context->context = + glx->create_new_context (screen_info->display_info->display, + fbconfigs[i], GLX_RGBA_TYPE, share_list, + GLITZ_GL_TRUE); + + if (context->context) + context->fbconfig = fbconfigs[i]; + else + context->fbconfig = (GLXFBConfig) 0; + + if (fbconfigs) + XFree (fbconfigs); +} + +glitz_glx_context_t * +glitz_glx_context_get (glitz_glx_screen_info_t *screen_info, + glitz_drawable_format_t *format) +{ + glitz_glx_context_t *context; + glitz_glx_context_t **contexts = screen_info->contexts; + int index, n_contexts = screen_info->n_contexts; + XID format_id; + + for (; n_contexts; n_contexts--, contexts++) + if ((*contexts)->id == screen_info->format_ids[format->id]) + return *contexts; + + index = screen_info->n_contexts++; + + screen_info->contexts = + realloc (screen_info->contexts, + sizeof (glitz_glx_context_t *) * screen_info->n_contexts); + if (!screen_info->contexts) + return NULL; + + context = malloc (sizeof (glitz_glx_context_t)); + if (!context) + return NULL; + + screen_info->contexts[index] = context; + + format_id = screen_info->format_ids[format->id]; + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) + _glitz_glx_context_create_using_fbconfig (screen_info, + format_id, + screen_info->root_context, + context); + else + _glitz_glx_context_create (screen_info, + format_id, + screen_info->root_context, + context); + + if (!screen_info->root_context) + screen_info->root_context = context->context; + + memcpy (&context->backend.gl, + &_glitz_glx_gl_proc_address, + sizeof (glitz_gl_proc_address_list_t)); + + context->backend.create_pbuffer = glitz_glx_create_pbuffer; + context->backend.destroy = glitz_glx_destroy; + context->backend.push_current = glitz_glx_push_current; + context->backend.pop_current = glitz_glx_pop_current; + context->backend.swap_buffers = glitz_glx_swap_buffers; + context->backend.make_current_read = glitz_glx_make_current_read; + + context->backend.drawable_formats = screen_info->formats; + context->backend.n_drawable_formats = screen_info->n_formats; + + context->backend.texture_formats = NULL; + context->backend.formats = NULL; + context->backend.n_formats = 0; + + context->backend.program_map = &screen_info->program_map; + context->backend.feature_mask = 0; + + context->initialized = 0; + + return context; +} + +void +glitz_glx_context_destroy (glitz_glx_screen_info_t *screen_info, + glitz_glx_context_t *context) +{ + if (context->backend.formats) + free (context->backend.formats); + + if (context->backend.texture_formats) + free (context->backend.texture_formats); + + glXDestroyContext (screen_info->display_info->display, + context->context); + free (context); +} + +static void +_glitz_glx_context_initialize (glitz_glx_screen_info_t *screen_info, + glitz_glx_context_t *context) +{ + glitz_backend_init (&context->backend, + glitz_glx_get_proc_address, + (void *) screen_info); + + context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS, + context->max_viewport_dims); + + glitz_initiate_state (&_glitz_glx_gl_proc_address); + + context->initialized = 1; +} + +static void +_glitz_glx_context_make_current (glitz_glx_drawable_t *drawable, + glitz_bool_t flush) +{ + if (flush) + glFlush (); + + glXMakeCurrent (drawable->screen_info->display_info->display, + drawable->drawable, + drawable->context->context); + + drawable->base.update_all = 1; + + if (!drawable->context->initialized) + _glitz_glx_context_initialize (drawable->screen_info, drawable->context); +} + +static void +_glitz_glx_context_update (glitz_glx_drawable_t *drawable, + glitz_constraint_t constraint) +{ + GLXContext context; + + switch (constraint) { + case GLITZ_NONE: + break; + case GLITZ_ANY_CONTEXT_CURRENT: + context = glXGetCurrentContext (); + if (context == (GLXContext) 0) + _glitz_glx_context_make_current (drawable, 0); + break; + case GLITZ_CONTEXT_CURRENT: + context = glXGetCurrentContext (); + if (context != drawable->context->context) + _glitz_glx_context_make_current (drawable, (context)? 1: 0); + break; + case GLITZ_DRAWABLE_CURRENT: + context = glXGetCurrentContext (); + if ((context != drawable->context->context) || + (glXGetCurrentDrawable () != drawable->drawable)) + _glitz_glx_context_make_current (drawable, (context)? 1: 0); + break; + } +} + +void +glitz_glx_push_current (void *abstract_drawable, + glitz_surface_t *surface, + glitz_constraint_t constraint) +{ + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; + glitz_glx_context_info_t *context_info; + int index; + + index = drawable->screen_info->context_stack_size++; + + context_info = &drawable->screen_info->context_stack[index]; + context_info->drawable = drawable; + context_info->surface = surface; + context_info->constraint = constraint; + + _glitz_glx_context_update (context_info->drawable, constraint); +} + +glitz_surface_t * +glitz_glx_pop_current (void *abstract_drawable) +{ + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; + glitz_glx_context_info_t *context_info = NULL; + int index; + + drawable->screen_info->context_stack_size--; + index = drawable->screen_info->context_stack_size - 1; + + context_info = &drawable->screen_info->context_stack[index]; + + if (context_info->drawable) + _glitz_glx_context_update (context_info->drawable, + context_info->constraint); + + if (context_info->constraint == GLITZ_DRAWABLE_CURRENT) + return context_info->surface; + + return NULL; +} diff --git a/src/glx/glitz_glx_drawable.c b/src/glx/glitz_glx_drawable.c new file mode 100644 index 0000000..7c70a14 --- /dev/null +++ b/src/glx/glitz_glx_drawable.c @@ -0,0 +1,210 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitz_glxint.h" + +glitz_status_t +glitz_glx_make_current_read (void *abstract_surface) +{ + return GLITZ_STATUS_NOT_SUPPORTED; +} + +static glitz_glx_drawable_t * +_glitz_glx_create_drawable (glitz_glx_screen_info_t *screen_info, + glitz_glx_context_t *context, + glitz_drawable_format_t *format, + GLXDrawable glx_drawable, + GLXPbuffer glx_pbuffer, + int width, + int height) +{ + glitz_glx_drawable_t *drawable; + + if (width <= 0 || height <= 0) + return NULL; + + drawable = (glitz_glx_drawable_t *) malloc (sizeof (glitz_glx_drawable_t)); + if (drawable == NULL) + return NULL; + + drawable->base.ref_count = 1; + drawable->screen_info = screen_info; + drawable->context = context; + drawable->drawable = glx_drawable; + drawable->pbuffer = glx_pbuffer; + drawable->base.format = format; + drawable->base.backend = &context->backend; + + glitz_drawable_update_size (&drawable->base, width, height); + + if (!context->initialized) { + glitz_glx_push_current (drawable, NULL, GLITZ_CONTEXT_CURRENT); + glitz_glx_pop_current (drawable); + } + + if (width > context->max_viewport_dims[0] || + height > context->max_viewport_dims[1]) { + free (drawable); + return NULL; + } + + screen_info->drawables++; + + return drawable; +} + +static glitz_drawable_t * +_glitz_glx_create_pbuffer_drawable (glitz_glx_screen_info_t *screen_info, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask) +{ + glitz_glx_drawable_t *drawable; + glitz_glx_context_t *context; + unsigned int width, height; + GLXPbuffer pbuffer; + + if (!format->types.pbuffer) + return NULL; + + context = glitz_glx_context_get (screen_info, format); + if (!context) + return NULL; + + pbuffer = glitz_glx_pbuffer_create (screen_info, context->fbconfig, + attributes, mask, + &width, &height); + if (!pbuffer) + return NULL; + + drawable = _glitz_glx_create_drawable (screen_info, context, format, + pbuffer, pbuffer, + width, height); + if (!drawable) { + glitz_glx_pbuffer_destroy (screen_info, pbuffer); + return NULL; + } + + return &drawable->base; +} + +glitz_drawable_t * +glitz_glx_create_pbuffer (void *abstract_templ, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask) +{ + glitz_glx_drawable_t *templ = (glitz_glx_drawable_t *) abstract_templ; + + return _glitz_glx_create_pbuffer_drawable (templ->screen_info, format, + attributes, mask); +} + +glitz_drawable_t * +glitz_glx_create_drawable_for_window (Display *display, + int screen, + glitz_drawable_format_t *format, + Window window, + int width, + int height) +{ + glitz_glx_drawable_t *drawable; + glitz_glx_screen_info_t *screen_info; + glitz_glx_context_t *context; + + screen_info = glitz_glx_screen_info_get (display, screen); + if (!screen_info) + return NULL; + + context = glitz_glx_context_get (screen_info, format); + if (!context) + return NULL; + + drawable = _glitz_glx_create_drawable (screen_info, context, format, + window, (GLXPbuffer) 0, + width, height); + if (!drawable) + return NULL; + + return &drawable->base; +} +slim_hidden_def(glitz_glx_create_drawable_for_window); + +glitz_drawable_t * +glitz_glx_create_pbuffer_drawable (Display *display, + int screen, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask) +{ + glitz_glx_screen_info_t *screen_info; + + screen_info = glitz_glx_screen_info_get (display, screen); + if (!screen_info) + return NULL; + + return _glitz_glx_create_pbuffer_drawable (screen_info, format, + attributes, mask); +} +slim_hidden_def(glitz_glx_create_pbuffer_drawable); + +void +glitz_glx_destroy (void *abstract_drawable) +{ + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; + + drawable->screen_info->drawables--; + if (drawable->screen_info->drawables == 0) { + /* + * Last drawable? We have to destroy all fragment programs as this may + * be our last chance to have a context current. + */ + glitz_glx_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT); + glitz_program_map_fini (&drawable->base.backend->gl, + &drawable->screen_info->program_map); + glitz_glx_pop_current (abstract_drawable); + } + + if (glXGetCurrentDrawable () == drawable->drawable) + glXMakeCurrent (drawable->screen_info->display_info->display, None, NULL); + + if (drawable->pbuffer) + glitz_glx_pbuffer_destroy (drawable->screen_info, drawable->pbuffer); + + free (drawable); +} + +void +glitz_glx_swap_buffers (void *abstract_drawable) +{ + glitz_glx_drawable_t *drawable = (glitz_glx_drawable_t *) abstract_drawable; + + glXSwapBuffers (drawable->screen_info->display_info->display, + drawable->drawable); +} diff --git a/src/glx/glitz_glx_extension.c b/src/glx/glitz_glx_extension.c new file mode 100644 index 0000000..efa089f --- /dev/null +++ b/src/glx/glitz_glx_extension.c @@ -0,0 +1,70 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitz_glxint.h" + +static glitz_extension_map glx_extensions[] = { + { 0.0, "GLX_SGIX_fbconfig", GLITZ_GLX_FEATURE_FBCONFIG_MASK }, + { 0.0, "GLX_SGIX_pbuffer", GLITZ_GLX_FEATURE_PBUFFER_MASK }, + { 0.0, "GLX_SGI_make_current_read", + GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK }, + { 0.0, "GLX_ARB_multisample", GLITZ_GLX_FEATURE_MULTISAMPLE_MASK }, + { 0.0, NULL, 0 } +}; + +void +glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info, + glitz_gl_float_t glx_version) +{ + const char *glx_extensions_string; + + glx_extensions_string = + glXQueryExtensionsString (screen_info->display_info->display, + screen_info->screen); + + screen_info->glx_feature_mask = + glitz_extensions_query (glx_version, + glx_extensions_string, + glx_extensions); + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) { + const char *vendor; + + vendor = glXGetClientString (screen_info->display_info->display, + GLX_VENDOR); + + if (vendor) { + + /* NVIDIA's driver seem to support multisample with pbuffers */ + if (!strncmp ("NVIDIA", vendor, 6)) + screen_info->glx_feature_mask |= + GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK; + } + } +} diff --git a/src/glx/glitz_glx_format.c b/src/glx/glitz_glx_format.c new file mode 100644 index 0000000..f4aaf0b --- /dev/null +++ b/src/glx/glitz_glx_format.c @@ -0,0 +1,363 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitz_glxint.h" + +#include <stdlib.h> +#include <string.h> + +static int +_glitz_glx_format_compare (const void *elem1, + const void *elem2) +{ + int i, score[2]; + glitz_drawable_format_t *format[2]; + + format[0] = (glitz_drawable_format_t *) elem1; + format[1] = (glitz_drawable_format_t *) elem2; + i = score[0] = score[1] = 0; + + for (; i < 2; i++) { + if (format[i]->color.red_size) { + if (format[i]->color.red_size == 8) + score[i] += 5; + score[i] += 10; + } + + if (format[i]->color.green_size) { + if (format[i]->color.green_size == 8) + score[i] += 5; + score[i] += 10; + } + + if (format[i]->color.alpha_size) { + if (format[i]->color.alpha_size == 8) + score[i] += 5; + score[i] += 10; + } + + if (format[i]->stencil_size) + score[i] += 5; + + if (format[i]->depth_size) + score[i] += 5; + + if (format[i]->doublebuffer) + score[i] += 10; + + if (format[i]->types.window) + score[i] += 10; + + if (format[i]->types.pbuffer) + score[i] += 10; + + if (format[i]->samples > 1) + score[i] -= (20 - format[i]->samples); + } + + return score[1] - score[0]; +} + +static void +_glitz_add_format (glitz_glx_screen_info_t *screen_info, + glitz_drawable_format_t *format, + XID id) +{ + if (!glitz_drawable_format_find (screen_info->formats, + screen_info->n_formats, + GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK, + format, 0)) { + int n = screen_info->n_formats; + + screen_info->formats = + realloc (screen_info->formats, + sizeof (glitz_drawable_format_t) * (n + 1)); + screen_info->format_ids = + realloc (screen_info->format_ids, sizeof (XID) * (n + 1)); + + if (screen_info->formats && screen_info->format_ids) { + screen_info->formats[n] = *format; + screen_info->formats[n].id = n; + screen_info->format_ids[n] = id; + screen_info->n_formats++; + } + } +} + +static void +_glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info) +{ + Display *display; + glitz_drawable_format_t format; + XVisualInfo visual_templ; + XVisualInfo *visuals; + int i, num_visuals; + + display = screen_info->display_info->display; + + visual_templ.screen = screen_info->screen; + visuals = XGetVisualInfo (display, VisualScreenMask, + &visual_templ, &num_visuals); + + /* No pbuffers without fbconfigs */ + format.types.window = 1; + format.types.pbuffer = 0; + format.id = 0; + + for (i = 0; i < num_visuals; i++) { + int value; + + if ((glXGetConfig (display, &visuals[i], GLX_USE_GL, &value) != 0) || + (value == 0)) + continue; + + glXGetConfig (display, &visuals[i], GLX_RGBA, &value); + if (value == 0) + continue; + + /* Stereo is not supported yet */ + glXGetConfig (display, &visuals[i], GLX_STEREO, &value); + if (value != 0) + continue; + + glXGetConfig (display, &visuals[i], GLX_RED_SIZE, &value); + format.color.red_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_GREEN_SIZE, &value); + format.color.green_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_BLUE_SIZE, &value); + format.color.blue_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_ALPHA_SIZE, &value); + format.color.alpha_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_DEPTH_SIZE, &value); + format.depth_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_STENCIL_SIZE, &value); + format.stencil_size = (unsigned short) value; + glXGetConfig (display, &visuals[i], GLX_DOUBLEBUFFER, &value); + format.doublebuffer = (value) ? 1: 0; + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) { + glXGetConfig (display, &visuals[i], GLX_SAMPLE_BUFFERS_ARB, &value); + if (value) { + glXGetConfig (display, &visuals[i], GLX_SAMPLES_ARB, &value); + format.samples = (unsigned short) (value > 1)? value: 1; + } else + format.samples = 1; + } else + format.samples = 1; + + _glitz_add_format (screen_info, &format, visuals[i].visualid); + } + + if (visuals) + XFree (visuals); +} + +static glitz_status_t +_glitz_glx_query_formats_using_fbconfigs (glitz_glx_screen_info_t *screen_info) +{ + glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; + Display *display; + glitz_drawable_format_t format; + GLXFBConfig *fbconfigs; + int i, num_configs; + XID id; + + display = screen_info->display_info->display; + + fbconfigs = glx->get_fbconfigs (display, screen_info->screen, &num_configs); + if (!fbconfigs) { + /* fbconfigs are not supported, falling back to visuals */ + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_FBCONFIG_MASK; + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; + + return GLITZ_STATUS_NOT_SUPPORTED; + } + + for (i = 0; i < num_configs; i++) { + int value; + + if ((glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_RENDER_TYPE, &value) != 0) || + (!(value & GLX_RGBA_BIT))) + continue; + + /* Stereo is not supported yet */ + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STEREO, &value); + if (value != 0) + continue; + + glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_DRAWABLE_TYPE, &value); + if (!((value & GLX_WINDOW_BIT) || (value & GLX_PBUFFER_BIT))) + continue; + + format.types.window = (value & GLX_WINDOW_BIT)? 1: 0; + format.types.pbuffer = (value & GLX_PBUFFER_BIT)? 1: 0; + format.id = 0; + + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_FBCONFIG_ID, &value); + id = (XID) value; + + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_RED_SIZE, &value); + format.color.red_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_GREEN_SIZE, &value); + format.color.green_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_BLUE_SIZE, &value); + format.color.blue_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_ALPHA_SIZE, &value); + format.color.alpha_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DEPTH_SIZE, &value); + format.depth_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_STENCIL_SIZE, &value); + format.stencil_size = (unsigned short) value; + glx->get_fbconfig_attrib (display, fbconfigs[i], GLX_DOUBLEBUFFER, &value); + format.doublebuffer = (value)? 1: 0; + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_MULTISAMPLE_MASK) { + glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_SAMPLE_BUFFERS_ARB, &value); + if (value) { + glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_SAMPLES_ARB, &value); + format.samples = (unsigned short) (value > 1)? value: 1; + if (format.samples > 1) { + if (!(screen_info->glx_feature_mask & + GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK)) + format.types.pbuffer = 0; + } + } else + format.samples = 1; + } else + format.samples = 1; + + _glitz_add_format (screen_info, &format, id); + } + + if (fbconfigs) + XFree (fbconfigs); + + return GLITZ_STATUS_SUCCESS; +} + +void +glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info) +{ + glitz_status_t status = GLITZ_STATUS_NOT_SUPPORTED; + XID *new_ids; + int i; + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) + status = _glitz_glx_query_formats_using_fbconfigs (screen_info); + + if (status) + _glitz_glx_query_formats (screen_info); + + if (!screen_info->n_formats) + return; + + qsort (screen_info->formats, screen_info->n_formats, + sizeof (glitz_drawable_format_t), _glitz_glx_format_compare); + + /* + * Update XID list so that it matches the sorted format list. + */ + new_ids = malloc (sizeof (XID) * screen_info->n_formats); + if (!new_ids) { + screen_info->n_formats = 0; + return; + } + + for (i = 0; i < screen_info->n_formats; i++) { + new_ids[i] = screen_info->format_ids[screen_info->formats[i].id]; + screen_info->formats[i].id = i; + } + + free (screen_info->format_ids); + screen_info->format_ids = new_ids; +} + +glitz_drawable_format_t * +glitz_glx_find_drawable_format (Display *display, + int screen, + unsigned long mask, + const glitz_drawable_format_t *templ, + int count) +{ + glitz_glx_screen_info_t *screen_info = + glitz_glx_screen_info_get (display, screen); + + return glitz_drawable_format_find (screen_info->formats, + screen_info->n_formats, + mask, templ, count); +} +slim_hidden_def(glitz_glx_find_drawable_format); + +XVisualInfo * +glitz_glx_get_visual_info_from_format (Display *display, + int screen, + glitz_drawable_format_t *format) +{ + XVisualInfo *vinfo = NULL; + glitz_glx_screen_info_t *screen_info = + glitz_glx_screen_info_get (display, screen); + glitz_glx_static_proc_address_list_t *glx = &screen_info->glx; + + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) { + GLXFBConfig *fbconfigs; + int i, n_fbconfigs; + int fbconfigid = screen_info->format_ids[format->id]; + + fbconfigs = glx->get_fbconfigs (display, screen, &n_fbconfigs); + for (i = 0; i < n_fbconfigs; i++) { + int value; + + glx->get_fbconfig_attrib (display, fbconfigs[i], + GLX_FBCONFIG_ID, &value); + if (value == fbconfigid) + break; + } + + if (i < n_fbconfigs) + vinfo = glx->get_visual_from_fbconfig (display, fbconfigs[i]); + + if (fbconfigs) + XFree (fbconfigs); + + } else { + XVisualInfo templ; + int n_items; + + templ.visualid = screen_info->format_ids[format->id]; + + vinfo = XGetVisualInfo (display, VisualIDMask, &templ, &n_items); + } + + return vinfo; +} +slim_hidden_def(glitz_glx_get_visual_info_from_format); diff --git a/src/glitz_glx_info.c b/src/glx/glitz_glx_info.c index d85a748..47bef56 100644 --- a/src/glitz_glx_info.c +++ b/src/glx/glitz_glx_info.c @@ -1,28 +1,26 @@ /* - * Copyright © 2004 David Reveman, Peter Nilsson - * + * 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 names of - * David Reveman and Peter Nilsson not be used in advertising or - * publicity pertaining to distribution of the software without - * specific, written prior permission. David Reveman and Peter Nilsson - * makes no representations about the suitability of this software for - * any purpose. It is provided "as is" without express or implied warranty. + * 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 AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND - * PETER NILSSON 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. + * 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. * - * Authors: David Reveman <c99drn@cs.umu.se> - * Peter Nilsson <c99pnn@cs.umu.se> + * Author: David Reveman <c99drn@cs.umu.se> */ #ifdef HAVE_CONFIG_H @@ -35,9 +33,12 @@ #include <dlfcn.h> glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address = { + + /* core */ (glitz_gl_enable_t) glEnable, (glitz_gl_disable_t) glDisable, (glitz_gl_get_error_t) glGetError, + (glitz_gl_get_string_t) glGetString, (glitz_gl_enable_client_state_t) glEnableClientState, (glitz_gl_disable_client_state_t) glDisableClientState, (glitz_gl_vertex_pointer_t) glVertexPointer, @@ -92,6 +93,7 @@ glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address = { (glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D, (glitz_gl_get_integer_v_t) glGetIntegerv, + /* extensions */ (glitz_gl_blend_color_t) 0, (glitz_gl_active_texture_t) 0, (glitz_gl_gen_programs_t) 0, @@ -107,20 +109,18 @@ glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address = { (glitz_gl_buffer_sub_data_t) 0, (glitz_gl_get_buffer_sub_data_t) 0, (glitz_gl_map_buffer_t) 0, - (glitz_gl_unmap_buffer_t) 0, - - 1 + (glitz_gl_unmap_buffer_t) 0 }; glitz_function_pointer_t -glitz_glx_get_proc_address (glitz_glx_screen_info_t *screen_info, - const char *name) +glitz_glx_get_proc_address (const char *name, + void *closure) { - glitz_function_pointer_t address = NULL; + glitz_glx_screen_info_t *screen_info = (glitz_glx_screen_info_t *) closure; glitz_glx_thread_info_t *info = screen_info->display_info->thread_info; + glitz_function_pointer_t address = NULL; - if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_GLX_GET_PROC_ADDRESS_MASK) + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK) address = screen_info->glx.get_proc_address ((glitz_gl_ubyte_t *) name); if (!address) { @@ -141,89 +141,108 @@ glitz_glx_get_proc_address (glitz_glx_screen_info_t *screen_info, static void _glitz_glx_proc_address_lookup (glitz_glx_screen_info_t *screen_info) { - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GLX_FBCONFIG_MASK) { + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_FBCONFIG_MASK) { if (screen_info->glx_version >= 1.3f) { screen_info->glx.get_fbconfigs = (glitz_glx_get_fbconfigs_t) - glitz_glx_get_proc_address (screen_info, "glXGetFBConfigs"); + glitz_glx_get_proc_address ("glXGetFBConfigs", (void *) screen_info); screen_info->glx.get_fbconfig_attrib = (glitz_glx_get_fbconfig_attrib_t) - glitz_glx_get_proc_address (screen_info, "glXGetFBConfigAttrib"); + glitz_glx_get_proc_address ("glXGetFBConfigAttrib", + (void *) screen_info); screen_info->glx.get_visual_from_fbconfig = (glitz_glx_get_visual_from_fbconfig_t) - glitz_glx_get_proc_address (screen_info, "glXGetVisualFromFBConfig"); + glitz_glx_get_proc_address ("glXGetVisualFromFBConfig", + (void *) screen_info); screen_info->glx.create_new_context = (glitz_glx_create_new_context_t) - glitz_glx_get_proc_address (screen_info, "glXCreateNewContext"); + glitz_glx_get_proc_address ("glXCreateNewContext", + (void *) screen_info); - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GLX_PBUFFER_MASK) { + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_PBUFFER_MASK) { screen_info->glx.create_pbuffer = (glitz_glx_create_pbuffer_t) - glitz_glx_get_proc_address (screen_info, "glXCreatePbuffer"); + glitz_glx_get_proc_address ("glXCreatePbuffer", + (void *) screen_info); screen_info->glx.destroy_pbuffer = (glitz_glx_destroy_pbuffer_t) - glitz_glx_get_proc_address (screen_info, "glXDestroyPbuffer"); + glitz_glx_get_proc_address ("glXDestroyPbuffer", + (void *) screen_info); + screen_info->glx.query_drawable = (glitz_glx_query_drawable_t) + glitz_glx_get_proc_address ("glXQueryDrawable", + (void *) screen_info); } } else { screen_info->glx.get_fbconfigs = (glitz_glx_get_fbconfigs_t) - glitz_glx_get_proc_address (screen_info, "glXGetFBConfigsSGIX"); + glitz_glx_get_proc_address ("glXGetFBConfigsSGIX", + (void *) screen_info); screen_info->glx.get_fbconfig_attrib = (glitz_glx_get_fbconfig_attrib_t) - glitz_glx_get_proc_address (screen_info, "glXGetFBConfigAttribSGIX"); + glitz_glx_get_proc_address ("glXGetFBConfigAttribSGIX", + (void *) screen_info); screen_info->glx.get_visual_from_fbconfig = (glitz_glx_get_visual_from_fbconfig_t) - glitz_glx_get_proc_address (screen_info, - "glXGetVisualFromFBConfigSGIX"); + glitz_glx_get_proc_address ("glXGetVisualFromFBConfigSGIX", + (void *) screen_info); screen_info->glx.create_new_context = (glitz_glx_create_new_context_t) - glitz_glx_get_proc_address (screen_info, - "glXCreateContextWithConfigSGIX"); + glitz_glx_get_proc_address ("glXCreateContextWithConfigSGIX", + (void *) screen_info); - if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_GLX_PBUFFER_MASK) { + if (screen_info->glx_feature_mask & GLITZ_GLX_FEATURE_PBUFFER_MASK) { screen_info->glx.create_pbuffer = (glitz_glx_create_pbuffer_t) - glitz_glx_get_proc_address (screen_info, "glXCreatePbufferSGIX"); + glitz_glx_get_proc_address ("glXCreateGLXPbufferSGIX", + (void *) screen_info); screen_info->glx.destroy_pbuffer = (glitz_glx_destroy_pbuffer_t) - glitz_glx_get_proc_address (screen_info, "glXDestroyPbufferSGIX"); + glitz_glx_get_proc_address ("glXDestroyGLXPbufferSGIX", + (void *) screen_info); + screen_info->glx.query_drawable = (glitz_glx_query_drawable_t) + glitz_glx_get_proc_address ("glXQueryGLXPbufferSGIX", + (void *) screen_info); } } if ((!screen_info->glx.create_pbuffer) || - (!screen_info->glx.destroy_pbuffer)) - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_GLX_PBUFFER_MASK; + (!screen_info->glx.destroy_pbuffer) || + (!screen_info->glx.query_drawable)) + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; if ((!screen_info->glx.get_fbconfigs) || (!screen_info->glx.get_fbconfig_attrib) || (!screen_info->glx.get_visual_from_fbconfig) || (!screen_info->glx.create_new_context)) { - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_GLX_FBCONFIG_MASK; - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_GLX_PBUFFER_MASK; + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_FBCONFIG_MASK; + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; } } else - screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_GLX_PBUFFER_MASK; + screen_info->glx_feature_mask &= ~GLITZ_GLX_FEATURE_PBUFFER_MASK; if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_GLX_MAKE_CURRENT_READ_MASK) { + GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK) { if (screen_info->glx_version >= 1.3f) { screen_info->glx.make_context_current = (glitz_glx_make_context_current_t) - glitz_glx_get_proc_address (screen_info, "glXMakeContextCurrent"); + glitz_glx_get_proc_address ("glXMakeContextCurrent", + (void *) screen_info); } else { screen_info->glx.make_context_current = (glitz_glx_make_context_current_t) - glitz_glx_get_proc_address (screen_info, "glXMakeCurrentReadSGI"); + glitz_glx_get_proc_address ("glXMakeCurrentReadSGI", + (void *) screen_info); } if (!screen_info->glx.make_context_current) screen_info->glx_feature_mask &= - ~GLITZ_GLX_FEATURE_GLX_MAKE_CURRENT_READ_MASK; + ~GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK; } if (screen_info->glx_feature_mask & - GLITZ_GLX_FEATURE_GLX_GET_PROC_ADDRESS_MASK) { + GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK) { if (screen_info->glx_version >= 1.4f) { screen_info->glx.get_proc_address = (glitz_glx_get_proc_address_t) - glitz_glx_get_proc_address (screen_info, "glXGetProcAddress"); + glitz_glx_get_proc_address ("glXGetProcAddress", (void *) screen_info); } else { screen_info->glx.get_proc_address = (glitz_glx_get_proc_address_t) - glitz_glx_get_proc_address (screen_info, "glXGetProcAddressARB"); + glitz_glx_get_proc_address ("glXGetProcAddressARB", + (void *) screen_info); } if (!screen_info->glx.get_proc_address) screen_info->glx_feature_mask &= - ~GLITZ_GLX_FEATURE_GLX_GET_PROC_ADDRESS_MASK; + ~GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK; } } @@ -417,76 +436,9 @@ _glitz_glx_display_destroy (glitz_glx_display_info_t *display_info) free (display_info); } -static void -_glitz_glx_create_root_context (glitz_glx_screen_info_t *screen_info) -{ - XVisualInfo *vinfo; - XSetWindowAttributes win_attrib; - static int attrib_double[] = { - GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_DOUBLEBUFFER, - None - }; - static int attrib_single[] = { - GLX_RGBA, - GLX_RED_SIZE, 1, - None - }; - int screen = screen_info->screen; - Display *display = screen_info->display_info->display; - - vinfo = glXChooseVisual (display, screen, attrib_double); - if (!vinfo) - vinfo = glXChooseVisual (display, screen, attrib_single); - - if (vinfo) { - screen_info->root_colormap = XCreateColormap (display, - RootWindow (display, screen), - vinfo->visual, AllocNone); - win_attrib.background_pixel = 0; - win_attrib.border_pixel = 0; - win_attrib.event_mask = StructureNotifyMask | ExposureMask; - win_attrib.colormap = screen_info->root_colormap; - - screen_info->root_drawable = - XCreateWindow (display, RootWindow (display, screen), - -1, -1, 1, 1, 0, vinfo->depth, InputOutput, - vinfo->visual, - CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, - &win_attrib); - - screen_info->root_context.context = - glXCreateContext (display, vinfo, NULL, 1); - - screen_info->root_context.id = vinfo->visualid; - - XFree (vinfo); - } else { - screen_info->root_drawable = None; - screen_info->root_context.context = NULL; - screen_info->root_context.id = 0; - } - - screen_info->root_context.fbconfig = (XID) 0; - - glitz_glx_surface_backend_init (&screen_info->root_context.backend); - - memcpy (&screen_info->root_context.backend.gl, - &_glitz_glx_gl_proc_address, - sizeof (glitz_gl_proc_address_list_t)); - - screen_info->root_context.backend.formats = NULL; - screen_info->root_context.backend.n_formats = 0; - screen_info->root_context.backend.program_map = NULL; - screen_info->root_context.backend.feature_mask = 0; - - screen_info->root_context.backend.gl.need_lookup = 1; -} - glitz_glx_screen_info_t * glitz_glx_screen_info_get (Display *display, - int screen) + int screen) { glitz_glx_screen_info_t *screen_info; glitz_glx_display_info_t *display_info = @@ -503,12 +455,13 @@ glitz_glx_screen_info_get (Display *display, display_info->screens = realloc (display_info->screens, sizeof (glitz_glx_screen_info_t *) * display_info->n_screens); - + screen_info = malloc (sizeof (glitz_glx_screen_info_t)); display_info->screens[index] = screen_info; - + screen_info->display_info = display_info; screen_info->screen = screen; + screen_info->drawables = 0; screen_info->formats = NULL; screen_info->format_ids = NULL; screen_info->n_formats = 0; @@ -520,43 +473,26 @@ glitz_glx_screen_info_get (Display *display, glitz_program_map_init (&screen_info->program_map); - screen_info->root_context.context = (GLXContext) 0; + screen_info->root_context = (GLXContext) 0; + 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_create_root_context (screen_info); - } - } - - screen_info->glx_feature_mask = screen_info->feature_mask = 0; - - if (screen_info->root_context.context && - glXMakeCurrent (screen_info->display_info->display, - screen_info->root_drawable, - screen_info->root_context.context)) { - if (glitz_glx_query_extensions (screen_info) == GLITZ_STATUS_SUCCESS) { - screen_info->root_context.backend.feature_mask = - screen_info->feature_mask; - + 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_context_proc_address_lookup (screen_info, - &screen_info->root_context); glitz_glx_query_formats (screen_info); + } } } - screen_info->root_context.backend.formats = screen_info->formats; - screen_info->root_context.backend.n_formats = screen_info->n_formats; - screen_info->root_context.backend.program_map = &screen_info->program_map; - screen_info->context_stack_size = 1; + screen_info->context_stack->drawable = NULL; screen_info->context_stack->surface = NULL; - screen_info->context_stack->constraint = GLITZ_CN_NONE; + screen_info->context_stack->constraint = GLITZ_NONE; return screen_info; } @@ -564,17 +500,11 @@ glitz_glx_screen_info_get (Display *display, static void _glitz_glx_screen_destroy (glitz_glx_screen_info_t *screen_info) { - int i; Display *display = screen_info->display_info->display; + int i; - if (screen_info->root_context.context && - glXMakeCurrent (screen_info->display_info->display, - screen_info->root_drawable, - screen_info->root_context.context)) { - glitz_program_map_fini (&screen_info->root_context.backend.gl, - &screen_info->program_map); + if (screen_info->root_context) glXMakeCurrent (display, None, NULL); - } for (i = 0; i < screen_info->n_contexts; i++) glitz_glx_context_destroy (screen_info, screen_info->contexts[i]); @@ -587,15 +517,6 @@ _glitz_glx_screen_destroy (glitz_glx_screen_info_t *screen_info) if (screen_info->format_ids) free (screen_info->format_ids); - - if (screen_info->root_context.context) - glXDestroyContext (display, screen_info->root_context.context); - - if (screen_info->root_drawable) - XDestroyWindow (display, screen_info->root_drawable); - - if (screen_info->root_colormap) - XFreeColormap (display, screen_info->root_colormap); free (screen_info); } diff --git a/src/glx/glitz_glx_pbuffer.c b/src/glx/glitz_glx_pbuffer.c new file mode 100644 index 0000000..9506322 --- /dev/null +++ b/src/glx/glitz_glx_pbuffer.c @@ -0,0 +1,86 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitz_glxint.h" + +GLXPbuffer +glitz_glx_pbuffer_create (glitz_glx_screen_info_t *screen_info, + GLXFBConfig fbconfig, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask, + unsigned int *width, + unsigned int *height) +{ + if (fbconfig) { + GLXPbuffer pbuffer; + int pbuffer_attr[13]; + int i = 0; + + pbuffer_attr[i++] = GLX_PBUFFER_WIDTH; + if (mask & GLITZ_PBUFFER_WIDTH_MASK) + pbuffer_attr[i++] = attributes->width; + else + pbuffer_attr[i++] = GLITZ_DEFAULT_PBUFFER_WIDTH; + + pbuffer_attr[i++] = GLX_PBUFFER_HEIGHT; + if (mask & GLITZ_PBUFFER_HEIGHT_MASK) + pbuffer_attr[i++] = attributes->height; + else + pbuffer_attr[i++] = GLITZ_DEFAULT_PBUFFER_HEIGHT; + + pbuffer_attr[i++] = GLX_LARGEST_PBUFFER; + pbuffer_attr[i++] = 1; + + pbuffer_attr[i++] = GLX_PRESERVED_CONTENTS; + pbuffer_attr[i++] = 1; + pbuffer_attr[i++] = 0; + + pbuffer = + screen_info->glx.create_pbuffer (screen_info->display_info->display, + fbconfig, pbuffer_attr); + if (!pbuffer) + return (GLXPbuffer) 0; + + screen_info->glx.query_drawable (screen_info->display_info->display, + pbuffer, GLX_WIDTH, width); + + screen_info->glx.query_drawable (screen_info->display_info->display, + pbuffer, GLX_HEIGHT, height); + return pbuffer; + } else + return (GLXPbuffer) 0; +} + +void +glitz_glx_pbuffer_destroy (glitz_glx_screen_info_t *screen_info, + GLXPbuffer pbuffer) +{ + screen_info->glx.destroy_pbuffer (screen_info->display_info->display, + pbuffer); +} diff --git a/src/glitz_glxext.h b/src/glx/glitz_glxext.h index 9f97452..9d3bea4 100644 --- a/src/glitz_glxext.h +++ b/src/glx/glitz_glxext.h @@ -106,6 +106,9 @@ typedef GLXPbuffer (* glitz_glx_create_pbuffer_t) (Display *display, GLXFBConfig config, const int *attrib_list); typedef void (* glitz_glx_destroy_pbuffer_t) (Display *display, GLXPbuffer pbuffer); +typedef void (* glitz_glx_query_drawable_t) + (Display *display, GLXDrawable drawable, + int attribute, unsigned int *value); typedef Bool (* glitz_glx_make_context_current_t) (Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); typedef GLXContext (* glitz_glx_create_new_context_t) diff --git a/src/glx/glitz_glxint.h b/src/glx/glitz_glxint.h new file mode 100644 index 0000000..9814511 --- /dev/null +++ b/src/glx/glitz_glxint.h @@ -0,0 +1,187 @@ +/* + * 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 names 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 <c99drn@cs.umu.se> + */ + +#ifndef GLITZ_GLXINT_H_INCLUDED +#define GLITZ_GLXINT_H_INCLUDED + +#include "glitz.h" +#include "glitzint.h" + +#include "glitz-glx.h" + +#include <GL/gl.h> +#include <GL/glx.h> + +#include "glitz_glxext.h" + +#define GLITZ_GLX_FEATURE_FBCONFIG_MASK (1L << 0) +#define GLITZ_GLX_FEATURE_PBUFFER_MASK (1L << 1) +#define GLITZ_GLX_FEATURE_MAKE_CURRENT_READ_MASK (1L << 2) +#define GLITZ_GLX_FEATURE_GET_PROC_ADDRESS_MASK (1L << 3) +#define GLITZ_GLX_FEATURE_MULTISAMPLE_MASK (1L << 4) +#define GLITZ_GLX_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 5) + +typedef struct _glitz_glx_drawable glitz_glx_drawable_t; +typedef struct _glitz_glx_screen_info_t glitz_glx_screen_info_t; +typedef struct _glitz_glx_display_info_t glitz_glx_display_info_t; + +typedef struct _glitz_glx_static_proc_address_list_t { + glitz_glx_get_proc_address_t get_proc_address; + glitz_glx_get_fbconfigs_t get_fbconfigs; + glitz_glx_get_fbconfig_attrib_t get_fbconfig_attrib; + glitz_glx_get_visual_from_fbconfig_t get_visual_from_fbconfig; + glitz_glx_create_pbuffer_t create_pbuffer; + glitz_glx_destroy_pbuffer_t destroy_pbuffer; + glitz_glx_query_drawable_t query_drawable; + glitz_glx_make_context_current_t make_context_current; + glitz_glx_create_new_context_t create_new_context; +} glitz_glx_static_proc_address_list_t; + +typedef struct _glitz_glx_thread_info_t { + glitz_glx_display_info_t **displays; + int n_displays; + char *gl_library; + void *dlhand; +} glitz_glx_thread_info_t; + +struct _glitz_glx_display_info_t { + glitz_glx_thread_info_t *thread_info; + Display *display; + glitz_glx_screen_info_t **screens; + int n_screens; +}; + +typedef struct _glitz_glx_context_info_t { + glitz_glx_drawable_t *drawable; + glitz_surface_t *surface; + glitz_constraint_t constraint; +} glitz_glx_context_info_t; + +typedef struct _glitz_glx_context_t { + GLXContext context; + glitz_format_id_t id; + GLXFBConfig fbconfig; + glitz_backend_t backend; + glitz_gl_int_t max_viewport_dims[2]; + glitz_gl_int_t max_texture_2d_size; + glitz_gl_int_t max_texture_rect_size; + glitz_bool_t initialized; +} glitz_glx_context_t; + +struct _glitz_glx_screen_info_t { + glitz_glx_display_info_t *display_info; + int screen; + int drawables; + glitz_drawable_format_t *formats; + XID *format_ids; + int n_formats; + glitz_glx_context_t **contexts; + int n_contexts; + glitz_glx_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE]; + int context_stack_size; + GLXContext root_context; + unsigned long glx_feature_mask; + glitz_gl_float_t glx_version; + glitz_glx_static_proc_address_list_t glx; + glitz_program_map_t program_map; +}; + +struct _glitz_glx_drawable { + glitz_drawable_t base; + + glitz_glx_screen_info_t *screen_info; + glitz_glx_context_t *context; + GLXDrawable drawable; + GLXDrawable pbuffer; +}; + +extern void __internal_linkage +glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info, + glitz_gl_float_t glx_version); + +extern glitz_glx_screen_info_t *__internal_linkage +glitz_glx_screen_info_get (Display *display, + int screen); + +extern glitz_function_pointer_t __internal_linkage +glitz_glx_get_proc_address (const char *name, + void *closure); + +extern glitz_glx_context_t *__internal_linkage +glitz_glx_context_get (glitz_glx_screen_info_t *screen_info, + glitz_drawable_format_t *format); + +extern void __internal_linkage +glitz_glx_context_destroy (glitz_glx_screen_info_t *screen_info, + glitz_glx_context_t *context); + +extern void __internal_linkage +glitz_glx_query_formats (glitz_glx_screen_info_t *screen_info); + +extern GLXPbuffer __internal_linkage +glitz_glx_pbuffer_create (glitz_glx_screen_info_t *screen_info, + GLXFBConfig fbconfig, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask, + unsigned int *width, + unsigned int *height); + +extern void __internal_linkage +glitz_glx_pbuffer_destroy (glitz_glx_screen_info_t *screen_info, + GLXPbuffer pbuffer); + +extern glitz_drawable_t *__internal_linkage +glitz_glx_create_pbuffer (void *abstract_templ, + glitz_drawable_format_t *format, + glitz_pbuffer_attributes_t *attributes, + unsigned long mask); + +extern void __internal_linkage +glitz_glx_push_current (void *abstract_drawable, + glitz_surface_t *surface, + glitz_constraint_t constraint); + +extern glitz_surface_t * __internal_linkage +glitz_glx_pop_current (void *abstract_drawable); + +extern glitz_status_t __internal_linkage +glitz_glx_make_current_read (void *abstract_surface); + +extern void __internal_linkage +glitz_glx_destroy (void *abstract_drawable); + +extern void __internal_linkage +glitz_glx_swap_buffers (void *abstract_drawable); + +/* Avoid unnecessary PLT entries. */ + +slim_hidden_proto(glitz_glx_init) +slim_hidden_proto(glitz_glx_fini) +slim_hidden_proto(glitz_glx_find_drawable_format) +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_pbuffer_drawable) + +#endif /* GLITZ_GLXINT_H_INCLUDED */ |