diff options
author | David Reveman <davidr@novell.com> | 2004-11-03 22:50:58 +0000 |
---|---|---|
committer | David Reveman <davidr@novell.com> | 2004-11-03 22:50:58 +0000 |
commit | 019e7f7e630ce6faeedeb1cf0b9a340530790101 (patch) | |
tree | bd05c27a379cd29d13a7b66e572279fb49ecacfa | |
parent | 0ef062afaa57e370ac68b26d11f4cd60f2b0388b (diff) |
Source tree restructuring and switch to new drawable interface
60 files changed, 5250 insertions, 5155 deletions
@@ -1,3 +1,7 @@ +2004-11-03 David Reveman <c99drn@cs.umu.se> + + * Source tree restructuring and switch to new drawable interface. + 2004-10-21 David Reveman <c99drn@cs.umu.se> * src/glitz_pixel.c (glitz_get_pixels): Set read buffer and diff --git a/Makefile.am b/Makefile.am index 8bb0fb3..5c7d167 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,29 +1,3 @@ SUBDIRS = . src -if GLITZ_BUILD_GLX_BACKEND -libglitz_glx_extra_dist = glitz-glx.pc.in -libglitz_glx_data = glitz-glx.pc -else -libglitz_glx_extra_dist = -libglitz_glx_data = -endif - -if GLITZ_BUILD_AGL_BACKEND -libglitz_agl_extra_dist = glitz-agl.pc.in -libglitz_agl_data = glitz-agl.pc -else -libglitz_agl_extra_dist = -libglitz_agl_data = -endif - -EXTRA_DIST = \ - COPYING \ - glitz.pc.in \ - $(libglitz_glx_extra_dist) - $(libglitz_agl_extra_dist) - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = \ - glitz.pc \ - $(libglitz_glx_data) \ - $(libglitz_agl_data) +EXTRA_DIST = COPYING
\ No newline at end of file @@ -1,3 +1,5 @@ +* API documentation. + * Allow the fragment filters to be applied to mask surfaces and not only source surfaces. The filter system and the fragment programs are design to work both with source and mask surfaces, diff --git a/configure.in b/configure.in index d539bbc..795c480 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ dnl =========================================================================== # Package version number, (as distinct from shared library version) # This must be manually synchronized with the version in src/glitz.h -GLITZ_VERSION=0.2.3 +GLITZ_VERSION=0.3.0 # libtool shared library version # Increment if the interface has additions, changes, removals. @@ -93,6 +93,14 @@ AC_C_BIGENDIAN dnl =========================================================================== +GLITZ_LIB='-L$(top_builddir)/src -lglitz' +GLITZ_INC='-I$(top_builddir)/src -I$(top_srcdir)/src' + +AC_SUBST(GLITZ_LIB) +AC_SUBST(GLITZ_INC) + +dnl =========================================================================== + AC_ARG_ENABLE(glx, AC_HELP_STRING([--disable-glx], [Disable glitz's GLX backend]), [use_glx=$enableval], [use_glx=yes]) @@ -193,9 +201,11 @@ dnl =========================================================================== AC_OUTPUT([ Makefile src/Makefile -glitz.pc -glitz-glx.pc -glitz-agl.pc +src/glx/Makefile +src/agl/Makefile +src/glitz.pc +src/glx/glitz-glx.pc +src/agl/glitz-agl.pc ]) dnl =========================================================================== 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/glitz-agl.pc.in b/src/agl/glitz-agl.pc.in index abe98cc..abe98cc 100644 --- a/glitz-agl.pc.in +++ b/src/agl/glitz-agl.pc.in 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/glitz.pc.in b/src/glitz.pc.in index fee3a7d..fee3a7d 100644 --- a/glitz.pc.in +++ b/src/glitz.pc.in 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/glitz-glx.pc.in b/src/glx/glitz-glx.pc.in index 2393cb2..2393cb2 100644 --- a/glitz-glx.pc.in +++ b/src/glx/glitz-glx.pc.in 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 */ |