From b05afb1f26e5084f4a4a8a77dbc0b35866f911c5 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Tue, 25 Jan 2005 19:50:26 +0000 Subject: Add anti-aliased trapezoids, rectangular clipping, multiple geometry arrays, bitmap geometry, mask surface convolution filtering --- AUTHORS | 2 +- COPYING | 2 +- ChangeLog | 13 + README | 2 +- TODO | 16 - configure.in | 2 +- src/Makefile.am | 4 +- src/agl/glitz-agl.h | 16 +- src/agl/glitz_agl_context.c | 6 +- src/agl/glitz_agl_drawable.c | 44 +- src/agl/glitz_agl_extension.c | 6 +- src/agl/glitz_agl_format.c | 6 +- src/agl/glitz_agl_info.c | 9 +- src/agl/glitz_agl_pbuffer.c | 32 +- src/agl/glitz_aglint.h | 30 +- src/glitz.c | 994 ++++++++++++++++++++++++------------------ src/glitz.h | 231 +++++++--- src/glitz_buffer.c | 159 +++---- src/glitz_compose.c | 72 ++- src/glitz_drawable.c | 18 +- src/glitz_filter.c | 118 +++-- src/glitz_format.c | 6 +- src/glitz_geometry.c | 820 +++++++++++++++++++++++++--------- src/glitz_gl.h | 25 +- src/glitz_operator.c | 4 +- src/glitz_pixel.c | 54 ++- src/glitz_program.c | 141 ++++-- src/glitz_rect.c | 317 +++++++++----- src/glitz_region.c | 6 +- src/glitz_status.c | 4 +- src/glitz_surface.c | 726 ++++++++++++++++-------------- src/glitz_texture.c | 216 +++++---- src/glitz_trap.c | 446 +++++++++++++++++++ src/glitz_trapimp.h | 746 +++++++++++++++++++++++++++++++ src/glitz_util.c | 28 +- src/glitzint.h | 211 +++++---- src/glx/glitz-glx.h | 20 +- src/glx/glitz_glx_context.c | 6 +- src/glx/glitz_glx_drawable.c | 44 +- src/glx/glitz_glx_extension.c | 6 +- src/glx/glitz_glx_format.c | 6 +- src/glx/glitz_glx_info.c | 9 +- src/glx/glitz_glx_pbuffer.c | 59 +-- src/glx/glitz_glxext.h | 4 +- src/glx/glitz_glxint.h | 28 +- 45 files changed, 3964 insertions(+), 1750 deletions(-) create mode 100644 src/glitz_trap.c create mode 100644 src/glitz_trapimp.h diff --git a/AUTHORS b/AUTHORS index 6f731f2..c7cdec0 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,2 @@ -David Reveman +David Reveman Peter Nilsson diff --git a/COPYING b/COPYING index 1296158..127674f 100644 --- a/COPYING +++ b/COPYING @@ -1,5 +1,5 @@ -Copyright © 2004 David Reveman, Peter Nilsson +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 diff --git a/ChangeLog b/ChangeLog index d405a02..41d5536 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-01-25 David Reveman + + * src/glitz.h (GLITZ_REVISION): Bump version to 0.4.0. + + * configure.in: Bump version to 0.4.0. + + Add anti-aliased trapezoids, rectangular clipping, multiple + geometry arrays, bitmap geometry, mask surface convolution filtering. + +2004-12-07 David Reveman + + * src/glitzint.h: Moved misplaced __internal_linkage. + 2004-12-03 David Reveman * src/glitz_compose.c (glitz_composite_op_init): Make sure some diff --git a/README b/README index 2f4fe3f..c65c15d 100644 --- a/README +++ b/README @@ -18,4 +18,4 @@ graphics hardware, hence making a higher level software layer responsible for appropriate actions. David Reveman -c99drn@cs.umu.se +davidr@novell.com diff --git a/TODO b/TODO index 80a22e5..802d076 100644 --- a/TODO +++ b/TODO @@ -1,21 +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, - so this should be really easy. Most of the work will be to validate - that it works correct in all cases. - -* Add low-pass sub-pixel filters for HW accelerated color balancing - of per-component alpha masks. - -* Gamma correction. Software multi-sampling using stencil bits - can easily be gamma corrected without any performance penelty. - The above mentioned sub-pixel filters should include gamma - correction and I should probably also add a gamma correction - filter for alpha-masks and per-component alpha-masks without color - balancing. - * WGL (Windows GL) backend. * Mesa-solo backend. diff --git a/configure.in b/configure.in index 795c480..35c2bb9 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.3.0 +GLITZ_VERSION=0.4.0 # libtool shared library version # Increment if the interface has additions, changes, removals. diff --git a/src/Makefile.am b/src/Makefile.am index 5d747b8..79b63f8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,6 +21,8 @@ libglitz_la_SOURCES = \ glitz_buffer.c \ glitz_geometry.c \ glitz_pixel.c \ + glitz_trap.c \ + glitz_trapimp.h \ glitz_gl.h \ glitzint.h @@ -32,4 +34,4 @@ pkgconfig_DATA = glitz.pc EXTRA_DIST = \ glitz.pc.in \ - glitz.man \ No newline at end of file + glitz.man diff --git a/src/agl/glitz-agl.h b/src/agl/glitz-agl.h index 0d6b637..7bc6031 100644 --- a/src/agl/glitz-agl.h +++ b/src/agl/glitz-agl.h @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifndef GLITZ_AGL_H_INCLUDED @@ -57,13 +57,13 @@ glitz_agl_find_drawable_format (unsigned long mask, glitz_drawable_t * glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format, WindowRef window, - int width, - int height); + unsigned int width, + unsigned int height); glitz_drawable_t * -glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format, - glitz_pbuffer_attributes_t *attributes, - unsigned long mask); +glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); #if defined(__cplusplus) || defined(c_plusplus) diff --git a/src/agl/glitz_agl_context.c b/src/agl/glitz_agl_context.c index d6be7d1..4c473a8 100644 --- a/src/agl/glitz_agl_context.c +++ b/src/agl/glitz_agl_context.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H diff --git a/src/agl/glitz_agl_drawable.c b/src/agl/glitz_agl_drawable.c index 661181d..97cf804 100644 --- a/src/agl/glitz_agl_drawable.c +++ b/src/agl/glitz_agl_drawable.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -41,8 +41,8 @@ _glitz_agl_create_drawable (glitz_agl_thread_info_t *thread_info, glitz_drawable_format_t *format, AGLDrawable agl_drawable, AGLPbuffer agl_pbuffer, - int width, - int height) + unsigned int width, + unsigned int height) { glitz_agl_drawable_t *drawable; @@ -80,15 +80,14 @@ _glitz_agl_create_drawable (glitz_agl_thread_info_t *thread_info, } 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_create_pbuffer_drawable (glitz_agl_thread_info_t *thread_info, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { glitz_agl_drawable_t *drawable; glitz_agl_context_t *context; AGLPbuffer pbuffer; - int width, height; if (!format->types.pbuffer) return NULL; @@ -97,8 +96,7 @@ _glitz_agl_create_pbuffer_drawable (glitz_agl_thread_info_t *thread_info, if (!context) return NULL; - pbuffer = glitz_agl_pbuffer_create (thread_info, attributes, mask, - &width, &height); + pbuffer = glitz_agl_pbuffer_create (thread_info, (int) width, (int) height); if (!pbuffer) return NULL; @@ -114,22 +112,22 @@ _glitz_agl_create_pbuffer_drawable (glitz_agl_thread_info_t *thread_info, } 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_create_pbuffer (void *abstract_templ, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { glitz_agl_drawable_t *templ = (glitz_agl_drawable_t *) abstract_templ; return _glitz_agl_create_pbuffer_drawable (templ->thread_info, format, - attributes, mask); + width, height); } glitz_drawable_t * glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format, WindowRef window, - int width, - int height) + unsigned int width, + unsigned int height) { glitz_agl_drawable_t *drawable; glitz_agl_thread_info_t *thread_info; @@ -159,9 +157,9 @@ glitz_agl_create_drawable_for_window (glitz_drawable_format_t *format, 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_create_pbuffer_drawable (glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { glitz_agl_thread_info_t *thread_info; @@ -170,7 +168,7 @@ glitz_agl_create_pbuffer_drawable (glitz_drawable_format_t *format, return NULL; return _glitz_agl_create_pbuffer_drawable (thread_info, format, - attributes, mask); + width, height); } slim_hidden_def(glitz_agl_create_pbuffer_drawable); diff --git a/src/agl/glitz_agl_extension.c b/src/agl/glitz_agl_extension.c index 22b800e..c564be8 100644 --- a/src/agl/glitz_agl_extension.c +++ b/src/agl/glitz_agl_extension.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H diff --git a/src/agl/glitz_agl_format.c b/src/agl/glitz_agl_format.c index 072c14f..3a10c11 100644 --- a/src/agl/glitz_agl_format.c +++ b/src/agl/glitz_agl_format.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H diff --git a/src/agl/glitz_agl_info.c b/src/agl/glitz_agl_info.c index 575c022..50ac828 100644 --- a/src/agl/glitz_agl_info.c +++ b/src/agl/glitz_agl_info.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -41,6 +41,7 @@ glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address = { (glitz_gl_enable_client_state_t) glEnableClientState, (glitz_gl_disable_client_state_t) glDisableClientState, (glitz_gl_vertex_pointer_t) glVertexPointer, + (glitz_gl_tex_coord_pointer_t) glTexCoordPointer, (glitz_gl_draw_arrays_t) glDrawArrays, (glitz_gl_tex_env_f_t) glTexEnvf, (glitz_gl_tex_env_fv_t) glTexEnvfv, @@ -95,6 +96,8 @@ glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address = { /* extensions */ (glitz_gl_blend_color_t) 0, (glitz_gl_active_texture_t) 0, + (glitz_gl_client_active_texture_t) 0, + (glitz_gl_multi_draw_arrays_t) 0, (glitz_gl_gen_programs_t) 0, (glitz_gl_delete_programs_t) 0, (glitz_gl_program_string_t) 0, diff --git a/src/agl/glitz_agl_pbuffer.c b/src/agl/glitz_agl_pbuffer.c index 5237316..65ed9eb 100644 --- a/src/agl/glitz_agl_pbuffer.c +++ b/src/agl/glitz_agl_pbuffer.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -30,27 +30,14 @@ #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) +glitz_agl_pbuffer_create (glitz_agl_thread_info_t *thread_info, + 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 (!POWER_OF_TWO (width) || !POWER_OF_TWO (height)) { if (thread_info->agl_feature_mask & GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK) target = GLITZ_GL_TEXTURE_RECTANGLE; @@ -59,10 +46,7 @@ glitz_agl_pbuffer_create (glitz_agl_thread_info_t *thread_info, } else target = GLITZ_GL_TEXTURE_2D; - aglCreatePBuffer (w, h, target, GLITZ_GL_RGBA, 0, &pbuffer); - - *width = w; - *height = h; + aglCreatePBuffer (width, height, target, GLITZ_GL_RGBA, 0, &pbuffer); return pbuffer; } diff --git a/src/agl/glitz_aglint.h b/src/agl/glitz_aglint.h index 0127117..ea1a64c 100644 --- a/src/agl/glitz_aglint.h +++ b/src/agl/glitz_aglint.h @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifndef GLITZ_GLXINT_H_INCLUDED @@ -87,10 +87,10 @@ struct _glitz_agl_drawable { 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 +extern glitz_agl_thread_info_t __internal_linkage * glitz_agl_thread_info_get (void); -extern glitz_agl_context_t *__internal_linkage +extern glitz_agl_context_t __internal_linkage * glitz_agl_context_get (glitz_agl_thread_info_t *thread_info, glitz_drawable_format_t *format); @@ -102,27 +102,25 @@ 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); +glitz_agl_pbuffer_create (glitz_agl_thread_info_t *thread_info, + 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 glitz_drawable_t __internal_linkage * +glitz_agl_create_pbuffer (void *abstract_templ, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); 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 +extern glitz_surface_t __internal_linkage * glitz_agl_pop_current (void *abstract_drawable); extern glitz_status_t __internal_linkage diff --git a/src/glitz.c b/src/glitz.c index 39620a5..2ea92a3 100644 --- a/src/glitz.c +++ b/src/glitz.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -29,22 +29,16 @@ #include "glitzint.h" -#define SET_COLOR(color, set_red, set_green, set_blue, set_alpha) \ - (color).red = (set_red); \ - (color).green = (set_green); \ - (color).blue = (set_blue); \ - (color).alpha = (set_alpha) - -glitz_gl_uint_t _texture_units[] = { - GLITZ_GL_TEXTURE0, - GLITZ_GL_TEXTURE1, - GLITZ_GL_TEXTURE2 +static glitz_gl_uint_t _texture_units[] = { + GLITZ_GL_TEXTURE0, + GLITZ_GL_TEXTURE1, + GLITZ_GL_TEXTURE2 }; typedef struct _glitz_texture_unit_t { glitz_texture_t *texture; glitz_gl_uint_t unit; - glitz_bool_t transform; + glitz_bool_t transform; } glitz_texture_unit_t; void @@ -52,456 +46,598 @@ 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) + int x_src, + int y_src, + int x_mask, + int y_mask, + int x_dst, + int y_dst, + int width, + int height) { - glitz_composite_op_t comp_op; - int i, passes, texture_nr = -1; - glitz_texture_t *stexture, *mtexture; - glitz_texture_unit_t textures[3]; - glitz_color_t alpha_mask; - 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; - - 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); - return; - } - - src = comp_op.src; - mask = comp_op.mask; - - if (src) { - stexture = glitz_surface_get_texture (src, 0); - if (!stexture) - return; - } else - stexture = NULL; - - if (mask) { - mtexture = glitz_surface_get_texture (mask, 0); - if (!mtexture) - return; - } else - mtexture = NULL; - - 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; - } - - rect.x1 = x_dst; - rect.y1 = y_dst; - rect.x2 = rect.x1 + width; - rect.y2 = rect.y1 + height; - - if (mtexture) { - textures[0].texture = mtexture; - textures[0].unit = _texture_units[0]; - textures[0].transform = 0; - texture_nr = 0; - - glitz_texture_bind (gl, mtexture); - - glitz_texture_set_tex_gen (gl, - mtexture, - rect.x1 - x_mask, - rect.y1 - y_mask, - mask->flags); - - if (mask->transform) { - textures[0].transform = 1; - gl->matrix_mode (GLITZ_GL_TEXTURE); - gl->load_matrix_f (SURFACE_EYE_COORDS (mask)? - mask->transform->m: mask->transform->t); - gl->matrix_mode (GLITZ_GL_MODELVIEW); - - if (SURFACE_LINEAR_TRANSFORM_FILTER (mask)) - glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_LINEAR); - else - glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_NEAREST); - } else - glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_NEAREST); + glitz_composite_op_t comp_op; + int i, texture_nr = -1; + glitz_texture_t *stexture, *mtexture; + glitz_texture_unit_t textures[3]; + glitz_box_t bounds; + glitz_bool_t no_border_clamp; + unsigned long flags; + + GLITZ_GL_SURFACE (dst); + + bounds.x1 = MAX (x_dst, 0); + bounds.y1 = MAX (y_dst, 0); + bounds.x2 = x_dst + width; + bounds.y2 = y_dst + height; - if (SURFACE_REPEAT (mask)) { - if (SURFACE_MIRRORED (mask)) - glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_MIRRORED_REPEAT); - else - glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_REPEAT); - } else { - 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); - else - glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_CLAMP_TO_BORDER); - } - } - - if (stexture) { - int last_texture_nr = comp_op.combine->texture_units - 1; - - while (texture_nr < last_texture_nr) { - textures[++texture_nr].texture = stexture; - textures[texture_nr].unit = _texture_units[texture_nr]; - textures[texture_nr].transform = 0; - if (texture_nr > 0) - gl->active_texture (textures[texture_nr].unit); - glitz_texture_bind (gl, stexture); - } + if (bounds.x2 > dst->box.x2) + bounds.x2 = dst->box.x2; + if (bounds.y2 > dst->box.y2) + bounds.y2 = dst->box.y2; - glitz_texture_set_tex_gen (gl, - stexture, - rect.x1 - x_src, - rect.y1 - y_src, - src->flags); - - if (src->transform) { - textures[texture_nr].transform = 1; - gl->matrix_mode (GLITZ_GL_TEXTURE); - 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 - glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_NEAREST); - } else - glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_NEAREST); - - if (SURFACE_REPEAT (src)) { - if (SURFACE_MIRRORED (src)) - glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_MIRRORED_REPEAT); - else - glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_REPEAT); - } else { - 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); - else - glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_CLAMP_TO_BORDER); - } - } - - gl->scissor (rect.x1 + dst->x, - dst->attached->height - dst->y - rect.y2, - width, height); + if (bounds.x1 >= bounds.x2 || bounds.y1 >= bounds.y2) + return; - gl->push_matrix (); + if (dst->geometry.buffer && (!dst->geometry.count)) + return; + + 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); + return; + } - glitz_geometry_enable (gl, dst, &primitive, &first, &count, &rect); + src = comp_op.src; + mask = comp_op.mask; - if (dst->indirect) { - glitz_sample_offset_t *offsets; + if (src) + { + stexture = glitz_surface_get_texture (src, 0); + if (!stexture) + return; + } else + stexture = NULL; - passes = dst->indirect->n_samples; - offsets = dst->indirect->offsets; + if (mask) + { + mtexture = glitz_surface_get_texture (mask, 0); + if (!mtexture) + return; + } else + mtexture = NULL; - gl->enable (GLITZ_GL_STENCIL_TEST); - gl->disable (GLITZ_GL_BLEND); - gl->color_mask (GLITZ_GL_FALSE, GLITZ_GL_FALSE, GLITZ_GL_FALSE, - GLITZ_GL_FALSE); - gl->clear_stencil (0); - gl->clear (GLITZ_GL_STENCIL_BUFFER_BIT); - gl->stencil_func (GLITZ_GL_ALWAYS, ~0, ~0); - gl->stencil_op (GLITZ_GL_KEEP, GLITZ_GL_INCR, GLITZ_GL_INCR); - - for (i = 0; i < passes; i++) { - gl->push_matrix (); - gl->translate_f (offsets[i].x, offsets[i].y, 0.0f); - gl->draw_arrays (primitive, first, count); - gl->pop_matrix (); + 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; } - - gl->pop_matrix (); - gl->push_matrix (); - - gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE, - GLITZ_GL_TRUE); - - glitz_geometry_disable (gl, dst); - glitz_geometry_enable_default (gl, dst, &rect); - primitive = GLITZ_GL_QUADS; - first = 0; - count = 4; - } else - passes = 1; - - if (comp_op.per_component) - passes *= comp_op.per_component; - - alpha_mask = comp_op.alpha_mask; - - for (i = 0; i < passes; i++) { - unsigned short weight, sample; + no_border_clamp = !(dst->drawable->backend->feature_mask & + GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK); + + if (mtexture) + { + textures[0].texture = mtexture; + textures[0].unit = _texture_units[0]; + textures[0].transform = 0; + texture_nr = 0; + + glitz_texture_bind (gl, mtexture); + + flags = mask->flags | GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK; + if (dst->geometry.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) + { + flags &= ~GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK; + + if (dst->geometry.u.v.mask.size == 2) + flags &= ~GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK; + } + + glitz_texture_set_tex_gen (gl, + mtexture, + &dst->geometry, + x_dst - x_mask, + y_dst - y_mask, + flags, + &dst->geometry.u.v.mask); - if (dst->indirect) { - if (comp_op.per_component) - sample = i / comp_op.per_component; - else - sample = i; - - weight = dst->indirect->weights[sample]; + if (mask->transform) + { + textures[0].transform = 1; + gl->matrix_mode (GLITZ_GL_TEXTURE); + gl->load_matrix_f (SURFACE_EYE_COORDS (mask)? + mask->transform->m: mask->transform->t); + gl->matrix_mode (GLITZ_GL_MODELVIEW); - gl->stencil_func (GLITZ_GL_EQUAL, sample + 1, ~0); - gl->stencil_op (GLITZ_GL_KEEP, GLITZ_GL_KEEP, GLITZ_GL_KEEP); - } else - weight = 0xffff; + if (SURFACE_LINEAR_TRANSFORM_FILTER (mask)) + glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_LINEAR); + else + glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_NEAREST); + } + else + { + if ((dst->geometry.attributes & + GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) && + SURFACE_LINEAR_TRANSFORM_FILTER (mask)) + glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_LINEAR); + else + glitz_texture_ensure_filter (gl, mtexture, GLITZ_GL_NEAREST); + } - if (comp_op.per_component) { - switch (i % comp_op.per_component) { - case 0: - SET_COLOR (comp_op.alpha_mask, - SHORT_MULT (weight, alpha_mask.red), 0, 0, 0); - gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_FALSE, GLITZ_GL_FALSE, - GLITZ_GL_FALSE); - break; - case 1: - SET_COLOR (comp_op.alpha_mask, - 0, 0, SHORT_MULT (weight, alpha_mask.blue), 0); - gl->color_mask (GLITZ_GL_FALSE, GLITZ_GL_FALSE, GLITZ_GL_TRUE, - GLITZ_GL_FALSE); - break; - case 2: - SET_COLOR (comp_op.alpha_mask, - 0, SHORT_MULT (weight, alpha_mask.green), 0, 0); - gl->color_mask (GLITZ_GL_FALSE, GLITZ_GL_TRUE, GLITZ_GL_FALSE, - GLITZ_GL_FALSE); - break; - case 3: - SET_COLOR (comp_op.alpha_mask, - 0, 0, 0, SHORT_MULT (weight, alpha_mask.alpha)); - gl->color_mask (GLITZ_GL_FALSE, GLITZ_GL_FALSE, GLITZ_GL_FALSE, - GLITZ_GL_TRUE); - break; - } - } else { - SET_COLOR (comp_op.alpha_mask, - SHORT_MULT (weight, alpha_mask.red), - SHORT_MULT (weight, alpha_mask.green), - SHORT_MULT (weight, alpha_mask.blue), - SHORT_MULT (weight, alpha_mask.alpha)); + if (SURFACE_REPEAT (mask)) + { + if (SURFACE_MIRRORED (mask)) + glitz_texture_ensure_wrap (gl, mtexture, + GLITZ_GL_MIRRORED_REPEAT); + else + glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_REPEAT); + } + else + { + if (no_border_clamp || SURFACE_PAD (mask)) + glitz_texture_ensure_wrap (gl, mtexture, + GLITZ_GL_CLAMP_TO_EDGE); + else + glitz_texture_ensure_wrap (gl, mtexture, + GLITZ_GL_CLAMP_TO_BORDER); + } } - - glitz_composite_enable (&comp_op); - gl->draw_arrays (primitive, first, count); - } - - glitz_geometry_disable (gl, dst); - - gl->pop_matrix (); - - if (dst->indirect) - gl->disable (GLITZ_GL_STENCIL_TEST); - - if (comp_op.per_component) - gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE, - GLITZ_GL_TRUE); - - glitz_composite_disable (&comp_op); - - for (i = texture_nr; i >= 0; i--) { - glitz_texture_unbind (gl, textures[i].texture); - if (textures[i].transform) { - gl->matrix_mode (GLITZ_GL_TEXTURE); - gl->load_identity (); - gl->matrix_mode (GLITZ_GL_MODELVIEW); + if (stexture) + { + int last_texture_nr = comp_op.combine->texture_units - 1; + + while (texture_nr < last_texture_nr) + { + textures[++texture_nr].texture = stexture; + textures[texture_nr].unit = _texture_units[texture_nr]; + textures[texture_nr].transform = 0; + if (texture_nr > 0) + { + gl->active_texture (textures[texture_nr].unit); + gl->client_active_texture (textures[texture_nr].unit); + } + glitz_texture_bind (gl, stexture); + } + + flags = src->flags | GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK; + if (dst->geometry.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) + { + flags &= ~GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK; + + if (dst->geometry.u.v.src.size == 2) + flags &= ~GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK; + } + + glitz_texture_set_tex_gen (gl, + stexture, + &dst->geometry, + x_dst - x_src, + y_dst - y_src, + flags, + &dst->geometry.u.v.src); + + if (src->transform) + { + textures[texture_nr].transform = 1; + gl->matrix_mode (GLITZ_GL_TEXTURE); + 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 + glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_NEAREST); + } + else + { + if ((dst->geometry.attributes & + GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) && + SURFACE_LINEAR_TRANSFORM_FILTER (src)) + glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_LINEAR); + else + glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_NEAREST); + } + + if (SURFACE_REPEAT (src)) + { + if (SURFACE_MIRRORED (src)) + glitz_texture_ensure_wrap (gl, stexture, + GLITZ_GL_MIRRORED_REPEAT); + else + glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_REPEAT); + } + else + { + if (no_border_clamp || SURFACE_PAD (src)) + glitz_texture_ensure_wrap (gl, stexture, + GLITZ_GL_CLAMP_TO_EDGE); + else + glitz_texture_ensure_wrap (gl, stexture, + GLITZ_GL_CLAMP_TO_BORDER); + } } - if (i > 0) - gl->active_texture (textures[i - 1].unit); - } - - glitz_surface_damage (dst, &rect, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_SOLID_MASK); + glitz_geometry_enable (gl, dst, &bounds); + + if (comp_op.per_component) + { + static unsigned short alpha_map[4][4] = { + { 0, 0, 0, 1 }, + { 0, 0, 1, 0 }, + { 0, 1, 0, 0 }, + { 1, 0, 0, 0 } + }; + static int damage[4] = { + GLITZ_DAMAGE_TEXTURE_MASK | GLITZ_DAMAGE_SOLID_MASK, + 0, + 0, + 0 + }; + glitz_color_t alpha = comp_op.alpha_mask; + int component = 4; + int cmask = 1; + + while (component--) + { + comp_op.alpha_mask.red = alpha_map[component][0] * alpha.red; + comp_op.alpha_mask.green = alpha_map[component][1] * alpha.green; + comp_op.alpha_mask.blue = alpha_map[component][2] * alpha.blue; + comp_op.alpha_mask.alpha = alpha_map[component][3] * alpha.alpha; + + gl->color_mask ((cmask & 1) , + (cmask & 2) >> 1, + (cmask & 4) >> 2, + (cmask & 8) >> 3); + + glitz_composite_enable (&comp_op); + glitz_geometry_draw_arrays (gl, dst, + dst->geometry.type, &bounds, + damage[component]); + cmask <<= 1; + } + + gl->color_mask (1, 1, 1, 1); + } + else + { + glitz_composite_enable (&comp_op); + glitz_geometry_draw_arrays (gl, dst, dst->geometry.type, &bounds, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + glitz_composite_disable (&comp_op); + glitz_geometry_disable (dst); + + for (i = texture_nr; i >= 0; i--) + { + glitz_texture_unbind (gl, textures[i].texture); + if (textures[i].transform) + { + gl->matrix_mode (GLITZ_GL_TEXTURE); + gl->load_identity (); + gl->matrix_mode (GLITZ_GL_MODELVIEW); + } + + if (i > 0) + { + gl->client_active_texture (textures[i - 1].unit); + gl->active_texture (textures[i - 1].unit); + } + } - glitz_surface_pop_current (dst); + glitz_surface_pop_current (dst); } 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) { - glitz_status_t status; + glitz_status_t status; + glitz_box_t bounds; + int src_width = src->box.x2; + int src_height = src->box.y2; - GLITZ_GL_SURFACE (dst); - - if (x_src < 0) { - x_dst -= x_src; - width += x_src; - x_src = 0; - } - - if (y_src < 0) { - y_dst -= y_src; - height += y_src; - y_src = 0; - } - - width = MIN (src->width - x_src, width); - height = MIN (src->height - y_src, height); - - if (x_dst < 0) { - x_src -= x_dst; - width += x_dst; - x_dst = 0; - } - - if (y_dst < 0) { - y_src -= y_dst; - height += y_dst; - y_dst = 0; - } - - width = MIN (dst->width - x_dst, width); - height = MIN (dst->height - y_dst, height); - - if (width <= 0 || height <= 0) - return; + GLITZ_GL_SURFACE (dst); - status = GLITZ_STATUS_NOT_SUPPORTED; - if (glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) { - glitz_box_t box; + if (x_src < 0) + { + bounds.x1 = x_dst - x_src; + width += x_src; + } + else + { + bounds.x1 = x_dst; + src_width -= x_src; + } + + if (y_src < 0) + { + bounds.y1 = y_dst - y_src; + height += y_src; + } + else + { + bounds.y1 = y_dst; + src_height -= y_src; + } - 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); - - box.x1 = x_dst; - box.y1 = y_dst; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - - if (!status) { - gl->read_buffer (src->buffer); - gl->draw_buffer (dst->buffer); - - glitz_set_operator (gl, GLITZ_OPERATOR_SRC); + if (width > src_width) + bounds.x2 = bounds.x1 + src_width; + else + bounds.x2 = bounds.x1 + width; + + if (height > src_height) + bounds.y2 = bounds.y1 + src_height; + else + bounds.y2 = bounds.y1 + height; + + if (bounds.x1 < 0) + bounds.x1 = 0; + if (bounds.y1 < 0) + bounds.y1 = 0; + if (bounds.x2 > dst->box.x2) + bounds.x2 = dst->box.x2; + if (bounds.y2 > dst->box.y2) + bounds.y2 = dst->box.y2; + + if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1) + return; + + status = GLITZ_STATUS_NOT_SUPPORTED; + if (glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) + { + 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); + + if (!status) + { + glitz_box_t box, *clip = dst->clip; + int n_clip = dst->n_clip; + + gl->read_buffer (src->buffer); + gl->draw_buffer (dst->buffer); - gl->disable (GLITZ_GL_SCISSOR_TEST); + glitz_set_operator (gl, GLITZ_OPERATOR_SRC); - 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; - - texture = glitz_surface_get_texture (src, 0); - if (texture) { - glitz_texture_bind (gl, texture); - - glitz_texture_set_tex_gen (gl, texture, - x_dst - x_src, - y_dst - y_src, - 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->x, - dst->attached->height - dst->y - box.y2, - width, height); - - glitz_geometry_enable_default (gl, dst, &box); + gl->disable (GLITZ_GL_SCISSOR_TEST); + + x_src += src->x; + y_src += src->y; + + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds.x1 > box.x1) + box.x1 = bounds.x1; + if (bounds.y1 > box.y1) + box.y1 = bounds.y1; + if (bounds.x2 < box.x2) + box.x2 = bounds.x2; + if (bounds.y2 < box.y2) + box.y2 = bounds.y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + glitz_set_raster_pos (gl, + dst->x + box.x1, + dst->attached->height - + (dst->y + box.y2)); + + gl->copy_pixels (x_src + (box.x1 - x_dst), + src->attached->height - + (y_src + (box.y2 - y_dst)), + box.x2 - box.x1, box.y2 - box.y1, + GLITZ_GL_COLOR); + + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + clip++; + } + + gl->enable (GLITZ_GL_SCISSOR_TEST); + } + else + { + glitz_texture_t *texture; + + texture = glitz_surface_get_texture (src, 0); + if (texture) + { + glitz_texture_bind (gl, texture); + + glitz_texture_set_tex_gen (gl, texture, NULL, + x_dst - x_src, + y_dst - y_src, + GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK, + NULL); + + gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, + GLITZ_GL_REPLACE); + gl->color_4us (0x0, 0x0, 0x0, 0xffff); - gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); + 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); + + if (dst->n_clip > 1) + { + glitz_float_t *data; + void *ptr; + int vertices = 0; + glitz_box_t box, *clip = dst->clip; + int n_clip = dst->n_clip; + + ptr = malloc (n_clip * 8 * sizeof (glitz_float_t)); + if (!ptr) { + glitz_surface_pop_current (dst); + glitz_surface_status_add (dst, + GLITZ_STATUS_NO_MEMORY_MASK); + return; + } + + data = (glitz_float_t *) ptr; + + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds.x1 > box.x1) + box.x1 = bounds.x1; + if (bounds.y1 > box.y1) + box.y1 = bounds.y1; + if (bounds.x2 < box.x2) + box.x2 = bounds.x2; + if (bounds.y2 < box.y2) + box.y2 = bounds.y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + *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; + + vertices += 4; + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + clip++; + } + + if (vertices) + { + gl->scissor (bounds.x1 + dst->x, + dst->attached->height - dst->y - + bounds.y2, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + + gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr); + gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices); + } + + free (ptr); + } + else + { + glitz_geometry_enable_none (gl, dst, &bounds); + glitz_geometry_draw_arrays (gl, dst, + GLITZ_GEOMETRY_TYPE_NONE, + &bounds, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + glitz_texture_unbind (gl, texture); + } + } - glitz_texture_unbind (gl, texture); - } + status = GLITZ_STATUS_SUCCESS; } - - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_SOLID_MASK); - - status = GLITZ_STATUS_SUCCESS; - } - - glitz_surface_pop_current (dst); - - if (status) { - if (glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT)) { - glitz_texture_t *texture; - gl->read_buffer (src->buffer); - - texture = glitz_surface_get_texture (dst, 1); - if (texture) { - 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_pop_current (dst); - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_DRAWABLE_MASK | - GLITZ_DAMAGE_SOLID_MASK); + if (status) + { + if (glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT)) + { + glitz_texture_t *texture; + + gl->read_buffer (src->buffer); + + texture = glitz_surface_get_texture (dst, 1); + if (texture) + { + glitz_box_t box, *clip = dst->clip; + int n_clip = dst->n_clip; + + gl->disable (GLITZ_GL_SCISSOR_TEST); + + glitz_texture_bind (gl, texture); + + x_src += src->x; + y_src += src->y; + + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds.x1 > box.x1) + box.x1 = bounds.x1; + if (bounds.y1 > box.y1) + box.y1 = bounds.y1; + if (bounds.x2 < box.x2) + box.x2 = bounds.x2; + if (bounds.y2 < box.y2) + box.y2 = bounds.y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + glitz_texture_copy_drawable (gl, + texture, + src->attached, + x_src + (box.x1 - x_dst), + y_src + (box.y1 - y_dst), + box.x2 - box.x1, + box.y2 - box.y1, + box.x1, + box.y1); + + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_DRAWABLE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + + clip++; + } + + glitz_texture_unbind (gl, texture); + + gl->enable (GLITZ_GL_SCISSOR_TEST); - status = GLITZ_STATUS_SUCCESS; - } + status = GLITZ_STATUS_SUCCESS; + } + } + glitz_surface_pop_current (src); } - glitz_surface_pop_current (src); - } - if (status) - glitz_surface_status_add (dst, glitz_status_to_status_mask (status)); + if (status) + glitz_surface_status_add (dst, glitz_status_to_status_mask (status)); } diff --git a/src/glitz.h b/src/glitz.h index 1425125..36c1233 100644 --- a/src/glitz.h +++ b/src/glitz.h @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifndef GLITZ_H_INCLUDED @@ -37,7 +37,7 @@ #endif #define GLITZ_MAJOR 0 -#define GLITZ_MINOR 3 +#define GLITZ_MINOR 4 #define GLITZ_REVISION 0 #if defined(__cplusplus) || defined(c_plusplus) @@ -56,6 +56,33 @@ typedef struct _glitz_rectangle_t { unsigned short width, height; } glitz_rectangle_t; +typedef struct _glitz_box_t { + short x1, y1, x2, y2; +} glitz_box_t; + +typedef struct _glitz_point_fixed_t { + glitz_fixed16_16_t x; + glitz_fixed16_16_t y; +} glitz_point_fixed_t; + +typedef struct _glitz_line_fixed_t { + glitz_point_fixed_t p1; + glitz_point_fixed_t p2; +} glitz_line_fixed_t; + +typedef struct _glitz_trapezoid_t { + glitz_fixed16_16_t top, bottom; + glitz_line_fixed_t left, right; +} glitz_trapezoid_t; + +typedef struct _glitz_span_fixed_t { + glitz_fixed16_16_t left, right, y; +} glitz_span_fixed_t; + +typedef struct _glitz_trap_t { + glitz_span_fixed_t top, bottom; +} glitz_trap_t; + typedef struct _glitz_transform_t { glitz_fixed16_16_t matrix[3][3]; } glitz_transform_t; @@ -107,6 +134,7 @@ typedef enum { #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) +#define GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK (1L << 15) typedef enum { GLITZ_STANDARD_ARGB32, @@ -176,14 +204,6 @@ typedef struct _glitz_drawable_format_t { 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, @@ -191,10 +211,10 @@ glitz_find_similar_drawable_format (glitz_drawable_t *other, 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); +glitz_create_pbuffer_drawable (glitz_drawable_t *other, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); void glitz_drawable_destroy (glitz_drawable_t *drawable); @@ -257,12 +277,20 @@ glitz_find_format (glitz_drawable_t *drawable, /* glitz_surface.c */ typedef struct _glitz_surface glitz_surface_t; + +#define GLITZ_SURFACE_UNNORMALIZED_MASK (1L << 0) + +typedef struct _glitz_surface_attributes_t { + glitz_bool_t unnormalized; +} glitz_surface_attributes_t; glitz_surface_t * -glitz_surface_create (glitz_drawable_t *drawable, - glitz_format_t *format, - unsigned int width, - unsigned int height); +glitz_surface_create (glitz_drawable_t *drawable, + glitz_format_t *format, + unsigned int width, + unsigned int height, + unsigned long mask, + glitz_surface_attributes_t *attributes); void glitz_surface_destroy (glitz_surface_t *surface); @@ -330,6 +358,18 @@ glitz_surface_get_status (glitz_surface_t *surface); glitz_format_t * glitz_surface_get_format (glitz_surface_t *surface); +void +glitz_surface_translate_point (glitz_surface_t *surface, + glitz_point_fixed_t *src, + glitz_point_fixed_t *dst); + +void +glitz_surface_set_clip_region (glitz_surface_t *surface, + int x_origin, + int y_origin, + glitz_box_t *box, + int n_box); + /* glitz_rect.c */ @@ -371,10 +411,10 @@ typedef enum { } glitz_buffer_access_t; glitz_buffer_t * -glitz_geometry_buffer_create (glitz_drawable_t *drawable, - void *data, - unsigned int size, - glitz_buffer_hint_t hint); +glitz_vertex_buffer_create (glitz_drawable_t *drawable, + void *data, + unsigned int size, + glitz_buffer_hint_t hint); glitz_buffer_t * glitz_pixel_buffer_create (glitz_drawable_t *drawable, @@ -456,30 +496,18 @@ glitz_get_pixels (glitz_surface_t *src, /* glitz_geometry.c */ typedef enum { - GLITZ_GEOMETRY_MODE_DIRECT, - GLITZ_GEOMETRY_MODE_INDIRECT -} glitz_geometry_mode_t; - -typedef enum { - GLITZ_GEOMETRY_EDGE_HINT_SHARP, - GLITZ_GEOMETRY_EDGE_HINT_FAST_SMOOTH, - GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH, - GLITZ_GEOMETRY_EDGE_HINT_BEST_SMOOTH -} glitz_geometry_edge_hint_t; + GLITZ_PRIMITIVE_POINTS, + GLITZ_PRIMITIVE_LINES, + GLITZ_PRIMITIVE_LINE_STRIP, + GLITZ_PRIMITIVE_LINE_LOOP, + GLITZ_PRIMITIVE_TRIANGLES, + GLITZ_PRIMITIVE_TRIANGLE_STRIP, + GLITZ_PRIMITIVE_TRIANGLE_FAN, + GLITZ_PRIMITIVE_QUADS, + GLITZ_PRIMITIVE_QUAD_STRIP, + GLITZ_PRIMITIVE_POLYGON +} glitz_primitive_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, - GLITZ_GEOMETRY_PRIMITIVE_QUADS, - GLITZ_GEOMETRY_PRIMITIVE_QUAD_STRIP, - GLITZ_GEOMETRY_PRIMITIVE_POLYGON -} glitz_geometry_primitive_t; - typedef enum { GLITZ_DATA_TYPE_SHORT, GLITZ_DATA_TYPE_INT, @@ -487,22 +515,111 @@ typedef enum { GLITZ_DATA_TYPE_DOUBLE } glitz_data_type_t; -typedef struct _glitz_geometry_format { - 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; +typedef enum { + GLITZ_COORDINATE_SIZE_X, + GLITZ_COORDINATE_SIZE_XY +} glitz_coordinate_size_t; + +typedef struct _glitz_coordinate_attribute { + glitz_data_type_t type; + glitz_coordinate_size_t size; + int offset; +} glitz_coordinate_attribute_t; + +#define GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK (1L << 0) +#define GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK (1L << 1) + +typedef struct _glitz_vertex_format { + glitz_primitive_t primitive; + glitz_data_type_t type; + unsigned int bytes_per_vertex; + unsigned long attributes; + glitz_coordinate_attribute_t src; + glitz_coordinate_attribute_t mask; +} glitz_vertex_format_t; + +typedef struct _glitz_bitmap_format { + glitz_pixel_scanline_order_t scanline_order; + unsigned int bytes_per_line; + int pad; +} glitz_bitmap_format_t; + +typedef enum { + GLITZ_GEOMETRY_TYPE_NONE, + GLITZ_GEOMETRY_TYPE_VERTEX, + GLITZ_GEOMETRY_TYPE_BITMAP +} glitz_geometry_type_t; + +typedef union _glitz_geometry_format { + glitz_vertex_format_t vertex; + glitz_bitmap_format_t bitmap; } glitz_geometry_format_t; void glitz_set_geometry (glitz_surface_t *dst, - glitz_fixed16_16_t x_dst, - glitz_fixed16_16_t y_dst, + glitz_geometry_type_t type, glitz_geometry_format_t *format, glitz_buffer_t *buffer); - + +void +glitz_set_array (glitz_surface_t *dst, + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off); + +typedef struct _glitz_multi_array glitz_multi_array_t; + +glitz_multi_array_t * +glitz_multi_array_create (unsigned int size); + +void +glitz_multi_array_destroy (glitz_multi_array_t *array); + +void +glitz_multi_array_reference (glitz_multi_array_t *array); + +void +glitz_multi_array_add (glitz_multi_array_t *array, + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off); + +void +glitz_multi_array_reset (glitz_multi_array_t *array); + +void +glitz_set_multi_array (glitz_surface_t *dst, + glitz_multi_array_t *array, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off); + + +/* glitz_trap.c */ + +int +glitz_add_trapezoids (glitz_buffer_t *buffer, + int offset, + unsigned int size, + glitz_data_type_t type, + glitz_surface_t *mask, + glitz_trapezoid_t *traps, + int n_traps, + int *n_added); + +int +glitz_add_traps (glitz_buffer_t *buffer, + int offset, + unsigned int size, + glitz_data_type_t type, + glitz_surface_t *mask, + glitz_trap_t *traps, + int n_traps, + int *n_added); + /* glitz.c */ diff --git a/src/glitz_buffer.c b/src/glitz_buffer.c index 1c5069a..df0561b 100644 --- a/src/glitz_buffer.c +++ b/src/glitz_buffer.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -36,84 +36,92 @@ _glitz_buffer_init (glitz_buffer_t *buffer, 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; - break; - case GLITZ_BUFFER_HINT_STREAM_READ: - usage = GLITZ_GL_STREAM_READ; - break; - case GLITZ_BUFFER_HINT_STREAM_COPY: - usage = GLITZ_GL_STREAM_COPY; - break; - case GLITZ_BUFFER_HINT_STATIC_DRAW: - usage = GLITZ_GL_STATIC_DRAW; - break; - case GLITZ_BUFFER_HINT_STATIC_READ: - usage = GLITZ_GL_STATIC_READ; - break; - case GLITZ_BUFFER_HINT_STATIC_COPY: - usage = GLITZ_GL_STATIC_COPY; - break; - case GLITZ_BUFFER_HINT_DYNAMIC_DRAW: - usage = GLITZ_GL_DYNAMIC_DRAW; - break; - case GLITZ_BUFFER_HINT_DYNAMIC_READ: - usage = GLITZ_GL_DYNAMIC_READ; - break; - default: - usage = GLITZ_GL_DYNAMIC_COPY; - break; - } - - if (drawable) { - - GLITZ_GL_DRAWABLE (drawable); + glitz_gl_enum_t usage; - buffer->drawable = drawable; - glitz_drawable_reference (drawable); - - drawable->backend->push_current (drawable, NULL, - GLITZ_ANY_CONTEXT_CURRENT); + buffer->ref_count = 1; + buffer->name = 0; - gl->gen_buffers (1, &buffer->name); - if (buffer->name) { - gl->bind_buffer (buffer->target, buffer->name); - gl->buffer_data (buffer->target, size, data, usage); - gl->bind_buffer (buffer->target, 0); + if (drawable) + { + GLITZ_GL_DRAWABLE (drawable); + + switch (hint) { + case GLITZ_BUFFER_HINT_STREAM_DRAW: + usage = GLITZ_GL_STREAM_DRAW; + break; + case GLITZ_BUFFER_HINT_STREAM_READ: + usage = GLITZ_GL_STREAM_READ; + break; + case GLITZ_BUFFER_HINT_STREAM_COPY: + usage = GLITZ_GL_STREAM_COPY; + break; + case GLITZ_BUFFER_HINT_STATIC_DRAW: + usage = GLITZ_GL_STATIC_DRAW; + break; + case GLITZ_BUFFER_HINT_STATIC_READ: + usage = GLITZ_GL_STATIC_READ; + break; + case GLITZ_BUFFER_HINT_STATIC_COPY: + usage = GLITZ_GL_STATIC_COPY; + break; + case GLITZ_BUFFER_HINT_DYNAMIC_DRAW: + usage = GLITZ_GL_DYNAMIC_DRAW; + break; + case GLITZ_BUFFER_HINT_DYNAMIC_READ: + usage = GLITZ_GL_DYNAMIC_READ; + break; + default: + usage = GLITZ_GL_DYNAMIC_COPY; + break; + } + + buffer->owns_data = 1; + buffer->drawable = drawable; + glitz_drawable_reference (drawable); + + drawable->backend->push_current (drawable, NULL, + GLITZ_ANY_CONTEXT_CURRENT); + + gl->gen_buffers (1, &buffer->name); + if (buffer->name) { + gl->bind_buffer (buffer->target, buffer->name); + gl->buffer_data (buffer->target, size, data, usage); + gl->bind_buffer (buffer->target, 0); + } + + drawable->backend->pop_current (drawable); + } + else + { + buffer->drawable = NULL; + usage = GLITZ_GL_DYNAMIC_COPY; } - drawable->backend->pop_current (drawable); - } else - buffer->drawable = NULL; - - if (size > 0 && buffer->name == 0) { - buffer->data = malloc (size); - if (buffer->data == NULL) - return GLITZ_STATUS_NO_MEMORY; - - if (data) - memcpy (buffer->data, data, size); - - buffer->owns_data = 1; - } else { - buffer->owns_data = 0; - buffer->data = data; - } + if (size > 0 && buffer->name == 0) + { + buffer->data = malloc (size); + if (buffer->data == NULL) + return GLITZ_STATUS_NO_MEMORY; + + if (data) + memcpy (buffer->data, data, size); + + buffer->owns_data = 1; + } + else + { + buffer->owns_data = 0; + buffer->data = data; + } - return GLITZ_STATUS_SUCCESS; + return GLITZ_STATUS_SUCCESS; } glitz_buffer_t * -glitz_geometry_buffer_create (glitz_drawable_t *drawable, - void *data, - unsigned int size, - glitz_buffer_hint_t hint) +glitz_vertex_buffer_create (glitz_drawable_t *drawable, + void *data, + unsigned int size, + glitz_buffer_hint_t hint) { glitz_buffer_t *buffer; glitz_status_t status; @@ -186,9 +194,6 @@ glitz_buffer_create_for_data (void *data) { glitz_buffer_t *buffer; - if (data == NULL) - return NULL; - buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t)); if (buffer == NULL) return NULL; @@ -226,7 +231,7 @@ glitz_buffer_destroy (glitz_buffer_t *buffer) void glitz_buffer_reference (glitz_buffer_t *buffer) { - if (buffer == NULL) + if (!buffer) return; buffer->ref_count++; diff --git a/src/glitz_compose.c b/src/glitz_compose.c index 6bdc7dd..b822ebd 100644 --- a/src/glitz_compose.c +++ b/src/glitz_compose.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -53,7 +53,7 @@ _glitz_combine_argb_argb (glitz_composite_op_t *op) GLITZ_GL_SRC_COLOR); op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB, GLITZ_GL_SRC_ALPHA); - + op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA, GLITZ_GL_MODULATE); op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA, @@ -143,6 +143,18 @@ _glitz_combine_argb_argbc (glitz_composite_op_t *op) } } +static void +_glitz_combine_argb_argbf (glitz_composite_op_t *op) +{ + glitz_set_operator (op->gl, op->render_op); + glitz_filter_enable (op->mask, op); + + op->gl->color_4us (op->alpha_mask.red, + op->alpha_mask.green, + op->alpha_mask.blue, + op->alpha_mask.alpha); +} + static void _glitz_combine_argb_solid (glitz_composite_op_t *op) { @@ -314,6 +326,18 @@ _glitz_combine_solid_argbc (glitz_composite_op_t *op) solid.alpha); } +static void +_glitz_combine_solid_argbf (glitz_composite_op_t *op) +{ + glitz_set_operator (op->gl, op->render_op); + glitz_filter_enable (op->mask, op); + + op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha), + SHORT_MULT (op->solid->green, op->alpha_mask.alpha), + SHORT_MULT (op->solid->blue, op->alpha_mask.alpha), + SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha)); +} + /* This only works with the OVER operator. */ static void _glitz_combine_solid_solidc (glitz_composite_op_t *op) @@ -350,14 +374,14 @@ _glitz_combine_map[GLITZ_SURFACE_TYPES][GLITZ_SURFACE_TYPES] = { { GLITZ_COMBINE_TYPE_ARGB, _glitz_combine_argb_solid, 1, 0 }, { GLITZ_COMBINE_TYPE_ARGB_ARGB, _glitz_combine_argb_argb, 2, 0 }, { GLITZ_COMBINE_TYPE_ARGB_ARGBC, _glitz_combine_argb_argbc, 3, 0 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_ARGBF, _glitz_combine_argb_argbf, 2, 2 }, { GLITZ_COMBINE_TYPE_ARGB_SOLID, _glitz_combine_argb_solid, 1, 0 }, { GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 } }, { { GLITZ_COMBINE_TYPE_ARGB, _glitz_combine_argb_solid, 1, 0 }, { GLITZ_COMBINE_TYPE_ARGB_ARGB, _glitz_combine_argb_argb, 2, 0 }, { GLITZ_COMBINE_TYPE_ARGB_ARGBC, _glitz_combine_argb_argbc, 3, 0 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_ARGB_ARGBF, _glitz_combine_argb_argbf, 2, 2 }, { GLITZ_COMBINE_TYPE_ARGB_SOLID, _glitz_combine_argb_solid, 1, 0 }, { GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 } }, { @@ -371,14 +395,14 @@ _glitz_combine_map[GLITZ_SURFACE_TYPES][GLITZ_SURFACE_TYPES] = { { GLITZ_COMBINE_TYPE_SOLID, _glitz_combine_solid_solid, 0, 0 }, { GLITZ_COMBINE_TYPE_SOLID_ARGB, _glitz_combine_solid_argb, 1, 0 }, { GLITZ_COMBINE_TYPE_SOLID_ARGBC, _glitz_combine_solid_argbc, 1, 0 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_ARGBF, _glitz_combine_solid_argbf, 1, 2 }, { GLITZ_COMBINE_TYPE_SOLID_SOLID, _glitz_combine_solid_solid, 0, 0 }, { GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 } }, { { GLITZ_COMBINE_TYPE_SOLID, _glitz_combine_solid_solid, 0, 0 }, { GLITZ_COMBINE_TYPE_SOLID_ARGB, _glitz_combine_solid_argb, 1, 0 }, { GLITZ_COMBINE_TYPE_SOLID_ARGBC, _glitz_combine_solid_argbc, 1, 0 }, - { GLITZ_COMBINE_TYPE_NA, NULL, 0, 0 }, + { GLITZ_COMBINE_TYPE_SOLID_ARGBF, _glitz_combine_solid_argbf, 1, 2 }, { GLITZ_COMBINE_TYPE_SOLID_SOLID, _glitz_combine_solid_solid, 0, 0 }, { GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 } } @@ -466,9 +490,6 @@ glitz_composite_op_init (glitz_composite_op_t *op, feature_mask = dst->attached->backend->feature_mask; - if (dst->indirect && (dst->attached->format->stencil_size < 1)) - return; - src_type = _glitz_get_surface_type (src, feature_mask); if (src_type < 1) return; @@ -494,6 +515,15 @@ glitz_composite_op_init (glitz_composite_op_t *op, if (!combine->type) return; + if (dst->geometry.type == GLITZ_GEOMETRY_TYPE_BITMAP) + { + /* We can't do anything but solid colors with bitmaps yet. */ + if (src_type != GLITZ_SURFACE_TYPE_SOLID || + (mask_type != GLITZ_SURFACE_TYPE_NULL && + mask_type != GLITZ_SURFACE_TYPE_SOLID)) + return; + } + if (src_type == GLITZ_SURFACE_TYPE_SOLID) { if (SURFACE_SOLID_DAMAGE (src)) { glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT); @@ -523,17 +553,20 @@ glitz_composite_op_init (glitz_composite_op_t *op, op->mask = NULL; if (op->src) { - op->per_component = 4; - op->combine = combine; + op->per_component = 4; + op->combine = combine; } 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 (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) - op->combine = combine; + /* we can't do component alpha with alpha only surfaces */ + if (op->src->format->color.red_size) { + op->per_component = 4; + if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) + op->combine = combine; + } } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) op->combine = combine; } else if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) @@ -552,8 +585,11 @@ glitz_composite_op_init (glitz_composite_op_t *op, if (op->combine == combine) { op->type = combine->type; - if (combine->fragment_processing) { - op->fp = glitz_filter_get_fragment_program (src, op); + if (combine->source_shader) { + if (combine->source_shader == 1) + op->fp = glitz_filter_get_fragment_program (src, op); + else + op->fp = glitz_filter_get_fragment_program (mask, op); if (op->fp == 0) op->type = GLITZ_COMBINE_TYPE_NA; } diff --git a/src/glitz_drawable.c b/src/glitz_drawable.c index f39b136..f8431e4 100644 --- a/src/glitz_drawable.c +++ b/src/glitz_drawable.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -42,15 +42,15 @@ glitz_find_similar_drawable_format (glitz_drawable_t *other, 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) +glitz_create_pbuffer_drawable (glitz_drawable_t *other, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { if (!format->types.pbuffer) return NULL; - return other->backend->create_pbuffer (other, format, attributes, mask); + return other->backend->create_pbuffer (other, format, width, height); } slim_hidden_def(glitz_create_pbuffer_drawable); @@ -70,7 +70,7 @@ glitz_drawable_destroy (glitz_drawable_t *drawable) void glitz_drawable_reference (glitz_drawable_t *drawable) { - if (drawable == NULL) + if (!drawable) return; drawable->ref_count++; diff --git a/src/glitz_filter.c b/src/glitz_filter.c index 77b1d6c..81f7ff3 100644 --- a/src/glitz_filter.c +++ b/src/glitz_filter.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -29,36 +29,39 @@ #include "glitzint.h" -#include - struct _glitz_filter_params_t { - int fp_type; - int id; + int fp_type; + int id; glitz_vec4_t *vectors; - int n_vectors; + int n_vectors; }; -static int -_glitz_filter_params_ensure (glitz_filter_params_t **params, int vectors) +static glitz_status_t +_glitz_filter_params_ensure (glitz_surface_t *surface, + int vectors) { - if (*params == NULL) { - *params = calloc (1, sizeof (glitz_filter_params_t)); - if (*params == NULL) - return 1; - } - - if ((*params)->n_vectors != vectors) { - (*params)->vectors = - realloc ((*params)->vectors, vectors * sizeof (glitz_vec4_t)); - (*params)->n_vectors = vectors; - } - - if (vectors > 0 && (*params)->vectors == NULL) { - free (*params); - return 1; - } + int size; + + size = sizeof (glitz_filter_params_t) + vectors * sizeof (glitz_vec4_t); + + if (!surface->filter_params || + surface->filter_params->n_vectors != vectors) + { + if (surface->filter_params) + free (surface->filter_params); + + surface->filter_params = malloc (size); + if (surface->filter_params == NULL) + return GLITZ_STATUS_NO_MEMORY; + + surface->filter_params->fp_type = 0; + surface->filter_params->id = 0; + surface->filter_params->vectors = + (glitz_vec4_t *) (surface->filter_params + 1); + surface->filter_params->n_vectors = vectors; + } - return 0; + return GLITZ_STATUS_SUCCESS; } static void @@ -108,7 +111,7 @@ glitz_filter_set_params (glitz_surface_t *surface, n = dn; size = m * n; - if (_glitz_filter_params_ensure (&surface->filter_params, size)) + if (_glitz_filter_params_ensure (surface, size)) return GLITZ_STATUS_NO_MEMORY; vecs = surface->filter_params->vectors; @@ -167,7 +170,7 @@ glitz_filter_set_params (glitz_surface_t *surface, size = half_size * 2 + 1; xy_scale = 2.0f * radius / size; - if (_glitz_filter_params_ensure (&surface->filter_params, size * size)) + if (_glitz_filter_params_ensure (surface, size * size)) return GLITZ_STATUS_NO_MEMORY; vecs = surface->filter_params->vectors; @@ -208,42 +211,42 @@ glitz_filter_set_params (glitz_surface_t *surface, case GLITZ_FILTER_LINEAR_GRADIENT: case GLITZ_FILTER_RADIAL_GRADIENT: if (n_params <= 4) { - if (surface->width == 1) - size = surface->height; - else if (surface->height == 1) - size = surface->width; + if (surface->box.x2 == 1) + size = surface->box.y2; + else if (surface->box.y2 == 1) + size = surface->box.x2; } else size = (n_params - 2) / 3; if (size < 2) size = 2; - if (_glitz_filter_params_ensure (&surface->filter_params, size + 1)) + if (_glitz_filter_params_ensure (surface, size + 1)) return GLITZ_STATUS_NO_MEMORY; vecs = surface->filter_params->vectors; if (filter == GLITZ_FILTER_LINEAR_GRADIENT) { glitz_float_t length, angle, dh, dv; - glitz_point_t start, stop; + glitz_float_t start_x, start_y, stop_x, stop_y; - _glitz_filter_params_set (&start.x, 0.0f, ¶ms, &n_params); - _glitz_filter_params_set (&start.y, 0.0f, ¶ms, &n_params); - _glitz_filter_params_set (&stop.x, 1.0f, ¶ms, &n_params); - _glitz_filter_params_set (&stop.y, 0.0f, ¶ms, &n_params); + _glitz_filter_params_set (&start_x, 0.0f, ¶ms, &n_params); + _glitz_filter_params_set (&start_y, 0.0f, ¶ms, &n_params); + _glitz_filter_params_set (&stop_x, 1.0f, ¶ms, &n_params); + _glitz_filter_params_set (&stop_y, 0.0f, ¶ms, &n_params); - dh = stop.x - start.x; - dv = stop.y - start.y; + dh = stop_x - start_x; + dv = stop_y - start_y; - length = sqrt (dh * dh + dv * dv); + length = sqrtf (dh * dh + dv * dv); - angle = -atan2 (dv, dh); + angle = -atan2f (dv, dh); - vecs->v[2] = cos (angle); - vecs->v[3] = -sin (angle); + vecs->v[2] = cosf (angle); + vecs->v[3] = -sinf (angle); - vecs->v[0] = vecs->v[2] * start.x; - vecs->v[0] += vecs->v[3] * start.y; + vecs->v[0] = vecs->v[2] * start_x; + vecs->v[0] += vecs->v[3] * start_y; vecs->v[1] = (length)? 1.0f / length: 2147483647.0f; } else { @@ -270,16 +273,16 @@ glitz_filter_set_params (glitz_surface_t *surface, glitz_float_t x_default, y_default, o_default; o_default = i / (glitz_float_t) (size - 1); - x_default = (surface->width * i) / (glitz_float_t) size; - y_default = (surface->height * i) / (glitz_float_t) size; + x_default = (surface->box.x2 * i) / (glitz_float_t) size; + y_default = (surface->box.y2 * i) / (glitz_float_t) size; _glitz_filter_params_set (&vecs[i].v[2], o_default, ¶ms, &n_params); _glitz_filter_params_set (&vecs[i].v[0], x_default, ¶ms, &n_params); _glitz_filter_params_set (&vecs[i].v[1], y_default, ¶ms, &n_params); glitz_clamp_value (&vecs[i].v[2], 0.0f, 1.0f); - glitz_clamp_value (&vecs[i].v[0], 0.0f, surface->width - 1.0f); - glitz_clamp_value (&vecs[i].v[1], 0.0f, surface->height - 1.0f); + glitz_clamp_value (&vecs[i].v[0], 0.0f, surface->box.x2 - 1.0f); + glitz_clamp_value (&vecs[i].v[1], 0.0f, surface->box.y2 - 1.0f); vecs[i].v[0] += 0.5f; vecs[i].v[1] += 0.5f; @@ -313,6 +316,10 @@ glitz_filter_set_params (glitz_surface_t *surface, break; case GLITZ_FILTER_BILINEAR: case GLITZ_FILTER_NEAREST: + if (surface->filter_params) + free (surface->filter_params); + + surface->filter_params = NULL; break; } @@ -321,15 +328,6 @@ glitz_filter_set_params (glitz_surface_t *surface, return GLITZ_STATUS_SUCCESS; } -void -glitz_filter_params_destroy (glitz_filter_params_t *params) -{ - if (params->vectors) - free (params->vectors); - - free (params); -} - glitz_gl_uint_t glitz_filter_get_fragment_program (glitz_surface_t *surface, glitz_composite_op_t *op) diff --git a/src/glitz_format.c b/src/glitz_format.c index fd40532..d359690 100644 --- a/src/glitz_format.c +++ b/src/glitz_format.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H diff --git a/src/glitz_geometry.c b/src/glitz_geometry.c index 733ccb6..1ac1108 100644 --- a/src/glitz_geometry.c +++ b/src/glitz_geometry.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -29,209 +29,289 @@ #include "glitzint.h" -/* This is supposed to be 8x, 4x and 2x rotated grid multi-sample - patterns. I'm not sure they're actually correct. */ -static glitz_sample_offset_t _8x_multi_sample_offsets[] = { - { -0.375f, -0.375f }, - { -0.125f, -0.125f }, - { 0.375f, -0.375f }, - { 0.125f, -0.125f }, - { 0.375f, 0.375f }, - { 0.125f, 0.125f }, - { -0.375f, 0.375f }, - { -0.125f, 0.125f } -}; - -static unsigned short _8x_multi_sample_weights[] = { - 0x2000, 0x4000, 0x6000, 0x8000, 0xa000, 0xbfff, 0xdfff, 0xffff -}; - -static glitz_sample_info_t _8x_multi_sample = { - _8x_multi_sample_offsets, - _8x_multi_sample_weights, - 8 -}; - -static glitz_sample_offset_t _4x_multi_sample_offsets[] = { - { -0.125f, -0.375f }, - { 0.375f, -0.125f }, - { 0.125f, 0.375f }, - { -0.375f, 0.125f } -}; - -static unsigned short _4x_multi_sample_weights[] = { - 0x4000, 0x8000, 0xbfff, 0xffff -}; - -static glitz_sample_info_t _4x_multi_sample = { - _4x_multi_sample_offsets, - _4x_multi_sample_weights, - 4 -}; - -static glitz_sample_offset_t _2x_multi_sample_offsets[] = { - { -0.24f, -0.24f }, - { 0.24f, 0.24f } -}; - -static unsigned short _2x_multi_sample_weights[] = { - 0x8000, 0xffff -}; - -static glitz_sample_info_t _2x_multi_sample = { - _2x_multi_sample_offsets, - _2x_multi_sample_weights, - 2 -}; - -static glitz_sample_offset_t _1x_sample_offsets[] = { - { 0.0f, 0.0f } -}; - -static unsigned short _1x_sample_weights[] = { - 0xffff -}; - -static glitz_sample_info_t _1x_sample = { - _1x_sample_offsets, - _1x_sample_weights, - 1 -}; -void -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) +static glitz_gl_enum_t +_glitz_data_type (glitz_data_type_t type) { - glitz_drawable_t *drawable = (dst->attached)? dst->attached: dst->drawable; - - if (buffer) { - glitz_buffer_reference (buffer); - - 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; - case GLITZ_GEOMETRY_PRIMITIVE_TRIANGLE_STRIP: - dst->geometry.primitive = GLITZ_GL_TRIANGLE_STRIP; - break; - case GLITZ_GEOMETRY_PRIMITIVE_TRIANGLE_FAN: - dst->geometry.primitive = GLITZ_GL_TRIANGLE_FAN; - break; - case GLITZ_GEOMETRY_PRIMITIVE_QUADS: - dst->geometry.primitive = GLITZ_GL_QUADS; - break; - case GLITZ_GEOMETRY_PRIMITIVE_QUAD_STRIP: - dst->geometry.primitive = GLITZ_GL_QUAD_STRIP; - break; - default: - dst->geometry.primitive = GLITZ_GL_POLYGON; - break; - } - - switch (format->type) { + switch (type) { case GLITZ_DATA_TYPE_SHORT: - dst->geometry.type = GLITZ_GL_SHORT; - break; + return GLITZ_GL_SHORT; case GLITZ_DATA_TYPE_INT: - dst->geometry.type = GLITZ_GL_INT; - break; + return GLITZ_GL_INT; case GLITZ_DATA_TYPE_DOUBLE: - dst->geometry.type = GLITZ_GL_DOUBLE; - break; + return GLITZ_GL_DOUBLE; default: - dst->geometry.type = GLITZ_GL_FLOAT; - break; + return GLITZ_GL_FLOAT; } +} - dst->geometry.first = format->first; - dst->geometry.count = format->count; +void +glitz_set_geometry (glitz_surface_t *dst, + glitz_geometry_type_t type, + glitz_geometry_format_t *format, + glitz_buffer_t *buffer) +{ + switch (type) { + case GLITZ_GEOMETRY_TYPE_VERTEX: + { + glitz_buffer_reference (buffer); + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); + dst->geometry.buffer = buffer; + + dst->geometry.type = GLITZ_GEOMETRY_TYPE_VERTEX; + + switch (format->vertex.primitive) { + case GLITZ_PRIMITIVE_POINTS: + dst->geometry.u.v.prim = GLITZ_GL_POINTS; + break; + case GLITZ_PRIMITIVE_LINES: + dst->geometry.u.v.prim = GLITZ_GL_LINES; + break; + case GLITZ_PRIMITIVE_LINE_STRIP: + dst->geometry.u.v.prim = GLITZ_GL_LINE_STRIP; + break; + case GLITZ_PRIMITIVE_LINE_LOOP: + dst->geometry.u.v.prim = GLITZ_GL_LINE_LOOP; + break; + case GLITZ_PRIMITIVE_TRIANGLES: + dst->geometry.u.v.prim = GLITZ_GL_TRIANGLES; + break; + case GLITZ_PRIMITIVE_TRIANGLE_STRIP: + dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_STRIP; + break; + case GLITZ_PRIMITIVE_TRIANGLE_FAN: + dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_FAN; + break; + case GLITZ_PRIMITIVE_QUADS: + dst->geometry.u.v.prim = GLITZ_GL_QUADS; + break; + case GLITZ_PRIMITIVE_QUAD_STRIP: + dst->geometry.u.v.prim = GLITZ_GL_QUAD_STRIP; + break; + default: + dst->geometry.u.v.prim = GLITZ_GL_POLYGON; + break; + } + + dst->geometry.u.v.type = _glitz_data_type (format->vertex.type); + dst->geometry.stride = format->vertex.bytes_per_vertex; + dst->geometry.attributes = format->vertex.attributes; - if (drawable->format->samples > 1) { - if (format->edge_hint != GLITZ_GEOMETRY_EDGE_HINT_SHARP) { - dst->flags |= GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK; + if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK) + { + dst->geometry.u.v.src.type = + _glitz_data_type (format->vertex.src.type); + dst->geometry.u.v.src.offset = format->vertex.src.offset; + + if (format->vertex.src.size == GLITZ_COORDINATE_SIZE_XY) + dst->geometry.u.v.src.size = 2; + else + dst->geometry.u.v.src.size = 1; + } + + if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK) + { + dst->geometry.u.v.mask.type = + _glitz_data_type (format->vertex.mask.type); + dst->geometry.u.v.mask.offset = format->vertex.mask.offset; + + if (format->vertex.mask.size == GLITZ_COORDINATE_SIZE_XY) + dst->geometry.u.v.mask.size = 2; + else + dst->geometry.u.v.mask.size = 1; + } + } break; + case GLITZ_GEOMETRY_TYPE_BITMAP: + glitz_buffer_reference (buffer); + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); + dst->geometry.buffer = buffer; + + dst->geometry.type = GLITZ_GEOMETRY_TYPE_BITMAP; - if (format->edge_hint != GLITZ_GEOMETRY_EDGE_HINT_FAST_SMOOTH) - dst->flags |= GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK; + if (format->bitmap.scanline_order == + GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN) + dst->geometry.u.b.top_down = 1; else - dst->flags &= ~GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK; - } else - dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK; - } else { - if (format->mode == GLITZ_GEOMETRY_MODE_INDIRECT) { - switch (format->edge_hint) { - case GLITZ_GEOMETRY_EDGE_HINT_BEST_SMOOTH: - if (drawable->format->stencil_size >= 4) { - dst->indirect = &_8x_multi_sample; + dst->geometry.u.b.top_down = 0; + + switch (format->bitmap.pad) { + case 2: + dst->geometry.u.b.pad = 2; break; - } - /* fall-through */ - case GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH: - if (drawable->format->stencil_size >= 3) { - dst->indirect = &_4x_multi_sample; + case 4: + dst->geometry.u.b.pad = 4; break; - } - /* fall-through */ - case GLITZ_GEOMETRY_EDGE_HINT_FAST_SMOOTH: - if (drawable->format->stencil_size >= 2) { - dst->indirect = &_2x_multi_sample; + case 8: + dst->geometry.u.b.pad = 8; break; - } - /* fall-through */ - case GLITZ_GEOMETRY_EDGE_HINT_SHARP: default: - dst->indirect = &_1x_sample; - break; + dst->geometry.u.b.pad = 1; + break; } - } else - dst->indirect = NULL; - } - } else { - if (dst->geometry.buffer) - glitz_buffer_destroy (dst->geometry.buffer); + + dst->geometry.stride = format->bitmap.bytes_per_line; + dst->geometry.attributes = 0; + break; + default: + dst->geometry.type = GLITZ_GEOMETRY_TYPE_NONE; + if (dst->geometry.buffer) + glitz_buffer_destroy (dst->geometry.buffer); - dst->geometry.buffer = NULL; - dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK; - dst->indirect = NULL; - } + dst->geometry.buffer = NULL; + dst->geometry.attributes = 0; + break; + } } slim_hidden_def(glitz_set_geometry); void -glitz_geometry_enable_default (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst, - glitz_box_t *box) +glitz_set_array (glitz_surface_t *dst, + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off) { - dst->geometry.data[0] = box->x1; - dst->geometry.data[1] = box->y1; - dst->geometry.data[2] = box->x2; - dst->geometry.data[3] = box->y1; - dst->geometry.data[4] = box->x2; - dst->geometry.data[5] = box->y2; - dst->geometry.data[6] = box->x1; - dst->geometry.data[7] = box->y2; + if (dst->geometry.array) + { + glitz_multi_array_destroy (dst->geometry.array); + dst->geometry.array = NULL; + } + + dst->geometry.first = first; + dst->geometry.size = size; + dst->geometry.count = count; + dst->geometry.off.v[0] = FIXED_TO_FLOAT (x_off); + dst->geometry.off.v[1] = FIXED_TO_FLOAT (y_off); +} +slim_hidden_def(glitz_set_array); + +glitz_multi_array_t * +glitz_multi_array_create (unsigned int size) +{ + glitz_multi_array_t *array; + int alloc_size; + + if (!size) + return NULL; + + alloc_size = sizeof (glitz_multi_array_t) + (sizeof (int) + + sizeof (int) + + sizeof (unsigned int) + + sizeof (glitz_vec2_t) + + sizeof (int)) * (size); + + array = (glitz_multi_array_t *) malloc (alloc_size); + if (array == NULL) + return NULL; + + array->ref_count = 1; + array->size = size; + array->first = (int *) (array + 1); + array->sizes = (int *) (array->first + size); + array->count = (int *) (array->sizes + size); + array->off = (glitz_vec2_t *) (array->count + size); + array->span = (int *) (array->off + size); + + array->n_arrays = 0; + + return array; +} +slim_hidden_def(glitz_multi_array_create); + +void +glitz_multi_array_destroy (glitz_multi_array_t *array) +{ + if (!array) + return; + + array->ref_count--; + if (array->ref_count) + return; + + free (array); +} + +void +glitz_multi_array_reference (glitz_multi_array_t *array) +{ + if (array == NULL) + return; + + array->ref_count++; +} + +void +glitz_multi_array_add (glitz_multi_array_t *array, + int first, + int size, + unsigned int count, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off) +{ + int i; + + if (array->size == array->n_arrays) + return; + + i = array->n_arrays++; + + array->first[i] = first; + array->sizes[i] = size; + array->count[i] = count; + array->span[i] = 0; + + if (i == 0 || x_off || y_off) + { + array->off[i].v[0] = FIXED_TO_FLOAT (x_off); + array->off[i].v[1] = FIXED_TO_FLOAT (y_off); + array->current_span = &array->span[i]; + } + + (*array->current_span)++; +} +slim_hidden_def(glitz_multi_array_add); + +void +glitz_multi_array_reset (glitz_multi_array_t *array) +{ + array->n_arrays = 0; +} +slim_hidden_def(glitz_multi_array_reset); + +void +glitz_set_multi_array (glitz_surface_t *dst, + glitz_multi_array_t *array, + glitz_fixed16_16_t x_off, + glitz_fixed16_16_t y_off) +{ + glitz_multi_array_reference (array); + + if (dst->geometry.array) + glitz_multi_array_destroy (dst->geometry.array); + + dst->geometry.array = array; + dst->geometry.count = array->n_arrays; + dst->geometry.off.v[0] = FIXED_TO_FLOAT (x_off); + dst->geometry.off.v[1] = FIXED_TO_FLOAT (y_off); +} +slim_hidden_def(glitz_set_multi_array); + +void +glitz_geometry_enable_none (glitz_gl_proc_address_list_t *gl, + glitz_surface_t *dst, + glitz_box_t *box) +{ + dst->geometry.data[0] = (glitz_float_t) box->x1; + dst->geometry.data[1] = (glitz_float_t) box->y1; + dst->geometry.data[2] = (glitz_float_t) box->x2; + dst->geometry.data[3] = (glitz_float_t) box->y1; + dst->geometry.data[4] = (glitz_float_t) box->x2; + dst->geometry.data[5] = (glitz_float_t) box->y2; + dst->geometry.data[6] = (glitz_float_t) box->x1; + dst->geometry.data[7] = (glitz_float_t) box->y2; gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, dst->geometry.data); } @@ -239,38 +319,362 @@ 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_box_t *box) { - if (dst->geometry.buffer) { - void *ptr; + switch (dst->geometry.type) { + case GLITZ_GEOMETRY_TYPE_VERTEX: + gl->vertex_pointer (2, dst->geometry.u.v.type, dst->geometry.stride, + glitz_buffer_bind (dst->geometry.buffer, + GLITZ_GL_ARRAY_BUFFER)); + break; + case GLITZ_GEOMETRY_TYPE_BITMAP: + dst->geometry.u.b.base = + glitz_buffer_bind (dst->geometry.buffer, + GLITZ_GL_PIXEL_UNPACK_BUFFER); - ptr = glitz_buffer_bind (dst->geometry.buffer, GLITZ_GL_ARRAY_BUFFER); + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0); + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0); - gl->vertex_pointer (2, dst->geometry.type, 0, ptr); +#if BITMAP_BIT_ORDER == MSBFirst + gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_FALSE); +#else + gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_TRUE); +#endif + + break; + case GLITZ_GEOMETRY_TYPE_NONE: + glitz_geometry_enable_none (gl, dst, box); + } +} + +void +glitz_geometry_disable (glitz_surface_t *dst) +{ + if (dst->geometry.buffer) + glitz_buffer_unbind (dst->geometry.buffer); +} + +static void +_glitz_draw_rectangle (glitz_gl_proc_address_list_t *gl, + glitz_surface_t *dst, + glitz_box_t *bounds, + int damage) +{ + glitz_box_t *clip = dst->clip; + int n_clip = dst->n_clip; + glitz_box_t box; - if (dst->geometry.x_offset || dst->geometry.y_offset) - gl->translate_f (dst->geometry.x_offset, dst->geometry.y_offset, 0.0f); + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds->x1 > box.x1) + box.x1 = bounds->x1; + if (bounds->y1 > box.y1) + box.y1 = bounds->y1; + if (bounds->x2 < box.x2) + box.x2 = bounds->x2; + if (bounds->y2 < box.y2) + box.y2 = bounds->y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, box.y2 - box.y1); + + gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); + + if (damage) + glitz_surface_damage (dst, &box, damage); + } + + clip++; + } +} + +#define MULTI_DRAW_ARRAYS(surface) \ + ((surface)->drawable->backend->feature_mask & \ + GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK) + +static void +_glitz_draw_vertex_arrays (glitz_gl_proc_address_list_t *gl, + glitz_surface_t *dst, + glitz_box_t *bounds, + int damage) +{ + glitz_multi_array_t *array = dst->geometry.array; + glitz_box_t *clip = dst->clip; + int i, n_clip = dst->n_clip; + glitz_box_t box; + + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds->x1 > box.x1) + box.x1 = bounds->x1; + if (bounds->y1 > box.y1) + box.y1 = bounds->y1; + if (bounds->x2 < box.x2) + box.x2 = bounds->x2; + if (bounds->y2 < box.y2) + box.y2 = bounds->y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, box.y2 - box.y1); + + gl->push_matrix (); + + if (dst->geometry.off.v[0] || dst->geometry.off.v[1]) + gl->translate_f (dst->geometry.off.v[0], + dst->geometry.off.v[1], 0.0f); + + if (array) + { + for (i = 0; i < array->n_arrays;) + { + gl->translate_f (array->off[i].v[0], + array->off[i].v[1], 0.0f); + + if (MULTI_DRAW_ARRAYS (dst)) + { + gl->multi_draw_arrays (dst->geometry.u.v.prim, + &array->first[i], + &array->count[i], + array->span[i]); + i += array->span[i]; + } + else + { + do { + if (array->count[i]) + gl->draw_arrays (dst->geometry.u.v.prim, + array->first[i], + array->count[i]); + + } while (array->span[++i] == 0); + } + } + } else + gl->draw_arrays (dst->geometry.u.v.prim, + dst->geometry.first, + dst->geometry.count); + + gl->pop_matrix (); + + if (damage) + glitz_surface_damage (dst, &box, damage); + } + + clip++; + } +} + +#define N_STACK_BITMAP 128 + +#define BITMAP_PAD 4 +#define BITMAP_STRIDE(x, w, a) \ + (((((x) & 3) + (w) + (((a) << 3) - 1)) / ((a) << 3)) * (a)) + +#define BITMAP_SETUP(dst, first, size, count, _w, _h, _b_off, _p_off) \ + (_w) = (size); \ + (_h) = (count); \ + (_b_off) = (first) >> 3; \ + if ((_p_off) != ((first) & 3)) \ + { \ + (_p_off) = (first) & 3; \ + gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, _p_off); \ + } \ + if ((dst)->geometry.u.b.top_down) \ + { \ + dst_stride = BITMAP_STRIDE ((first), _w, BITMAP_PAD); \ + if ((dst)->geometry.stride) \ + src_stride = (dst)->geometry.stride; \ + else \ + src_stride = BITMAP_STRIDE ((first), _w, \ + (dst)->geometry.u.b.pad); \ + min_stride = MIN (src_stride, dst_stride); \ + base = (dst)->geometry.u.b.base + (_b_off); \ + y = (_h); \ + while (y--) \ + memcpy (bitmap + ((_h) - 1 - y) * dst_stride, \ + base + y * src_stride, \ + min_stride); \ + (_b_off) = 0; \ + } + +/* TODO: clipping could be done without glScissor, that might be + faster. Other then solid colors can be used if bitmap fits into a + stipple pattern. Maybe we should add a repeat parameter to + glitz_bitmap_format_t as 2, 4, 8, 16 and 32 sized bitmaps can be tiled. + */ +static void +_glitz_draw_bitmap_arrays (glitz_gl_proc_address_list_t *gl, + glitz_surface_t *dst, + glitz_box_t *bounds, + int damage) +{ + glitz_multi_array_t *array = dst->geometry.array; + glitz_box_t *clip = dst->clip; + int n, i, n_clip = dst->n_clip; + int x, y, w, h, min_stride, dst_stride, src_stride; + glitz_gl_ubyte_t *heap_bitmap = NULL; + glitz_gl_ubyte_t stack_bitmap[N_STACK_BITMAP]; + glitz_gl_ubyte_t *base, *bitmap = dst->geometry.u.b.base; + int byte_offset, pixel_offset = 0; + glitz_float_t x_off, y_off; + glitz_box_t box; + + if (dst->geometry.u.b.top_down) + { + int max_size = 0; + + if (array) + { + int size; + + for (i = 0, n = array->n_arrays; n--; i++) + { + x = array->first[i]; + w = array->sizes[i]; + size = BITMAP_STRIDE (x, w, BITMAP_PAD) * array->count[i]; + if (size > max_size) + max_size = size; + } + } + else + { + x = dst->geometry.first; + w = dst->geometry.size; + max_size = BITMAP_STRIDE (x, w, BITMAP_PAD) * dst->geometry.count; + } + + if (max_size > N_STACK_BITMAP) + { + heap_bitmap = malloc (max_size); + if (!heap_bitmap) + { + glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); + return; + } + bitmap = heap_bitmap; + } else + bitmap = stack_bitmap; + + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, BITMAP_PAD); + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0); + } + else + { + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, dst->geometry.u.b.pad); + gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, + dst->geometry.stride * 8); + } - *primitive = dst->geometry.primitive; - *first = dst->geometry.first; - *count = dst->geometry.count; - } else { - glitz_geometry_enable_default (gl, dst, box); - *primitive = GLITZ_GL_QUADS; - *first = 0; - *count = 4; - } + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + if (bounds->x1 > box.x1) + box.x1 = bounds->x1; + if (bounds->y1 > box.y1) + box.y1 = bounds->y1; + if (bounds->x2 < box.x2) + box.x2 = bounds->x2; + if (bounds->y2 < box.y2) + box.y2 = bounds->y2; + + if (box.x1 < box.x2 && box.y1 < box.y2) + { + gl->scissor (box.x1 + dst->x, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, box.y2 - box.y1); + + x_off = dst->x + dst->geometry.off.v[0]; + y_off = dst->y + dst->geometry.off.v[1]; + + if (array) + { + x_off += array->off->v[0]; + y_off += array->off->v[1]; + + glitz_set_raster_pos (gl, x_off, + dst->attached->height - y_off); + + for (i = 0, n = array->n_arrays; n--; i++) + { + if (n) + { + x_off = array->off[i + 1].v[0]; + y_off = array->off[i + 1].v[1]; + } + + BITMAP_SETUP (dst, + array->first[i], + array->sizes[i], + array->count[i], + w, h, byte_offset, pixel_offset); + + gl->bitmap (w, h, + 0.0f, (glitz_gl_float_t) array->count[i], + x_off, -y_off, + bitmap + byte_offset); + } + } + else + { + glitz_set_raster_pos (gl, x_off, + dst->attached->height - y_off); + + BITMAP_SETUP (dst, + dst->geometry.first, + dst->geometry.size, + dst->geometry.count, + w, h, byte_offset, pixel_offset); + + gl->bitmap (w, h, + 0.0f, (glitz_gl_float_t) dst->geometry.count, + 0.0f, 0.0f, + bitmap + byte_offset); + } + + if (damage) + glitz_surface_damage (dst, &box, damage); + } + + clip++; + } + + if (heap_bitmap) + free (heap_bitmap); } void -glitz_geometry_disable (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst) +glitz_geometry_draw_arrays (glitz_gl_proc_address_list_t *gl, + glitz_surface_t *dst, + glitz_geometry_type_t type, + glitz_box_t *bounds, + int damage) { - if (dst->geometry.buffer && - (dst->drawable->backend->feature_mask & - GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK)) - gl->bind_buffer (GLITZ_GL_ARRAY_BUFFER, 0); + switch (type) { + case GLITZ_GEOMETRY_TYPE_VERTEX: + _glitz_draw_vertex_arrays (gl, dst, bounds, damage); + break; + case GLITZ_GEOMETRY_TYPE_BITMAP: + _glitz_draw_bitmap_arrays (gl, dst, bounds, damage); + break; + case GLITZ_GEOMETRY_TYPE_NONE: + _glitz_draw_rectangle (gl, dst, bounds, damage); + break; + } } diff --git a/src/glitz_gl.h b/src/glitz_gl.h index 4bdb544..aad2862 100644 --- a/src/glitz_gl.h +++ b/src/glitz_gl.h @@ -1,5 +1,5 @@ /* - * Copyright © 2004 David Reveman, Peter Nilsson + * 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 @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: David Reveman + * Authors: David Reveman * Peter Nilsson */ @@ -39,6 +39,7 @@ typedef int glitz_gl_sizei_t; typedef double glitz_gl_double_t; typedef float glitz_gl_float_t; typedef unsigned short glitz_gl_ushort_t; +typedef short glitz_gl_short_t; typedef unsigned int glitz_gl_bitfield_t; typedef double glitz_gl_clampd_t; typedef float glitz_gl_clampf_t; @@ -57,7 +58,6 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #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 #define GLITZ_GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 #define GLITZ_GL_UNSIGNED_SHORT_5_6_5 0x8363 @@ -89,7 +89,8 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_QUAD_STRIP 0x0008 #define GLITZ_GL_POLYGON 0x0009 -#define GLITZ_GL_VERTEX_ARRAY 0x8074 +#define GLITZ_GL_VERTEX_ARRAY 0x8074 +#define GLITZ_GL_TEXTURE_COORD_ARRAY 0x8078 #define GLITZ_GL_FILL 0x1B02 #define GLITZ_GL_FRONT 0x0404 @@ -225,10 +226,12 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_CONSTANT_COLOR 0x8001 #define GLITZ_GL_PACK_ALIGNMENT 0x0D05 +#define GLITZ_GL_PACK_LSB_FIRST 0x0D01 #define GLITZ_GL_PACK_ROW_LENGTH 0x0D02 #define GLITZ_GL_PACK_SKIP_PIXELS 0x0D04 #define GLITZ_GL_PACK_SKIP_ROWS 0x0D03 #define GLITZ_GL_UNPACK_ALIGNMENT 0x0CF5 +#define GLITZ_GL_UNPACK_LSB_FIRST 0x0CF1 #define GLITZ_GL_UNPACK_ROW_LENGTH 0x0CF2 #define GLITZ_GL_UNPACK_SKIP_PIXELS 0x0CF4 #define GLITZ_GL_UNPACK_SKIP_ROWS 0x0CF3 @@ -282,9 +285,9 @@ typedef ptrdiff_t glitz_gl_sizeiptr_t; #define GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS 0x880F #define GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS 0x8810 -#define GLITZ_GL_ARRAY_BUFFER 0x8892 -#define GLITZ_GL_PIXEL_PACK_BUFFER 0x88EB -#define GLITZ_GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GLITZ_GL_ARRAY_BUFFER 0x8892 +#define GLITZ_GL_PIXEL_PACK_BUFFER 0x88EB +#define GLITZ_GL_PIXEL_UNPACK_BUFFER 0x88EC #define GLITZ_GL_STREAM_DRAW 0x88E0 #define GLITZ_GL_STREAM_READ 0x88E1 @@ -316,8 +319,14 @@ typedef glitz_gl_void_t (* glitz_gl_disable_client_state_t) typedef glitz_gl_void_t (* glitz_gl_vertex_pointer_t) (glitz_gl_int_t size, glitz_gl_enum_t type, glitz_gl_sizei_t stride, const glitz_gl_void_t *ptr); +typedef glitz_gl_void_t (* glitz_gl_tex_coord_pointer_t) + (glitz_gl_int_t size, glitz_gl_enum_t type, glitz_gl_sizei_t stride, + const glitz_gl_void_t *ptr); typedef glitz_gl_void_t (* glitz_gl_draw_arrays_t) (glitz_gl_enum_t mode, glitz_gl_int_t first, glitz_gl_sizei_t count); +typedef glitz_gl_void_t (* glitz_gl_multi_draw_arrays_t) + (glitz_gl_enum_t mode, glitz_gl_int_t *first, glitz_gl_sizei_t *count, + glitz_gl_sizei_t primcount); typedef glitz_gl_void_t (* glitz_gl_tex_env_f_t) (glitz_gl_enum_t target, glitz_gl_enum_t pname, glitz_gl_float_t param); typedef glitz_gl_void_t (* glitz_gl_tex_env_fv_t) @@ -457,6 +466,8 @@ typedef glitz_gl_void_t (* glitz_gl_get_pointer_v_t) (glitz_gl_enum_t pname, glitz_gl_void_t **params); typedef glitz_gl_void_t (* glitz_gl_active_texture_t) (glitz_gl_enum_t); +typedef glitz_gl_void_t (* glitz_gl_client_active_texture_t) + (glitz_gl_enum_t); typedef glitz_gl_void_t (* glitz_gl_gen_programs_t) (glitz_gl_sizei_t, glitz_gl_uint_t *); typedef glitz_gl_void_t (* glitz_gl_delete_programs_t) diff --git a/src/glitz_operator.c b/src/glitz_operator.c index 223b7ad..b19186b 100644 --- a/src/glitz_operator.c +++ b/src/glitz_operator.c @@ -1,5 +1,5 @@ /* - * Copyright © 2004 David Reveman, Peter Nilsson + * 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 @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: David Reveman + * Authors: David Reveman * Peter Nilsson */ diff --git a/src/glitz_pixel.c b/src/glitz_pixel.c index 220a9c4..0c04572 100644 --- a/src/glitz_pixel.c +++ b/src/glitz_pixel.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -599,8 +599,8 @@ glitz_set_pixels (glitz_surface_t *dst, GLITZ_GL_SURFACE (dst); - if (x_dst < 0 || x_dst > (dst->width - width) || - y_dst < 0 || y_dst > (dst->height - height)) { + if (x_dst < 0 || x_dst > (dst->box.x2 - width) || + y_dst < 0 || y_dst > (dst->box.y2 - height)) { glitz_surface_status_add (dst, GLITZ_STATUS_BAD_COORDINATE_MASK); return; } @@ -612,6 +612,7 @@ glitz_set_pixels (glitz_surface_t *dst, if (SURFACE_SOLID (dst)) { glitz_image_t src_image, dst_image; + glitz_color_t old = dst->solid; dst_image.width = dst_image.height = 1; @@ -620,7 +621,7 @@ glitz_set_pixels (glitz_surface_t *dst, src_image.format = format; src_image.width = src_image.height = 1; - if (format->masks.alpha_mask) { + if (format->masks.alpha_mask && dst->format->color.alpha_size) { dst_image.data = (void *) &dst->solid.alpha; dst_image.format = &_solid_format[SOLID_ALPHA]; @@ -630,7 +631,7 @@ glitz_set_pixels (glitz_surface_t *dst, } else dst->solid.alpha = 0xffff; - if (format->masks.red_mask) { + if (format->masks.red_mask && dst->format->color.red_size) { dst_image.data = (void *) &dst->solid.red; dst_image.format = &_solid_format[SOLID_RED]; @@ -640,7 +641,7 @@ glitz_set_pixels (glitz_surface_t *dst, } else dst->solid.red = 0; - if (format->masks.green_mask) { + if (format->masks.green_mask && dst->format->color.green_size) { dst_image.data = (void *) &dst->solid.green; dst_image.format = &_solid_format[SOLID_GREEN]; @@ -650,7 +651,7 @@ glitz_set_pixels (glitz_surface_t *dst, } else dst->solid.green = 0; - if (format->masks.blue_mask) { + if (format->masks.blue_mask && dst->format->color.blue_size) { dst_image.data = (void *) &dst->solid.blue; dst_image.format = &_solid_format[SOLID_BLUE]; @@ -662,10 +663,23 @@ glitz_set_pixels (glitz_surface_t *dst, glitz_buffer_unmap (buffer); - dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; - glitz_surface_damage (dst, &box, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_DRAWABLE_MASK); + if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK) + { + dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_DRAWABLE_MASK); + } + else + { + if (dst->solid.red != old.red || + dst->solid.green != old.green || + dst->solid.blue != old.blue || + dst->solid.alpha != old.alpha) + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_DRAWABLE_MASK); + } return; } @@ -750,12 +764,10 @@ glitz_set_pixels (glitz_surface_t *dst, if (bytes_per_line) { if ((bytes_per_line % 4) == 0) gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 4); - else if ((bytes_per_line % 3) == 0) - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 3); else if ((bytes_per_line % 2) == 0) gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 2); else - gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 2); + gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1); gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, bytes_per_line / (bpp / 8)); } else { @@ -808,8 +820,8 @@ glitz_get_pixels (glitz_surface_t *src, GLITZ_GL_SURFACE (src); - if (x_src < 0 || x_src > (src->width - width) || - y_src < 0 || y_src > (src->height - height)) { + if (x_src < 0 || x_src > (src->box.x2 - width) || + y_src < 0 || y_src > (src->box.y2 - height)) { glitz_surface_status_add (src, GLITZ_STATUS_BAD_COORDINATE_MASK); return; } @@ -969,12 +981,10 @@ glitz_get_pixels (glitz_surface_t *src, if (bytes_per_line) { if ((bytes_per_line % 4) == 0) gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 4); - else if ((bytes_per_line % 3) == 0) - gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 3); else if ((bytes_per_line % 2) == 0) gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 2); else - gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 2); + gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 1); gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, bytes_per_line / (bpp / 8)); } else { @@ -982,7 +992,7 @@ glitz_get_pixels (glitz_surface_t *src, gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, 0); } - if (from_drawable) { + if (from_drawable) { gl->read_buffer (src->buffer); gl->disable (GLITZ_GL_SCISSOR_TEST); diff --git a/src/glitz_program.c b/src/glitz_program.c index 01f6bae..b5d0239 100644 --- a/src/glitz_program.c +++ b/src/glitz_program.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -32,69 +32,110 @@ #include #define EXPAND_NONE "" -#define EXPAND_2D "2D" +#define EXPAND_2D "2D" #define EXPAND_RECT "RECT" +#define EXPAND_NA "NA" -#define EXPAND_NO_IN_OP \ - "MUL result.color, color, fragment.color.a;" +#define EXPAND_X_IN_SOLID_OP \ + { "", "", "MUL result.color, color, fragment.color.a;" } +#define EXPAND_SOLID_IN_X_OP \ + { "", "", "MUL result.color, fragment.color, color.a;" } + #define EXPAND_SRC_DECL "TEMP src;" #define EXPAND_SRC_2D_IN_OP \ - "TXP src, fragment.texcoord[1], texture[1], 2D;" \ - "DP4 color.a, color, fragment.color;" \ - "MUL result.color, src, color.a;" + { "TXP src, fragment.texcoord[1], texture[1], 2D;", \ + "DP4 color.a, color, fragment.color;", \ + "MUL result.color, src, color.a;" } + #define EXPAND_SRC_RECT_IN_OP \ - "TXP src, fragment.texcoord[1], texture[1], RECT;" \ - "DP4 color.a, color, fragment.color;" \ - "MUL result.color, src, color.a;" + { "TXP src, fragment.texcoord[1], texture[1], RECT;", \ + "DP4 color.a, color, fragment.color;", \ + "MUL result.color, src, color.a;" } #define EXPAND_MASK_DECL "TEMP mask;" #define EXPAND_MASK_2D_IN_OP \ - "TXP mask, fragment.texcoord[0], texture[0], 2D;" \ - "DP4 mask.a, mask, fragment.color;" \ - "MUL result.color, color, mask.a;" + { "TXP mask, fragment.texcoord[0], texture[0], 2D;", \ + "DP4 mask.a, mask, fragment.color;", \ + "MUL result.color, color, mask.a;" } #define EXPAND_MASK_RECT_IN_OP \ - "TXP mask, fragment.texcoord[0], texture[0], RECT;" \ - "DP4 mask.a, mask, fragment.color;" \ - "MUL result.color, color, mask.a;" + { "TXP mask, fragment.texcoord[0], texture[0], RECT;", \ + "DP4 mask.a, mask, fragment.color;", \ + "MUL result.color, color, mask.a;" } + +#define EXPAND_IN_NA \ + { "NA", "NA", "NA" } typedef struct _glitz_program_expand_t glitz_program_expand_t; +typedef struct _glitz_inop { + char *fetch; + char *dot_product; + char *mult; +} glitz_in_op_t; + static const struct _glitz_program_expand_t { - char *texture; - char *declarations; - char *in; -} _program_expand_map[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST] = { + char *texture; + char *declarations; + glitz_in_op_t in; +} _program_expand_map[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST][2] = { { /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_NONE] */ - { EXPAND_NONE, EXPAND_NONE, EXPAND_NO_IN_OP }, + { + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }, + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA } + }, /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_2D] */ - { EXPAND_NONE, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP }, + { + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }, + { EXPAND_2D, EXPAND_NONE, EXPAND_SOLID_IN_X_OP } + }, /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_RECT] */ - { EXPAND_NONE, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP } + { + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }, + { EXPAND_RECT, EXPAND_NONE, EXPAND_SOLID_IN_X_OP } + } }, { /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_NONE] */ - { EXPAND_2D, EXPAND_NONE, EXPAND_NO_IN_OP }, + { + { EXPAND_2D, EXPAND_NONE, EXPAND_X_IN_SOLID_OP }, + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA } + }, /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_2D] */ - { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP }, + { + { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP }, + { EXPAND_2D, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP } + }, /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_RECT] */ - { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP } + { + { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP }, + { EXPAND_RECT, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP } + } }, { - + /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_NONE] */ - { EXPAND_RECT, EXPAND_NONE, EXPAND_NO_IN_OP }, + { + { EXPAND_RECT, EXPAND_NONE, EXPAND_X_IN_SOLID_OP }, + { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA } + }, /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_2D] */ - { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP }, + { + { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP }, + { EXPAND_2D, EXPAND_SRC_DECL, EXPAND_SRC_2D_IN_OP } + }, /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_RECT] */ - { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP } + { + { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP }, + { EXPAND_RECT, EXPAND_SRC_DECL, EXPAND_SRC_RECT_IN_OP } + } } }; @@ -106,7 +147,7 @@ static const char *_convolution_header[] = { "ATTRIB pos = fragment.texcoord[%s];", "TEMP color, in, coord, position;", - /* extra declerations */ + /* extra declarations */ "%s" /* perspective divide */ @@ -139,7 +180,7 @@ static const char *_gradient_header[] = { "ATTRIB pos = fragment.texcoord[%s];", "TEMP color, second_color, stop0, stop1, position;", - /* extra declerations */ + /* extra declarations */ "%s", /* perspective divide */ @@ -352,23 +393,36 @@ _glitz_create_fragment_program (glitz_composite_op_t *op, const glitz_program_expand_t *expand) { char buffer[1024], *program = NULL, *tex, *p = NULL; + char *texture_type, *extra_declarations; + const glitz_in_op_t *in; glitz_gl_uint_t fp; int i; - + switch (op->type) { case GLITZ_COMBINE_TYPE_ARGBF: case GLITZ_COMBINE_TYPE_ARGBF_SOLID: case GLITZ_COMBINE_TYPE_ARGBF_SOLIDC: + i = 0; + tex = "0"; + break; + case GLITZ_COMBINE_TYPE_ARGB_ARGBF: + case GLITZ_COMBINE_TYPE_SOLID_ARGBF: + i = 1; tex = "0"; break; case GLITZ_COMBINE_TYPE_ARGBF_ARGB: case GLITZ_COMBINE_TYPE_ARGBF_ARGBC: + i = 0; tex = "1"; break; default: return 0; } + texture_type = expand[i].texture; + extra_declarations = expand[i].declarations; + in = &expand[i].in; + switch (fp_type) { case GLITZ_FP_CONVOLUTION: program = malloc (CONVOLUTION_BASE_SIZE + CONVOLUTION_SAMPLE_SIZE * id); @@ -380,14 +434,14 @@ _glitz_create_fragment_program (glitz_composite_op_t *op, p += sprintf (p, "!!ARBfp1.0"); _string_array_to_char_array (buffer, _convolution_header); - p += sprintf (p, buffer, id, id - 1, tex, expand->declarations); + p += sprintf (p, buffer, id, id - 1, tex, extra_declarations); _string_array_to_char_array (buffer, _convolution_sample_first); - p += sprintf (p, buffer, tex, expand->texture); + p += sprintf (p, buffer, tex, texture_type); _string_array_to_char_array (buffer, _convolution_sample); for (i = 1; i < id; i++) - p += sprintf (p, buffer, i, i, tex, expand->texture, i); + p += sprintf (p, buffer, i, i, tex, texture_type, i); break; case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT: @@ -409,7 +463,7 @@ _glitz_create_fragment_program (glitz_composite_op_t *op, p += sprintf (p, "!!ARBfp1.0"); _string_array_to_char_array (buffer, _gradient_header); - p += sprintf (p, buffer, id, id, tex, expand->declarations); + p += sprintf (p, buffer, id, id, tex, extra_declarations); switch (fp_type) { case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT: @@ -452,7 +506,7 @@ _glitz_create_fragment_program (glitz_composite_op_t *op, p += sprintf (p, buffer, id - i - 1, id - i - 1); _string_array_to_char_array (buffer, _gradient_fetch_and_interpolate); - p += sprintf (p, buffer, tex, expand->texture, tex, expand->texture); + p += sprintf (p, buffer, tex, texture_type, tex, texture_type); id++; break; @@ -463,7 +517,10 @@ _glitz_create_fragment_program (glitz_composite_op_t *op, if (program == NULL) return 0; - p += sprintf (p, "%s", expand->in); + p += sprintf (p, "%s", in->fetch); + if (op->per_component) + p += sprintf (p, "%s", in->dot_product); + p += sprintf (p, "%s", in->mult); sprintf (p, "END"); fp = _glitz_compile_arb_fragment_program (op->gl, program, id); @@ -549,7 +606,7 @@ glitz_get_fragment_program (glitz_composite_op_t *op, program->name[id - 1] = _glitz_create_fragment_program (op, fp_type, id, - &_program_expand_map[t0][t1]); + _program_expand_map[t0][t1]); glitz_surface_pop_current (op->dst); } diff --git a/src/glitz_rect.c b/src/glitz_rect.c index 07d1860..48ec839 100644 --- a/src/glitz_rect.c +++ b/src/glitz_rect.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -35,26 +35,39 @@ ((1L << (size)) - 1L)) : \ dst) -static void -glitz_rectangle_bounds (const glitz_rectangle_t *rects, - int n_rects, - glitz_box_t *box) +static glitz_buffer_t * +_glitz_minimum_buffer (glitz_surface_t *surface, + const glitz_rectangle_t *rects, + int n_rects, + unsigned int pixel) { - box->x1 = MAXSHORT; - box->x2 = MINSHORT; - box->y1 = MAXSHORT; - box->y2 = MINSHORT; + glitz_buffer_t *buffer; + int i, size = 0; + unsigned int *data; - for (; n_rects; n_rects--, rects++) { - if (rects->x < box->x1) - box->x1 = rects->x; - if ((rects->x + rects->width) > box->x2) - box->x2 = rects->x + rects->width; - if (rects->y < box->y1) - box->y1 = rects->y; - if ((rects->y + rects->height) > box->y2) - box->y2 = rects->y + rects->height; - } + while (n_rects--) + { + i = rects->width * rects->height; + if (i > size) + size = i; + + rects++; + } + + buffer = glitz_pixel_buffer_create (surface->drawable, NULL, + size * sizeof (unsigned int), + GLITZ_BUFFER_HINT_STATIC_DRAW); + if (!buffer) + return NULL; + + data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + + while (size--) + *data++ = pixel; + + glitz_buffer_unmap (buffer); + + return buffer; } void @@ -63,99 +76,171 @@ glitz_set_rectangles (glitz_surface_t *dst, const glitz_rectangle_t *rects, int n_rects) { - 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) && - (bounds.x2 - bounds.x1) > 0 && (bounds.y2 - bounds.y1) > 0) { - 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); - - dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; - glitz_surface_damage (dst, &bounds, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_DRAWABLE_MASK); - return; - } - - 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, - color->alpha / (glitz_gl_clampf_t) 0xffff); - - for (; n_rects; n_rects--, rects++) { - gl->scissor (rects->x, - dst->attached->height - dst->y - rects->y - rects->height, - rects->width, - rects->height); - gl->clear (GLITZ_GL_COLOR_BUFFER_BIT); + GLITZ_GL_SURFACE (dst); + + if (n_rects < 1) + return; + + if (SURFACE_SOLID (dst)) + { + glitz_color_t old = dst->solid; + glitz_box_t *clip = dst->clip; + int n_clip = dst->n_clip; + + for (; n_clip; clip++, n_clip--) + { + if (clip->x1 > 0 || + clip->y1 > 0 || + clip->x2 < 1 || + clip->y2 < 1) + continue; + + for (; n_rects; rects++, n_rects--) + { + if (rects->x > 0 || + rects->y > 0 || + (rects->x + rects->width) < 1 || + (rects->y + rects->height) < 1) + continue; + + 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); + + if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK) + { + dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; + glitz_surface_damage (dst, &dst->box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_DRAWABLE_MASK); + } + else + { + if (dst->solid.red != old.red || + dst->solid.green != old.green || + dst->solid.blue != old.blue || + dst->solid.alpha != old.alpha) + glitz_surface_damage (dst, &dst->box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_DRAWABLE_MASK); + } + break; + } + break; + } } - glitz_surface_damage (dst, &bounds, - GLITZ_DAMAGE_TEXTURE_MASK | - GLITZ_DAMAGE_SOLID_MASK); - } else { - static glitz_pixel_format_t pf = { - { - 32, - 0xff000000, - 0x00ff0000, - 0x0000ff00, - 0x000000ff - }, - 0, 0, 0, - GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP - }; - glitz_buffer_t *buffer; - unsigned int i, width, height, pixel, *data; + else + { + static glitz_pixel_format_t pf = { + { + 32, + 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff + }, + 0, 0, 0, + GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP + }; + glitz_buffer_t *buffer = NULL; + glitz_box_t box; + glitz_bool_t drawable; + + drawable = glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT); + if (drawable) + { + gl->clear_color (color->red / (glitz_gl_clampf_t) 0xffff, + color->green / (glitz_gl_clampf_t) 0xffff, + color->blue / (glitz_gl_clampf_t) 0xffff, + color->alpha / (glitz_gl_clampf_t) 0xffff); + } + else + { + unsigned int pixel = + ((((unsigned int) color->alpha * 0xff) / 0xffff) << 24) | + ((((unsigned int) color->red * 0xff) / 0xffff) << 16) | + ((((unsigned int) color->green * 0xff) / 0xffff) << 8) | + ((((unsigned int) color->blue * 0xff) / 0xffff)); + + buffer = _glitz_minimum_buffer (dst, rects, n_rects, pixel); + if (!buffer) + { + glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); + return; + } + } + + while (n_rects--) + { + glitz_box_t *clip = dst->clip; + int n_clip = dst->n_clip; + + while (n_clip--) + { + box.x1 = clip->x1 + dst->x_clip; + box.y1 = clip->y1 + dst->y_clip; + box.x2 = clip->x2 + dst->x_clip; + box.y2 = clip->y2 + dst->y_clip; + + if (dst->box.x1 > box.x1) + box.x1 = dst->box.x1; + if (dst->box.y1 > box.y1) + box.y1 = dst->box.y1; + if (dst->box.x2 < box.x2) + box.x2 = dst->box.x2; + if (dst->box.y2 < box.y2) + box.y2 = dst->box.y2; + + if (rects->x > box.x1) + box.x1 = rects->x; + if (rects->y > box.y1) + box.y1 = rects->y; + if (rects->x + rects->width < box.x2) + box.x2 = rects->x + rects->width; + if (rects->y + rects->height < box.y2) + box.y2 = rects->y + rects->height; - width = bounds.x2 - bounds.x1; - height = bounds.y2 - bounds.y1; + if (box.x1 < box.x2 && box.y1 < box.y2) + { + if (drawable) + { + gl->scissor (box.x1, + dst->attached->height - dst->y - box.y2, + box.x2 - box.x1, + box.y2 - box.y1); + gl->clear (GLITZ_GL_COLOR_BUFFER_BIT); + + glitz_surface_damage (dst, &box, + GLITZ_DAMAGE_TEXTURE_MASK | + GLITZ_DAMAGE_SOLID_MASK); + } + else + { + glitz_set_pixels (dst, + box.x1, box.y1, + box.x2 - box.x1, box.y2 - box.y1, + &pf, buffer); + } + } + clip++; + } + rects++; + } + + if (buffer) + glitz_buffer_destroy (buffer); - data = malloc (width * height * 4); - if (data == NULL) { - glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); - return; + glitz_surface_pop_current (dst); } - - buffer = glitz_buffer_create_for_data (data); - if (buffer == NULL) { - free (data); - glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK); - return; - } - - pixel = - ((((unsigned int) color->alpha * 0xff) / 0xffff) << 24) | - ((((unsigned int) color->red * 0xff) / 0xffff) << 16) | - ((((unsigned int) color->green * 0xff) / 0xffff) << 8) | - ((((unsigned int) color->blue * 0xff) / 0xffff)); - - for (i = 0; i < width; i++) - data[i] = pixel; - - for (i = 1; i < height; i++) - memcpy (&data[i * width], data, width * sizeof (unsigned int)); - - for (; n_rects; n_rects--, rects++) - glitz_set_pixels (dst, - rects->x, rects->y, - rects->width, rects->height, - &pf, buffer); - - glitz_buffer_destroy (buffer); - free (data); - } - - glitz_surface_pop_current (dst); } slim_hidden_def(glitz_set_rectangles); @@ -167,13 +252,13 @@ glitz_set_rectangle (glitz_surface_t *dst, unsigned int width, unsigned int height) { - glitz_rectangle_t rect; + glitz_rectangle_t rect; - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; - glitz_set_rectangles (dst, color, &rect, 1); + glitz_set_rectangles (dst, color, &rect, 1); } slim_hidden_def(glitz_set_rectangle); diff --git a/src/glitz_region.c b/src/glitz_region.c index 253ad31..88e7884 100644 --- a/src/glitz_region.c +++ b/src/glitz_region.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H diff --git a/src/glitz_status.c b/src/glitz_status.c index 364960b..2edcb08 100644 --- a/src/glitz_status.c +++ b/src/glitz_status.c @@ -1,5 +1,5 @@ /* - * Copyright © 2004 David Reveman, Peter Nilsson + * 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 @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: David Reveman + * Authors: David Reveman * Peter Nilsson */ diff --git a/src/glitz_surface.c b/src/glitz_surface.c index 74c73af..43f3470 100644 --- a/src/glitz_surface.c +++ b/src/glitz_surface.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -33,55 +33,81 @@ #include glitz_surface_t * -glitz_surface_create (glitz_drawable_t *drawable, - glitz_format_t *format, - unsigned int width, - unsigned int height) +glitz_surface_create (glitz_drawable_t *drawable, + glitz_format_t *format, + unsigned int width, + unsigned int height, + unsigned long mask, + glitz_surface_attributes_t *attributes) { - glitz_surface_t *surface; - - if (width == 0 || height == 0) - return NULL; + glitz_surface_t *surface; + glitz_bool_t unnormalized = 0; + unsigned long feature_mask = drawable->backend->feature_mask; - surface = (glitz_surface_t *) calloc (1, sizeof (glitz_surface_t)); - if (surface == NULL) - return NULL; + if (!width || !height) + return NULL; + + if (mask & GLITZ_SURFACE_UNNORMALIZED_MASK) + { + if (attributes->unnormalized) + { + if (!(feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK)) + return NULL; + + unnormalized = 1; + } + } - surface->drawable = drawable; - glitz_drawable_reference (drawable); + surface = (glitz_surface_t *) calloc (1, sizeof (glitz_surface_t)); + if (surface == NULL) + return NULL; + + surface->drawable = drawable; + glitz_drawable_reference (drawable); - surface->ref_count = 1; - surface->filter = GLITZ_FILTER_NEAREST; - surface->format = format; - surface->width = (int) width; - surface->height = (int) height; - surface->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.alpha = 0xffff; - } + surface->ref_count = 1; + surface->filter = GLITZ_FILTER_NEAREST; + surface->format = format; + surface->box.x2 = (short) width; + surface->box.y2 = (short) height; + surface->clip = &surface->box; + surface->n_clip = 1; + surface->buffer = GLITZ_GL_FRONT; + + if (width == 1 && height == 1) + { + surface->flags |= GLITZ_SURFACE_FLAG_SOLID_MASK; + surface->solid.alpha = 0xffff; + + REGION_INIT (&surface->texture_damage, &surface->box); + REGION_INIT (&surface->drawable_damage, &surface->box); + } + else + { + REGION_INIT (&surface->texture_damage, NULL_BOX); + REGION_INIT (&surface->drawable_damage, NULL_BOX); + } - glitz_texture_init (&surface->texture, width, height, - drawable->backend->texture_formats[format->id], - drawable->backend->feature_mask); + glitz_texture_init (&surface->texture, width, height, + drawable->backend->texture_formats[format->id], + feature_mask, unnormalized); - 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; + 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; + return surface; } void @@ -106,11 +132,14 @@ glitz_surface_destroy (glitz_surface_t *surface) if (surface->geometry.buffer) glitz_buffer_destroy (surface->geometry.buffer); + if (surface->geometry.array) + glitz_multi_array_destroy (surface->geometry.array); + if (surface->transform) free (surface->transform); if (surface->filter_params) - glitz_filter_params_destroy (surface->filter_params); + free (surface->filter_params); if (surface->attached) glitz_drawable_destroy (surface->attached); @@ -132,195 +161,217 @@ glitz_surface_reference (glitz_surface_t *surface) static void _glitz_surface_sync_texture (glitz_surface_t *surface) { - if (REGION_NOTEMPTY (&surface->texture_damage)) { - glitz_box_t *box; - int n_box; - - 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; - + if (REGION_NOTEMPTY (&surface->texture_damage)) + { + glitz_box_t *box; + int n_box; + + 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); - 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); + + box = REGION_RECTS (&surface->texture_damage); + n_box = REGION_NUM_RECTS (&surface->texture_damage); + + 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); - } - 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); - - 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++; + + gl->enable (GLITZ_GL_SCISSOR_TEST); + + glitz_surface_pop_current (surface); } - - 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_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); - - texture = glitz_surface_get_texture (surface, 0); - if (!texture) - return; - - 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); + if (REGION_NOTEMPTY (&surface->drawable_damage)) + { + glitz_texture_t *texture; + glitz_box_t *box, *ext; + int n_box; + + GLITZ_GL_SURFACE (surface); + + texture = glitz_surface_get_texture (surface, 0); + if (!texture) + return; + + 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_texture_set_tex_gen (gl, texture, NULL, + 0, 0, + GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK, + NULL); - gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE, - GLITZ_GL_REPLACE); - gl->color_4us (0x0, 0x0, 0x0, 0xffff); + 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_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); + glitz_set_operator (gl, GLITZ_OPERATOR_SRC); - 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; + 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; + } + + 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); - ptr = malloc (n_box * 8 * sizeof (glitz_float_t)); - if (!ptr) { - glitz_surface_status_add (surface, GLITZ_STATUS_NO_MEMORY_MASK); - return; - } + free (ptr); + } + else + { + glitz_geometry_enable_none (gl, surface, ext); + gl->draw_arrays (GLITZ_GL_QUADS, 0, 4); + } - 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; + glitz_texture_unbind (gl, texture); - 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); + REGION_EMPTY (&surface->drawable_damage); } - - glitz_texture_unbind (gl, texture); - - REGION_EMPTY (&surface->drawable_damage); - } } void glitz_surface_sync_solid (glitz_surface_t *surface) { - if (SURFACE_SOLID_DAMAGE (surface)) { - glitz_gl_float_t *c, color[64]; - glitz_texture_t *texture; - - GLITZ_GL_SURFACE (surface); + if (SURFACE_SOLID_DAMAGE (surface)) + { + glitz_gl_float_t *c, color[64]; + glitz_texture_t *texture; + + 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); + gl->get_tex_image (texture->target, 0, + GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color); + glitz_texture_unbind (gl, texture); + } + else + { + 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; - 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); - gl->get_tex_image (texture->target, 0, - GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color); - glitz_texture_unbind (gl, texture); - } else { - c[0] = c[1] = c[2] = 0.0f; - c[3] = 1.0f; + surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; } - - 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_DAMAGE_MASK; - } } glitz_texture_t * glitz_surface_get_texture (glitz_surface_t *surface, glitz_bool_t allocate) { - GLITZ_GL_SURFACE (surface); + 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; + 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; + return NULL; } void @@ -328,107 +379,93 @@ 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 (box) + { + if (what & GLITZ_DAMAGE_DRAWABLE_MASK) + REGION_UNION (&surface->drawable_damage, box); - if (what & GLITZ_DAMAGE_DRAWABLE_MASK) { - REGION_EMPTY (&surface->drawable_damage); - REGION_INIT (&surface->drawable_damage, &b); + if (what & GLITZ_DAMAGE_TEXTURE_MASK) + REGION_UNION (&surface->texture_damage, box); } - - if (what & GLITZ_DAMAGE_TEXTURE_MASK) { - REGION_EMPTY (&surface->texture_damage); - REGION_INIT (&surface->texture_damage, &b); + else + { + if (what & GLITZ_DAMAGE_DRAWABLE_MASK) + { + REGION_EMPTY (&surface->drawable_damage); + REGION_INIT (&surface->drawable_damage, &surface->box); + } + + if (what & GLITZ_DAMAGE_TEXTURE_MASK) + { + REGION_EMPTY (&surface->texture_damage); + REGION_INIT (&surface->texture_damage, &surface->box); + } } - } - - if (what & GLITZ_DAMAGE_SOLID_MASK) - surface->flags |= GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK; + + 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) +glitz_surface_status_add (glitz_surface_t *surface, + int flags) { - surface->status_mask |= flags; + surface->status_mask |= flags; } static void _glitz_surface_update_state (glitz_surface_t *surface) { - 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); + glitz_rectangle_t *viewport; - viewport->x = surface->x; - viewport->y = surface->y; - viewport->width = surface->width; - viewport->height = surface->height; + GLITZ_GL_SURFACE (surface); - surface->attached->update_all = 0; - } - - gl->draw_buffer (surface->buffer); + viewport = &surface->attached->viewport; + + if (surface->attached->update_all || + viewport->x != surface->x || + viewport->y != surface->y || + viewport->width != surface->box.x2 || + viewport->height != surface->box.y2) + { + gl->viewport (surface->x, + surface->attached->height - surface->y - surface->box.y2, + surface->box.x2, + surface->box.y2); + gl->matrix_mode (GLITZ_GL_PROJECTION); + gl->load_identity (); + gl->ortho (0.0, + surface->box.x2, + surface->attached->height - surface->box.y2, + 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->box.x2; + viewport->height = surface->box.y2; + + surface->attached->update_all = 0; + } + + gl->draw_buffer (surface->buffer); - if (SURFACE_DITHER (surface)) - gl->enable (GLITZ_GL_DITHER); - else - gl->disable (GLITZ_GL_DITHER); + 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); - } + if (surface->attached->format->samples > 1) + { + gl->enable (GLITZ_GL_MULTISAMPLE); + if (surface->attached->backend->feature_mask & + GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK) + gl->hint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_NICEST); + } } void @@ -438,64 +475,59 @@ glitz_surface_attach (glitz_surface_t *surface, int x, int y) { - glitz_drawable_reference (drawable); + glitz_drawable_reference (drawable); - if (surface->attached) - glitz_drawable_destroy (surface->attached); + 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; - } + 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); + 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 (!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); - } + 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; + glitz_drawable_destroy (surface->attached); + surface->attached = NULL; - REGION_EMPTY (&surface->drawable_damage); - REGION_INIT (&surface->drawable_damage, &box); + REGION_EMPTY (&surface->drawable_damage); + REGION_INIT (&surface->drawable_damage, &surface->box); } glitz_drawable_t * glitz_surface_get_drawable (glitz_surface_t *surface) { - return surface->drawable; + 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; + return surface->attached; } slim_hidden_def(glitz_surface_get_attached_drawable); @@ -775,14 +807,14 @@ slim_hidden_def(glitz_surface_flush); unsigned int glitz_surface_get_width (glitz_surface_t *surface) { - return (unsigned int) surface->width; + return (unsigned int) surface->box.x2; } slim_hidden_def(glitz_surface_get_width); unsigned int glitz_surface_get_height (glitz_surface_t *surface) { - return (unsigned int) surface->height; + return (unsigned int) surface->box.y2; } slim_hidden_def(glitz_surface_get_height); @@ -799,3 +831,47 @@ glitz_surface_get_format (glitz_surface_t *surface) return surface->format; } slim_hidden_def(glitz_surface_get_format); + +void +glitz_surface_translate_point (glitz_surface_t *surface, + glitz_point_fixed_t *src, + glitz_point_fixed_t *dst) +{ + + if (surface->texture.target == GLITZ_GL_TEXTURE_2D) + { + dst->x = (INT_TO_FIXED (surface->texture.box.x1) + src->x) / + surface->texture.width; + dst->y = (INT_TO_FIXED (surface->texture.box.y2) - src->y) / + surface->texture.height; + } + else + { + dst->x = INT_TO_FIXED (surface->texture.box.x1) + src->x; + dst->y = INT_TO_FIXED (surface->texture.box.y2) - src->y; + } +} +slim_hidden_def(glitz_surface_translate_point); + +void +glitz_surface_set_clip_region (glitz_surface_t *surface, + int x_origin, + int y_origin, + glitz_box_t *box, + int n_box) +{ + if (n_box) + { + surface->clip = box; + surface->n_clip = n_box; + surface->x_clip = x_origin; + surface->y_clip = y_origin; + } + else + { + surface->clip = &surface->box; + surface->n_clip = 1; + surface->x_clip = surface->y_clip = 0; + } +} +slim_hidden_def(glitz_surface_set_clip_region); diff --git a/src/glitz_texture.c b/src/glitz_texture.c index f4f25b2..de53ff5 100644 --- a/src/glitz_texture.c +++ b/src/glitz_texture.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -34,55 +34,69 @@ glitz_texture_init (glitz_texture_t *texture, int width, int height, glitz_gl_int_t texture_format, - unsigned long feature_mask) + unsigned long feature_mask, + glitz_bool_t unnormalized) { - texture->filter = 0; - texture->wrap = 0; - texture->format = texture_format; - texture->name = 0; + texture->filter = 0; + texture->wrap = 0; + texture->format = texture_format; + texture->name = 0; - if (feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK) { - texture->box.x1 = texture->box.y1 = 0; - texture->box.x2 = texture->width = width; - texture->box.y2 = texture->height = height; - texture->flags = GLITZ_TEXTURE_FLAG_REPEATABLE_MASK | - GLITZ_TEXTURE_FLAG_PADABLE_MASK; - } else { - texture->box.x1 = texture->box.y1 = 1; - texture->box.x2 = width + 1; - texture->box.y2 = height + 1; - texture->width = width + 2; - texture->height = height + 2; - texture->flags = 0; - } + if (feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK) + { + texture->box.x1 = texture->box.y1 = 0; + texture->box.x2 = texture->width = width; + texture->box.y2 = texture->height = height; + texture->flags = GLITZ_TEXTURE_FLAG_REPEATABLE_MASK | + GLITZ_TEXTURE_FLAG_PADABLE_MASK; + } + else + { + texture->box.x1 = texture->box.y1 = 1; + texture->box.x2 = width + 1; + texture->box.y2 = height + 1; + texture->width = width + 2; + texture->height = height + 2; + texture->flags = 0; + } - if ((feature_mask & GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) || - (POWER_OF_TWO (texture->width) && POWER_OF_TWO (texture->height))) { - texture->target = GLITZ_GL_TEXTURE_2D; - } else { - texture->flags &= ~GLITZ_TEXTURE_FLAG_REPEATABLE_MASK; - - if (feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) { - texture->target = GLITZ_GL_TEXTURE_RECTANGLE; - } else { - texture->target = GLITZ_GL_TEXTURE_2D; - texture->flags &= ~GLITZ_TEXTURE_FLAG_PADABLE_MASK; - - if (!POWER_OF_TWO (texture->width)) - texture->width = glitz_uint_to_power_of_two (texture->width); + if (!unnormalized && + ((feature_mask & GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) || + (POWER_OF_TWO (texture->width) && POWER_OF_TWO (texture->height)))) + { + texture->target = GLITZ_GL_TEXTURE_2D; + } + else + { + texture->flags &= ~GLITZ_TEXTURE_FLAG_REPEATABLE_MASK; - if (!POWER_OF_TWO (texture->height)) - texture->height = glitz_uint_to_power_of_two (texture->height); + if (feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) + { + texture->target = GLITZ_GL_TEXTURE_RECTANGLE; + } + else + { + texture->target = GLITZ_GL_TEXTURE_2D; + texture->flags &= ~GLITZ_TEXTURE_FLAG_PADABLE_MASK; + + if (!POWER_OF_TWO (texture->width)) + texture->width = glitz_uint_to_power_of_two (texture->width); + + if (!POWER_OF_TWO (texture->height)) + texture->height = glitz_uint_to_power_of_two (texture->height); + } } - } - if (texture->target == GLITZ_GL_TEXTURE_2D) { - texture->texcoord_width_unit = 1.0f / texture->width; - texture->texcoord_height_unit = 1.0f / texture->height; - } else { - texture->texcoord_width_unit = 1.0f; - texture->texcoord_height_unit = 1.0f; - } + if (texture->target == GLITZ_GL_TEXTURE_2D) + { + texture->texcoord_width_unit = 1.0f / texture->width; + texture->texcoord_height_unit = 1.0f / texture->height; + } + else + { + texture->texcoord_width_unit = 1.0f; + texture->texcoord_height_unit = 1.0f; + } } void @@ -240,47 +254,85 @@ glitz_texture_copy_drawable (glitz_gl_proc_address_list_t *gl, void glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl, glitz_texture_t *texture, + glitz_geometry_t *geometry, int x_src, int y_src, - unsigned long flags) + unsigned long flags, + glitz_int_coordinate_t *coord) { - glitz_vec4_t plane; + glitz_vec4_t plane; - plane.v[1] = plane.v[2] = 0.0f; - - if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) { - plane.v[0] = 1.0f; - plane.v[3] = -x_src; - } else { - plane.v[0] = texture->texcoord_width_unit; - - if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK) - plane.v[3] = -(x_src) * texture->texcoord_width_unit; - else - plane.v[3] = -(x_src - texture->box.x1) * texture->texcoord_width_unit; - } - - gl->tex_gen_i (GLITZ_GL_S, GLITZ_GL_TEXTURE_GEN_MODE, - GLITZ_GL_EYE_LINEAR); - gl->tex_gen_fv (GLITZ_GL_S, GLITZ_GL_EYE_PLANE, plane.v); - gl->enable (GLITZ_GL_TEXTURE_GEN_S); + if (flags & GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK) + { + plane.v[1] = plane.v[2] = 0.0f; + + if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) + { + plane.v[0] = 1.0f; + plane.v[3] = -x_src; + } + else + { + plane.v[0] = texture->texcoord_width_unit; + + if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK) + plane.v[3] = -(x_src) * texture->texcoord_width_unit; + else + plane.v[3] = -(x_src - texture->box.x1) * + texture->texcoord_width_unit; + } + + gl->tex_gen_i (GLITZ_GL_S, GLITZ_GL_TEXTURE_GEN_MODE, + GLITZ_GL_EYE_LINEAR); + gl->tex_gen_fv (GLITZ_GL_S, GLITZ_GL_EYE_PLANE, plane.v); - plane.v[0] = 0.0f; - if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) { - plane.v[1] = 1.0f; - plane.v[3] = -y_src; - } else { - plane.v[1] = -texture->texcoord_height_unit; - - if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK) - plane.v[3] = (y_src + texture->box.y2 - texture->box.y1) * - texture->texcoord_height_unit; + gl->enable (GLITZ_GL_TEXTURE_GEN_S); + } else - plane.v[3] = (y_src + texture->box.y2) * texture->texcoord_height_unit; - } + gl->disable (GLITZ_GL_TEXTURE_GEN_S); + + if (flags & GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK) + { + plane.v[0] = 0.0f; + if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) + { + plane.v[1] = 1.0f; + plane.v[3] = -y_src; + } + else + { + plane.v[1] = -texture->texcoord_height_unit; + + if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK) + plane.v[3] = (y_src + texture->box.y2 - texture->box.y1) * + texture->texcoord_height_unit; + else + plane.v[3] = (y_src + texture->box.y2) * + texture->texcoord_height_unit; + } - gl->tex_gen_i (GLITZ_GL_T, GLITZ_GL_TEXTURE_GEN_MODE, - GLITZ_GL_EYE_LINEAR); - gl->tex_gen_fv (GLITZ_GL_T, GLITZ_GL_EYE_PLANE, plane.v); - gl->enable (GLITZ_GL_TEXTURE_GEN_T); + gl->tex_gen_i (GLITZ_GL_T, GLITZ_GL_TEXTURE_GEN_MODE, + GLITZ_GL_EYE_LINEAR); + gl->tex_gen_fv (GLITZ_GL_T, GLITZ_GL_EYE_PLANE, plane.v); + + gl->enable (GLITZ_GL_TEXTURE_GEN_T); + } + else + gl->disable (GLITZ_GL_TEXTURE_GEN_T); + + if (!(flags & GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK)) + { + unsigned char *ptr; + + gl->enable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY); + + ptr = glitz_buffer_bind (geometry->buffer, GLITZ_GL_ARRAY_BUFFER); + ptr += coord->offset; + + gl->tex_coord_pointer (coord->size, + coord->type, + geometry->stride, + (void *) ptr); + } else + gl->disable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY); } diff --git a/src/glitz_trap.c b/src/glitz_trap.c new file mode 100644 index 0000000..7cad8a5 --- /dev/null +++ b/src/glitz_trap.c @@ -0,0 +1,446 @@ +/* + * Copyright © 2005 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Novell, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Novell, Inc. makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NOVELL, INC. 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 + */ + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif + +#include "glitzint.h" + +/* whether 't' is a well defined not obviously empty trapezoid */ +#define TRAPEZOID_VALID(t) ((t)->left.p1.y != (t)->left.p2.y && \ + (t)->right.p1.y != (t)->right.p2.y && \ + (int) ((t)->bottom - (t)->top) > 0) + +/* whether 't' is a well defined not obviously empty trap */ +#define TRAP_VALID(t) ((int) ((t)->bottom.y - (t)->top.y) > 0) + +typedef struct _glitz_edge { + glitz_float_t dx, dy; + glitz_float_t x0, y0; + glitz_float_t kx, ky; + glitz_float_t tx, bx; + glitz_float_t hypx; + int hyp; +} glitz_edge_t; + +#define EDGE_INIT(e, p1x, p1y, p2x, p2y) \ + (e)->hyp = 1; \ + (e)->dx = (p2x) - (p1x); \ + (e)->dy = (p2y) - (p1y); \ + if ((e)->dy) \ + (e)->kx = (e)->dx / (e)->dy; \ + else \ + (e)->kx = 0; \ + (e)->x0 = (p1x) - (e)->kx * (p1y); \ + if ((e)->dx) \ + (e)->ky = (e)->dy / (e)->dx; \ + else \ + (e)->ky = 0; \ + (e)->y0 = (p1y) - (e)->ky * (p1x) + +#define EDGE_X(e, _y) (((e)->kx * (_y)) + (e)->x0) +#define EDGE_Y(e, _x) (((e)->ky * (_x)) + (e)->y0) + +#define EDGE_INTERSECT_BOX(upper_x, lower_y, left_y, right_y, \ + box_x1, box_x2, box_y1, box_y2, \ + max_x, max_y, \ + _x1, _y1, _x2, _y2) \ + if (upper_x < (box_x1)) \ + { \ + (_x1) = 0.0f; \ + (_y1) = (left_y) - (box_y1); \ + } \ + else if ((upper_x) > (box_x2)) \ + { \ + (_x1) = (max_x); \ + (_y1) = (right_y) - (box_y1); \ + } \ + else \ + { \ + (_x1) = (upper_x) - (box_x1); \ + (_y1) = 0.0f; \ + } \ + if ((lower_x) < (box_x1)) \ + { \ + (_x2) = 0.0f; \ + (_y2) = (left_y) - (box_y1); \ + } \ + else if ((lower_x) > (box_x2)) \ + { \ + (_x2) = (max_x); \ + (_y2) = (right_y) - (box_y1); \ + } \ + else \ + { \ + (_x2) = (lower_x) - (box_x1); \ + (_y2) = (max_y); \ + } + +#define AREA_ABOVE_LEFT(x1, y1, x2, y2, bottom) \ + ((x1) * (y1) + \ + (((x1) + (x2)) / 2.0f) * ((y2) - (y1)) + \ + (x2) * ((bottom) - (y2))) + +/* + Given a single pixel position this function calculates + trapezoid pixel coverage. +*/ +static glitz_float_t +_glitz_pixel_area (glitz_float_t pixel_x, + glitz_float_t pixel_y, + glitz_float_t top, + glitz_float_t bottom, + glitz_edge_t *left, + glitz_edge_t *right) +{ + glitz_float_t area; + glitz_float_t upper_x, lower_x; + glitz_float_t left_y, right_y; + glitz_float_t pixel_x_1 = pixel_x + 1.0f; + glitz_float_t pixel_y_1 = pixel_y + 1.0f; + glitz_float_t x1, x2, y1, y2; + + if (bottom >= pixel_y_1) + bottom = 1.0f; + else + bottom = bottom - pixel_y; + + if (top <= pixel_y) + top = 0.0f; + else + top = top - pixel_y; + + if (right->ky) + { + upper_x = EDGE_X (right, pixel_y); + lower_x = EDGE_X (right, pixel_y_1); + + left_y = EDGE_Y (right, pixel_x); + right_y = EDGE_Y (right, pixel_x_1); + + EDGE_INTERSECT_BOX (upper_x, lower_y, left_y, right_y, + pixel_x, pixel_x_1, pixel_y, pixel_y_1, + 1.0f, 1.0f, x1, y1, x2, y2); + + if (bottom <= y1) + { + if (left_y > right_y) + area = bottom; + else + area = 0.0f; + } + else + { + if (bottom < y2) + { + x2 -= right->kx * (y2 - bottom); + y2 = bottom; + } + area = AREA_ABOVE_LEFT (x1, y1, x2, y2, bottom); + } + + if (top <= y1) + { + if (left_y > right_y) + area -= top; + } + else + { + if (top < y2) + { + x2 -= right->kx * (y2 - top); + y2 = top; + } + + area -= AREA_ABOVE_LEFT (x1, y1, x2, y2, top); + } + } + else + { + /* Vertical Edge */ + if (right->x0 < pixel_x_1) + area = (right->x0 - pixel_x) * (bottom - top); + else + area = bottom - top; + } + + if (left->kx) + { + upper_x = EDGE_X (left, pixel_y); + lower_x = EDGE_X (left, pixel_y_1); + + left_y = EDGE_Y (left, pixel_x); + right_y = EDGE_Y (left, pixel_x_1); + + EDGE_INTERSECT_BOX (upper_x, lower_y, left_y, right_y, + pixel_x, pixel_x_1, pixel_y, pixel_y_1, + 1.0f, 1.0f, x1, y1, x2, y2); + + if (bottom <= y1) + { + if (left_y > right_y) + area -= bottom; + } + else + { + if (bottom < y2) + { + x2 -= left->kx * (y2 - bottom); + y2 = bottom; + } + area -= AREA_ABOVE_LEFT (x1, y1, x2, y2, bottom); + } + + if (top <= y1) + { + if (left_y > right_y) + area += top; + } + else + { + if (top < y2) + { + x2 -= left->kx * (y2 - top); + y2 = top; + } + + area += AREA_ABOVE_LEFT (x1, y1, x2, y2, top); + } + } + else + { + /* Vertical Edge */ + if (left->x0 > pixel_x) + area -= (left->x0 - pixel_x) * (bottom - top); + } + + return area; +} + +#define TRAPINIT(trap, _top, _bottom, _left, _right) \ + if (!TRAPEZOID_VALID (trap)) \ + continue; \ + \ + (_top) = FIXED_TO_FLOAT ((trap)->top); \ + (_bottom) = FIXED_TO_FLOAT ((trap)->bottom); \ + \ + (_left)->tx = FIXED_TO_FLOAT ((trap)->left.p1.x); \ + (_left)->bx = FIXED_TO_FLOAT ((trap)->left.p1.y); \ + \ + (_right)->tx = FIXED_TO_FLOAT ((trap)->right.p1.x); \ + (_right)->bx = FIXED_TO_FLOAT ((trap)->right.p1.y); \ + \ + EDGE_INIT (_left, \ + (_left)->tx, (_left)->bx, \ + FIXED_TO_FLOAT ((trap)->left.p2.x), \ + FIXED_TO_FLOAT ((trap)->left.p2.y)); \ + \ + EDGE_INIT (_right, \ + (_right)->tx, (_right)->bx, \ + FIXED_TO_FLOAT ((trap)->right.p2.x), \ + FIXED_TO_FLOAT ((trap)->right.p2.y)); \ + \ + if ((_left)->dx) \ + { \ + (_left)->tx = EDGE_X (_left, _top); \ + (_left)->bx = EDGE_X (_left, _bottom); \ + } else \ + (_left)->tx = (_left)->bx = (_left)->x0; \ + \ + if ((_right)->dx) \ + { \ + (_right)->tx = EDGE_X (_right, _top); \ + (_right)->bx = EDGE_X (_right, _bottom); \ + } else \ + (_right)->tx = (_right)->bx = (_right)->x0 + +#define TRAP glitz_trapezoid_t + +#define UNIT glitz_short_t +#define TRAPS _glitz_add_trapezoids_short +#include "glitz_trapimp.h" +#undef TRAPS +#undef UNIT + +#define UNIT glitz_int_t +#define TRAPS _glitz_add_trapezoids_int +#include "glitz_trapimp.h" +#undef TRAPS +#undef UNIT + +#define UNIT glitz_float_t +#define TRAPS _glitz_add_trapezoids_float +#include "glitz_trapimp.h" +#undef TRAPS +#undef UNIT + +#define UNIT glitz_double_t +#define TRAPS _glitz_add_trapezoids_double +#include "glitz_trapimp.h" +#undef TRAPS +#undef UNIT + +#undef TRAP +#undef TRAPINIT + +#define TRAPINIT(trap, _top, _bottom, _left, _right) \ + if (!TRAP_VALID (trap)) \ + continue; \ + \ + (_top) = FIXED_TO_FLOAT ((trap)->top.y); \ + (_bottom) = FIXED_TO_FLOAT ((trap)->bottom.y); \ + \ + (_left)->tx = FIXED_TO_FLOAT ((trap)->top.left); \ + (_left)->bx = FIXED_TO_FLOAT ((trap)->bottom.left); \ + \ + (_right)->tx = FIXED_TO_FLOAT ((trap)->top.right); \ + (_right)->bx = FIXED_TO_FLOAT ((trap)->bottom.right); \ + \ + EDGE_INIT (_left, \ + (_left)->tx, _top, \ + (_left)->bx, _bottom); \ + \ + EDGE_INIT (_right, \ + (_right)->tx, _top, \ + (_right)->bx, _bottom) + +#define TRAP glitz_trap_t + +#define UNIT glitz_short_t +#define TRAPS _glitz_add_traps_short +#include "glitz_trapimp.h" +#undef TRAPS +#undef UNIT + +#define UNIT glitz_int_t +#define TRAPS _glitz_add_traps_int +#include "glitz_trapimp.h" +#undef TRAPS +#undef UNIT + +#define UNIT glitz_float_t +#define TRAPS _glitz_add_traps_float +#include "glitz_trapimp.h" +#undef TRAPS +#undef UNIT + +#define UNIT glitz_double_t +#define TRAPS _glitz_add_traps_double +#include "glitz_trapimp.h" +#undef TRAPS +#undef UNIT + +#undef TRAP +#undef TRAPINIT + +int +glitz_add_trapezoids (glitz_buffer_t *buffer, + int offset, + unsigned int size, + glitz_data_type_t type, + glitz_surface_t *mask, + glitz_trapezoid_t *traps, + int n_traps, + int *n_added) +{ + int count, n = n_traps; + uint8_t *ptr; + + *n_added = 0; + + ptr = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + if (!ptr) + return 0; + + ptr += offset; + + switch (type) { + case GLITZ_DATA_TYPE_SHORT: + count = _glitz_add_trapezoids_short (ptr, size, mask, traps, &n_traps); + break; + case GLITZ_DATA_TYPE_INT: + count = _glitz_add_trapezoids_int (ptr, size, mask, traps, &n_traps); + break; + case GLITZ_DATA_TYPE_DOUBLE: + count = _glitz_add_trapezoids_double (ptr, size, mask, + traps, &n_traps); + break; + default: + count = _glitz_add_trapezoids_float (ptr, size, mask, traps, &n_traps); + break; + } + + if (glitz_buffer_unmap (buffer)) + return 0; + + *n_added = n - n_traps; + + return count; +} + +int +glitz_add_traps (glitz_buffer_t *buffer, + int offset, + unsigned int size, + glitz_data_type_t type, + glitz_surface_t *mask, + glitz_trap_t *traps, + int n_traps, + int *n_added) +{ + int count, n = n_traps; + uint8_t *ptr; + + *n_added = 0; + + ptr = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); + if (!ptr) + return 0; + + ptr += offset; + + switch (type) { + case GLITZ_DATA_TYPE_SHORT: + count = _glitz_add_traps_short (ptr, size, mask, traps, &n_traps); + break; + case GLITZ_DATA_TYPE_INT: + count = _glitz_add_traps_int (ptr, size, mask, traps, &n_traps); + break; + case GLITZ_DATA_TYPE_DOUBLE: + count = _glitz_add_traps_double (ptr, size, mask, traps, &n_traps); + break; + default: + count = _glitz_add_traps_float (ptr, size, mask, traps, &n_traps); + break; + } + + if (glitz_buffer_unmap (buffer)) + return 0; + + *n_added = n - n_traps; + + return count; +} diff --git a/src/glitz_trapimp.h b/src/glitz_trapimp.h new file mode 100644 index 0000000..1fefe6c --- /dev/null +++ b/src/glitz_trapimp.h @@ -0,0 +1,746 @@ +/* + * Copyright © 2005 Novell, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Novell, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Novell, Inc. makes no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NOVELL, INC. 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 + */ + +/* + Define the following before including this file: + + TRAPS name of function for adding trapezoids + UNIT type of underlying vertex unit + TRAP type of underlying trapezoid structure + TRAPINIT initialization code for underlying trapezoid structure +*/ + +#define BYTES_PER_VERTEX (2 * sizeof (UNIT) + sizeof (glitz_float_t)) +#define BYTES_PER_QUAD (4 * BYTES_PER_VERTEX) + +#define VSKIP (BYTES_PER_VERTEX / sizeof (UNIT)) +#define TSKIP (BYTES_PER_VERTEX / sizeof (glitz_float_t)) + +#define ADD_VERTEX(vptr, tptr, texcoord, _x, _y) \ + (vptr)[0] = (UNIT) (_x); \ + (vptr)[1] = (UNIT) (_y); \ + (tptr)[0] = (texcoord); \ + (vptr) += VSKIP; \ + (tptr) += TSKIP + +#define ADD_QUAD(vptr, tptr, offset, size, \ + t00, t01, t10, t11, x1, y1, x2, y2) \ + if ((offset) == (size)) \ + return (toff); \ + (offset) += BYTES_PER_QUAD; \ + ADD_VERTEX (vptr, tptr, t00, x1, y1); \ + ADD_VERTEX (vptr, tptr, t01, x2, y1); \ + ADD_VERTEX (vptr, tptr, t10, x2, y2); \ + ADD_VERTEX (vptr, tptr, t11, x1, y2) + +#define ADD_PIXEL(vptr, tptr, offset, size, tmp0, tbase, tsize, \ + x1, y1, x2, y2, alpha) \ + (tmp0) = (tbase) + (alpha - 0.5f) * (tsize); \ + ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp0, tmp0, tmp0, \ + x1, y1, x2, y2) + +#define CALC_SPAN(tmp0, tmp1, tbase, tsize, edge, end) \ + (tmp0) = (edge) - (end); \ + (tmp0) = (tbase) - (tmp0) * (tsize); \ + (tmp1) = (tbase) + (end) * (tsize) + +#define ADD_LEFT_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \ + x1, y1, x2, y2, end) \ + CALC_SPAN (tmp0, tmp1, tbase, tsize, (x2) - (x1), end); \ + ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp1, tmp1, tmp0, \ + x1, y1, x2, y2) + +#define ADD_RIGHT_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \ + x1, y1, x2, y2, end) \ + CALC_SPAN (tmp0, tmp1, tbase, tsize, (x2) - (x1), end); \ + ADD_QUAD (vptr, tptr, offset, size, tmp1, tmp0, tmp0, tmp1, \ + x1, y1, x2, y2) + +#define ADD_TOP_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \ + x1, y1, x2, y2, end) \ + CALC_SPAN (tmp0, tmp1, tbase, tsize, (y2) - (y1), end); \ + ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp0, tmp1, tmp1, \ + x1, y1, x2, y2) + +#define ADD_BOTTOM_SPAN(vptr, tptr, offset, size, tmp0, tmp1, tbase, tsize, \ + x1, y1, x2, y2, end) \ + CALC_SPAN (tmp0, tmp1, tbase, tsize, (y2) - (y1), end); \ + ADD_QUAD (vptr, tptr, offset, size, tmp1, tmp1, tmp0, tmp0, \ + x1, y1, x2, y2) + + +#define CALC_EDGE(tl, tr, bl, br, x1, x2, tsize, edge, tx, bx) \ + if ((edge)->hyp) \ + { \ + (edge)->hypx = (edge)->dy / \ + sqrtf ((edge)->dx * (edge)->dx + (edge)->dy * (edge)->dy); \ + (edge)->hyp = 0; \ + } \ + (tl) = (((tx) - (x1)) * (edge)->hypx) * tsize; \ + (tr) = (((tx) - (x2)) * (edge)->hypx) * tsize; \ + (bl) = (((bx) - (x1)) * (edge)->hypx) * tsize; \ + (br) = (((bx) - (x2)) * (edge)->hypx) * tsize + +#define CALC_LEFT_EDGE(tl, tr, bl, br, x1, x2, tbase, tsize, edge, tx, bx) \ + CALC_EDGE (tl, tr, bl, br, x1, x2, tsize, edge, tx, bx); \ + (tl) = (tbase) - (tl); \ + (tr) = (tbase) - (tr); \ + (bl) = (tbase) - (bl); \ + (br) = (tbase) - (br) + +#define CALC_RIGHT_EDGE(tl, tr, bl, br, x1, x2, tbase, tsize, edge, tx, bx) \ + CALC_EDGE (tl, tr, bl, br, x1, x2, tsize, edge, tx, bx); \ + (tl) = (tbase) + (tl); \ + (tr) = (tbase) + (tr); \ + (bl) = (tbase) + (bl); \ + (br) = (tbase) + (br) + +#define ADD_LEFT_EDGE(vptr, tptr, offset, size, \ + tmp0, tmp1, tmp2, tmp3, tbase, tsize, \ + edge, x1, y1, x2, y2, tx, bx) \ + CALC_LEFT_EDGE (tmp0, tmp1, tmp2, tmp3, x1, x2, \ + tbase, tsize, edge, tx, bx); \ + ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp1, tmp3, tmp2, \ + x1, y1, x2, y2) + +#define ADD_RIGHT_EDGE(vptr, tptr, offset, size, \ + tmp0, tmp1, tmp2, tmp3, tbase, tsize, \ + edge, x1, y1, x2, y2, tx, bx) \ + CALC_RIGHT_EDGE (tmp0, tmp1, tmp2, tmp3, x1, x2, \ + tbase, tsize, edge, tx, bx); \ + ADD_QUAD (vptr, tptr, offset, size, tmp0, tmp1, tmp3, tmp2, \ + x1, y1, x2, y2) + +/* + An implicit mask surface for a single anti-aliased edge that + intersect a rectangle in any direction, can be represented + accurately and consistently with a set of one-dimensional texture + coordinates in a fixed size texture. By using linear texture + filtering this allow us two render perfectly anti-aliased + geometry on a wide range of hardware. + + Each trapezoid needs to be slit up into a set of rectangles along + with appropriate horizontal texture coordinates for the specified + mask surface. In general the mask is a 2x1 surface with pixel + 0,0 "clear black" and pixel 1,0 "solid white". This function + generates geometry data in the following format: + + primitive : QUADS + type : SHORT|INT|FLOAT|DOUBLE + stride : 2 * sizeof (type) + sizeof (FLOAT) + attributes : MASK_COORD + mask.type : FLOAT + mask.size : COORDINATE_SIZE_X + mask.offset : 2 * sizeof (type) + + Trapezoid: + top { l, r, y } + bottom { l, r, y } + + Bounds: + x1 = floor (MIN (top.l, bottom.l)) + x2 = ceil (MAX (top.r, bottom.r)) + y1 = floor (top.y) + y2 = ceil (bottom.y) + + W = x2 - x1; + H = y2 - y1; + + TH = 1 if TOP rectangle exist, else 0 + BH = 1 if BOTTOM rectangle exist, else 0 + + TOP rectangle exists if: floor (top.y) != top.y + BOTTOM rectangle exists if: ceil (bottom.y) != bottom.y && + bottom.y > ceil (top.y) + MIDDLE rectangle exists if: (H - TH - BH) > 0 + + W + +----------------------------------------------------+ + | | + | TOP +---------------------------+ | TH + | / | | + +---------------/-----------------------------+------+ + | / | | + | MIDDLE / | | + | / | | + | / | | + | / | | H - TH - BH + | / | | + | / | | + | / | | + | / | | + +-----/---------------------------------------+------+ + | / | | + | +-----------------------------------------+ | BH + | BOTTOM | + +----------------------------------------------------+ +*/ +static unsigned int +TRAPS (void *ptr, + unsigned int size, + glitz_surface_t *mask, + TRAP *traps, + int *n_traps) +{ + unsigned int toff = 0, offset = 0; + UNIT *vptr = (UNIT *) ptr; + glitz_float_t *tptr = (glitz_float_t *) (vptr + 2); + + glitz_edge_t left, right; + glitz_float_t top, bottom; + + glitz_float_t tbase, tsize; + glitz_float_t l, r, lspan, rspan; + glitz_float_t tmp0, tmp1, tmp2, tmp3, tmpx, tmpy; + glitz_float_t x1, x2, lx, rx; + glitz_float_t y, y0, y1, y2, y3; + glitz_float_t y1lx, y2lx, y1rx, y2rx; + glitz_float_t area; + + size -= size % BYTES_PER_QUAD; + + tsize = (glitz_float_t) (mask->texture.box.x2 - mask->texture.box.x1); + tbase = (glitz_float_t) mask->texture.box.x1 + (tsize / 2.0f); + + tsize = (tsize - 1.0f) * mask->texture.texcoord_width_unit; + tbase *= mask->texture.texcoord_width_unit; + + for (; *n_traps; (*n_traps)--, traps++) + { + TRAPINIT (traps, top, bottom, &left, &right); + + /* + Top left X greater than top right X or bottom left X greater + than bottom right X. To me, this seems like an invalid trapezoid. + Cairo's current caps generation code, creates a lot of these. The + following adjustments makes them render almost correct. + */ + if (left.tx > right.tx) + { + if (floorf (left.tx) > floorf (right.tx)) + left.tx = right.tx = floorf (left.tx); + } + + if (left.bx > right.bx) + { + if (floorf (left.bx) > floorf (right.bx)) + left.bx = right.bx = floorf (left.bx); + } + + x1 = floorf (MIN (left.tx, left.bx)); + x2 = ceilf (MAX (right.tx, right.bx)); + + /* + TOP rectangle + W + +---------+---------+------------------+---------+--------+ + | | | | | | + | lE | +------+------------------|------+ | rE | + | |/ | | \| | 1 + | /| lEtE | tE | tErE |\ | + | +-+---------+------------------+---------+-+ | + +-----+---+---------+------------------+---------+--------+ + + The following set sub-rectangles might need to be generated + to render the top span of the trapezoid correctly. + + lE = Left Edge + tE = Top Edge + rE = Right Edge + lEtE = Left/Top Edge intersection + tErE = Top/Right Edge intersection + */ + y1 = ceilf (top); + if (y1 != top) + { + y0 = floorf (top); + lx = x1; + rx = x2; + + y1lx = EDGE_X (&left, y1); + y1rx = EDGE_X (&right, y1); + + if (bottom > y1) + { + l = MAX (left.tx, y1lx); + r = MIN (right.tx, y1rx); + } + else + { + l = MAX (left.tx, left.bx); + r = MIN (right.tx, right.bx); + } + + lspan = ceilf (l); + rspan = floorf (r); + + l = floorf (l); + if (l > rspan) + l = rspan; + + r = ceilf (r); + if (r < lspan) + r = lspan; + + /* Left Edge */ + if (l > x1) + { + lx = EDGE_X (&left, y0); + if (left.dx > 0.0f) + { + tmpx = y1lx + (left.tx - lx); + lx = left.tx; + } + else + { + if (bottom < y1) + { + lx += (left.bx - y1lx); + tmpx = left.bx; + } + else + tmpx = y1lx; + } + + ADD_LEFT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &left, + x1, y0, l, y1, + lx, tmpx); + + lx = l; + } + + /* Right Edge */ + if (r < x2) + { + rx = EDGE_X (&right, y0); + if (right.dx < 0.0f) + { + tmpx = y1rx - (rx - right.tx); + rx = right.tx; + } + else + { + if (bottom < y1) + { + rx -= (y1rx - right.bx); + tmpx = right.bx; + } + else + tmpx = y1rx; + } + + ADD_RIGHT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &right, + r, y0, x2, y1, + rx, tmpx); + rx = r; + } + + /* Left/Top Edge intersection */ + if (lx < l) + { + area = _glitz_pixel_area (l++, y0, + top, bottom, + &left, &right); + + ADD_LEFT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + lx, y0, l, y1, + area); + } + + /* Top Edge */ + while (l < r) + { + if (l < lspan || l >= rspan) + { + area = _glitz_pixel_area (l, y0, + top, bottom, + &left, &right); + + tmpx = l++; + + ADD_PIXEL (vptr, tptr, offset, size, + tmp0, + tbase, tsize, + tmpx, y0, l, y1, + area); + } + else + { + area = MIN (bottom, y1) - top; + ADD_TOP_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + lspan, y0, rspan, y1, + area); + l = rspan; + } + } + + /* Top/Right Edge intersection */ + if (rx > r) + { + area = _glitz_pixel_area (r, y0, + top, bottom, + &left, &right); + + ADD_RIGHT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + r, y0, rx, y1, + area); + } + } + else + { + y1lx = EDGE_X (&left, y1); + y1rx = EDGE_X (&right, y1); + } + + /* + BOTTOM rectangle + W + +--+------+---------+------------------+---------+----+----+ + | \ | | | | / | + | \ | | | |/ | + | \| | | /| | 1 + | |\ lEbE | bE | bErE / | | + | lE | +------+------------------|----+ | rE | + | | | | | | + +---------+---------+------------------+---------+---------+ + + The following set sub-rectangles might need to be generated + to render the bottom span of the trapezoid correctly. + + lE = Left Edge + bE = Top Edge + rE = Right Edge + lEbE = Left/Bottom Edge intersection + bErE = Bottom/Right Edge intersection + */ + + y2 = floorf (bottom); + if (y2 != bottom && y2 >= y1) + { + y3 = ceilf (bottom); + lx = x1; + rx = x2; + + if (y2 > y1) + { + y2lx = EDGE_X (&left, y2); + y2rx = EDGE_X (&right, y2); + } + else + { + y2lx = y1lx; + y2rx = y1rx; + } + + l = MAX (left.bx, y2lx); + r = MIN (right.bx, y2rx); + + lspan = ceilf (l); + rspan = floorf (r); + + l = floorf (l); + if (l > rspan) + l = rspan; + + r = ceilf (r); + if (r < lspan) + r = lspan; + + /* Left Edge */ + if (l > x1) + { + lx = EDGE_X (&left, y3); + if (y2lx > left.bx) + { + tmpx = y2lx + (left.bx - lx); + lx = left.bx; + } else + tmpx = y2lx; + + ADD_LEFT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &left, + x1, y2, l, y3, + tmpx, lx); + lx = l; + } + + /* Right Edge */ + if (r < x2) + { + rx = EDGE_X (&right, y3); + if (y2rx < right.bx) + { + tmpx = y2rx - (rx - right.bx); + rx = right.bx; + } else + tmpx = y2rx; + + ADD_RIGHT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &right, + r, y2, x2, y3, + tmpx, rx); + rx = r; + } + + /* Left/Bottom Edge intersection */ + if (lx < l) + { + area = _glitz_pixel_area (l++, y2, + top, bottom, + &left, &right); + + ADD_LEFT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + lx, y2, l, y3, + area); + } + + /* Bottom Edge */ + while (l < r) + { + if (l < lspan || l >= rspan) + { + area = _glitz_pixel_area (l, y2, + top, bottom, + &left, &right); + + tmpx = l++; + + ADD_PIXEL (vptr, tptr, offset, size, + tmp0, + tbase, tsize, + tmpx, y2, l, y3, + area); + } + else + { + area = bottom - y2; + ADD_BOTTOM_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + lspan, y2, rspan, y3, + area); + l = rspan; + } + } + + /* Bottom/Right Edge intersection */ + if (rx > r) + { + area = _glitz_pixel_area (r, y2, + top, bottom, + &left, &right); + + ADD_RIGHT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + r, y2, rx, y3, + area); + } + } + else + { + y2lx = EDGE_X (&left, y2); + y2rx = EDGE_X (&right, y2); + } + + /* + MIDDLE rectangle + W + +---+---------------------------------+--------+------+ + | \ | / | + | \ | / | + | \ lE | / rE | H - TH - BH + | \ | / | + | \ | / | + +---------+---------------------------+--+------------+ + + The following set sub-rectangles might need to be generated + to render the middle span of the trapezoid correctly. + + lE = Left Edge + rE = Right Edge + + If floor (MIN (rE)) < ceil (MAX (lE)) a number of left and right + edges needs to be generated as pixels intersected by both edges + needs to be calculated separately in a middle span. + */ + if (y1 < y2) + { + left.tx = y1lx; + right.tx = y1rx; + + do { + if (left.tx > y2rx) + { + rx = lx = ceilf (left.tx); + if (right.dx) + y = floorf (EDGE_Y (&right, rx)); + else + y = y2; + } + else + { + rx = lx = floorf (MIN (right.tx, y2rx)); + if (left.dx) + y = floorf (EDGE_Y (&left, rx)); + else + y = y2; + } + + if (y == y1) + y = y1 + 1.0f; + + if (y > y1 && y < y2) + { + left.bx = EDGE_X (&left, y); + right.bx = EDGE_X (&right, y); + } + else + { + y = y2; + left.bx = y2lx; + right.bx = y2rx; + } + + if (lx > right.tx) + lx = floorf (right.tx); + + if (lx > right.bx) + lx = floorf (right.bx); + + if (rx < left.tx) + rx = ceilf (left.tx); + + if (rx < left.bx) + rx = ceilf (left.bx); + + /* Left Edge */ + if (lx > x1) + { + if (left.dx) + { + ADD_LEFT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &left, + x1, y1, lx, y, + left.tx, left.bx); + } + else + { + area = lx - left.x0; + ADD_LEFT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + x1, y1, lx, y, + area); + } + } + + /* Middle Span */ + while (lx < rx) + { + tmpy = y1; + tmpx = lx++; + + while (tmpy < y) + { + y0 = tmpy++; + area = _glitz_pixel_area (tmpx, y0, + y0, y2, + &left, &right); + + ADD_PIXEL (vptr, tptr, offset, size, + tmp0, + tbase, tsize, + tmpx, y0, lx, tmpy, + area); + } + } + + /* Right Edge */ + if (rx < x2) + { + if (right.dx) + { + ADD_RIGHT_EDGE (vptr, tptr, offset, size, + tmp0, tmp1, tmp2, tmp3, + tbase, tsize, &right, + rx, y1, x2, y, + right.tx, right.bx); + } + else + { + area = right.x0 - rx; + ADD_RIGHT_SPAN (vptr, tptr, offset, size, + tmp0, tmp1, + tbase, tsize, + rx, y1, x2, y, + area); + } + } + + left.tx = left.bx; + right.tx = right.bx; + y1 = y; + } while (y < y2); + } + + toff = offset; + } + + return toff; +} + +#undef ADD_RIGHT_EDGE +#undef ADD_LEFT_EDGE +#undef CALC_RIGHT_EDGE +#undef CALC_LEFT_EDGE +#undef CALC_EDGE +#undef ADD_BOTTOM_SPAN +#undef ADD_TOP_SPAN +#undef ADD_RIGHT_SPAN +#undef ADD_LEFT_SPAN +#undef CALC_SPAN +#undef ADD_PIXEL +#undef ADD_QUAD +#undef ADD_VERTEX +#undef TSKIP +#undef VSKIP +#undef BYTES_PER_QUAD +#undef BYTES_PER_VERTEX diff --git a/src/glitz_util.c b/src/glitz_util.c index 853eb7c..969c2d3 100644 --- a/src/glitz_util.c +++ b/src/glitz_util.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -51,9 +51,12 @@ static glitz_extension_map gl_extensions[] = { { 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_EXT_multi_draw_arrays", GLITZ_FEATURE_MULTI_DRAW_ARRAYS_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_ARB_pixel_buffer_object", + GLITZ_FEATURE_PIXEL_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 }, @@ -154,17 +157,30 @@ _glitz_gl_proc_address_lookup (glitz_backend_t *backend, if (backend->gl_version >= 1.3f) { backend->gl.active_texture = (glitz_gl_active_texture_t) get_proc_address ("glActiveTexture", closure); + backend->gl.client_active_texture = (glitz_gl_client_active_texture_t) + get_proc_address ("glClientActiveTexture", closure); } else { backend->gl.active_texture = (glitz_gl_active_texture_t) get_proc_address ("glActiveTextureARB", closure); + backend->gl.client_active_texture = (glitz_gl_client_active_texture_t) + get_proc_address ("glClientActiveTextureARB", closure); } - if (!backend->gl.active_texture) { + if ((!backend->gl.active_texture) || + (!backend->gl.client_active_texture)) { backend->feature_mask &= ~GLITZ_FEATURE_MULTITEXTURE_MASK; backend->feature_mask &= ~GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK; } } + if (backend->feature_mask & GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK) { + backend->gl.multi_draw_arrays = (glitz_gl_multi_draw_arrays_t) + get_proc_address ("glMultiDrawArraysEXT", closure); + + if (!backend->gl.multi_draw_arrays) + backend->feature_mask &= ~GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK; + } + if (backend->feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) { backend->gl.gen_programs = (glitz_gl_gen_programs_t) get_proc_address ("glGenProgramsARB", closure); @@ -278,8 +294,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) + glitz_float_t x, + glitz_float_t y) { gl->push_attrib (GLITZ_GL_TRANSFORM_BIT | GLITZ_GL_VIEWPORT_BIT); gl->matrix_mode (GLITZ_GL_PROJECTION); diff --git a/src/glitzint.h b/src/glitzint.h index af47e2c..8c6cb22 100644 --- a/src/glitzint.h +++ b/src/glitzint.h @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifndef GLITZINT_H_INCLUDED @@ -29,9 +29,23 @@ #include #include #include +#include #include "glitz.h" +#if defined(__APPLE__) || defined(__sun__) +# define floorf(a) floor (a) +# define ceilf(a) ceil (a) +# define sinf(a) sin (a) +# define cosf(a) cos (a) +# define tanf(a) tan (a) +# define asinf(a) asin (a) +# define acosf(a) acos (a) +# define atanf(a) atan (a) +# define atan2f(a, b) atan2 (a, b) +# define sqrtf(a) sqrt (a) +#endif + #if __GNUC__ >= 3 && defined(__ELF__) # define slim_hidden_proto(name) slim_hidden_proto1(name, INT_##name) # define slim_hidden_def(name) slim_hidden_def1(name, INT_##name) @@ -71,9 +85,6 @@ #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); @@ -88,6 +99,7 @@ typedef struct _glitz_gl_proc_address_list_t { 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_tex_coord_pointer_t tex_coord_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; @@ -142,6 +154,8 @@ typedef struct _glitz_gl_proc_address_list_t { /* extensions */ glitz_gl_blend_color_t blend_color; glitz_gl_active_texture_t active_texture; + glitz_gl_client_active_texture_t client_active_texture; + glitz_gl_multi_draw_arrays_t multi_draw_arrays; glitz_gl_gen_programs_t gen_programs; glitz_gl_delete_programs_t delete_programs; glitz_gl_program_string_t program_string; @@ -175,19 +189,22 @@ typedef int glitz_combine_type_t; #define GLITZ_COMBINE_TYPE_ARGB 1 #define GLITZ_COMBINE_TYPE_ARGB_ARGB 2 #define GLITZ_COMBINE_TYPE_ARGB_ARGBC 3 -#define GLITZ_COMBINE_TYPE_ARGB_SOLID 4 -#define GLITZ_COMBINE_TYPE_ARGB_SOLIDC 5 -#define GLITZ_COMBINE_TYPE_ARGBF 6 -#define GLITZ_COMBINE_TYPE_ARGBF_ARGB 7 -#define GLITZ_COMBINE_TYPE_ARGBF_ARGBC 8 -#define GLITZ_COMBINE_TYPE_ARGBF_SOLID 9 -#define GLITZ_COMBINE_TYPE_ARGBF_SOLIDC 10 -#define GLITZ_COMBINE_TYPE_SOLID 11 -#define GLITZ_COMBINE_TYPE_SOLID_ARGB 12 -#define GLITZ_COMBINE_TYPE_SOLID_ARGBC 13 -#define GLITZ_COMBINE_TYPE_SOLID_SOLID 14 -#define GLITZ_COMBINE_TYPE_SOLID_SOLIDC 15 -#define GLITZ_COMBINE_TYPES 16 +#define GLITZ_COMBINE_TYPE_ARGB_ARGBF 4 +#define GLITZ_COMBINE_TYPE_ARGB_SOLID 5 +#define GLITZ_COMBINE_TYPE_ARGB_SOLIDC 6 +#define GLITZ_COMBINE_TYPE_ARGBF 7 +#define GLITZ_COMBINE_TYPE_ARGBF_ARGB 8 +#define GLITZ_COMBINE_TYPE_ARGBF_ARGBC 9 +#define GLITZ_COMBINE_TYPE_ARGBF_ARGBF 10 +#define GLITZ_COMBINE_TYPE_ARGBF_SOLID 11 +#define GLITZ_COMBINE_TYPE_ARGBF_SOLIDC 12 +#define GLITZ_COMBINE_TYPE_SOLID 13 +#define GLITZ_COMBINE_TYPE_SOLID_ARGB 14 +#define GLITZ_COMBINE_TYPE_SOLID_ARGBC 15 +#define GLITZ_COMBINE_TYPE_SOLID_ARGBF 16 +#define GLITZ_COMBINE_TYPE_SOLID_SOLID 17 +#define GLITZ_COMBINE_TYPE_SOLID_SOLIDC 18 +#define GLITZ_COMBINE_TYPES 19 #define GLITZ_TEXTURE_NONE 0 #define GLITZ_TEXTURE_2D 1 @@ -225,10 +242,6 @@ typedef enum { GLITZ_DRAWABLE_CURRENT } glitz_constraint_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; @@ -295,10 +308,10 @@ glitz_region_union (glitz_region_t *region, typedef struct glitz_backend { glitz_drawable_t * - (*create_pbuffer) (void *drawable, - glitz_drawable_format_t *format, - glitz_pbuffer_attributes_t *attributes, - unsigned long mask); + (*create_pbuffer) (void *drawable, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); void (*destroy) (void *drawable); @@ -347,11 +360,11 @@ struct _glitz_drawable { #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; -} glitz_point_t; +typedef struct _glitz_vec2_t { + glitz_float_t v[2]; +} glitz_vec2_t; -typedef struct _glitz_vec_t { +typedef struct _glitz_vec4_t { glitz_float_t v[4]; } glitz_vec4_t; @@ -399,15 +412,50 @@ struct _glitz_buffer { glitz_drawable_t *drawable; }; +struct _glitz_multi_array { + int ref_count; + int size; + int n_arrays; + int *first; + int *sizes; + int *count; + int *span, *current_span; + glitz_vec2_t *off; +}; + +typedef struct _glitz_int_coordinate { + glitz_gl_enum_t type; + int size, offset; +} glitz_int_coordinate_t; + +typedef struct _glitz_vertex_info { + glitz_gl_enum_t prim; + glitz_gl_enum_t type; + glitz_int_coordinate_t src; + glitz_int_coordinate_t mask; +} glitz_vertex_info_t; + +typedef struct _glitz_bitmap_info { + glitz_bool_t top_down; + glitz_gl_int_t pad; + glitz_gl_ubyte_t *base; +} glitz_bitmap_info_t; + typedef struct _glitz_geometry { - 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_gl_float_t data[8]; + glitz_geometry_type_t type; + glitz_buffer_t *buffer; + glitz_gl_sizei_t stride; + glitz_gl_float_t data[8]; + glitz_gl_int_t first; + glitz_gl_int_t size; + glitz_gl_sizei_t count; + glitz_vec2_t off; + glitz_multi_array_t *array; + unsigned long attributes; + union { + glitz_vertex_info_t v; + glitz_bitmap_info_t b; + } u; } glitz_geometry_t; #define GLITZ_SURFACE_FLAG_SOLID_MASK (1L << 0) @@ -425,6 +473,12 @@ typedef struct _glitz_geometry { #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 GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK (1L << 15) +#define GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK (1L << 16) + +#define GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK \ + (GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK | \ + GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK) #define SURFACE_SOLID(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_MASK) @@ -446,12 +500,6 @@ typedef struct _glitz_geometry { #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_DAMAGE(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK) @@ -470,17 +518,6 @@ typedef struct _glitz_geometry { #define SURFACE_PROJECTIVE_TRANSFORM(surface) \ ((surface)->flags & GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK) -typedef struct _glitz_sample_offset { - glitz_float_t x; - glitz_float_t y; -} glitz_sample_offset_t; - -typedef struct _glitz_multi_sample_info { - glitz_sample_offset_t *offsets; - unsigned short *weights; - int n_samples; -} glitz_sample_info_t; - typedef struct _glitz_filter_params_t glitz_filter_params_t; typedef struct _glitz_matrix { @@ -503,12 +540,23 @@ struct _glitz_surface { glitz_filter_params_t *filter_params; glitz_matrix_t *transform; int x, y; - int width, height; + glitz_box_t box; + short x_clip, y_clip; + glitz_box_t *clip; + int n_clip; glitz_gl_enum_t buffer; unsigned long flags; - glitz_sample_info_t *indirect; glitz_color_t solid; glitz_geometry_t geometry; + void *arrays; + int n_arrays; + int *first; + unsigned int *count; + glitz_vec2_t *off; + int default_first; + unsigned int default_count; + glitz_vec2_t default_off; + int *primcount; glitz_region_t texture_damage; glitz_region_t drawable_damage; }; @@ -524,7 +572,7 @@ typedef struct _glitz_combine_t { glitz_combine_type_t type; glitz_combine_function_t enable; int texture_units; - int fragment_processing; + int source_shader; } glitz_combine_t; struct _glitz_composite_op_t { @@ -570,8 +618,8 @@ 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); + glitz_float_t x, + glitz_float_t y); extern void __internal_linkage glitz_clamp_value (glitz_float_t *value, @@ -599,7 +647,8 @@ glitz_texture_init (glitz_texture_t *texture, int width, int height, glitz_gl_int_t texture_format, - unsigned long feature_mask); + unsigned long feature_mask, + glitz_bool_t unnormalized); void glitz_texture_fini (glitz_gl_proc_address_list_t *gl, @@ -618,7 +667,7 @@ glitz_texture_allocate (glitz_gl_proc_address_list_t *gl, extern void __internal_linkage glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl, glitz_texture_t *texture, - glitz_filter_t filter); + glitz_gl_enum_t filter); extern void __internal_linkage glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl, @@ -647,11 +696,13 @@ glitz_texture_copy_drawable (glitz_gl_proc_address_list_t *gl, void glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl, glitz_texture_t *texture, + glitz_geometry_t *geometry, int x_src, int y_src, - unsigned long flags); + unsigned long flags, + glitz_int_coordinate_t *coord); -extern glitz_texture_t *__internal_linkage +extern glitz_texture_t __internal_linkage * glitz_surface_get_texture (glitz_surface_t *surface, glitz_bool_t allocate); @@ -708,7 +759,7 @@ glitz_composite_enable (glitz_composite_op_t *op); extern void __internal_linkage glitz_composite_disable (glitz_composite_op_t *op); -extern void *__internal_linkage +extern void __internal_linkage * glitz_buffer_bind (glitz_buffer_t *buffer, glitz_gl_enum_t target); @@ -725,9 +776,6 @@ extern void __internal_linkage glitz_filter_set_type (glitz_surface_t *surface, 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_composite_op_t *op); @@ -741,22 +789,24 @@ 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_box_t *box); +glitz_geometry_enable_none (glitz_gl_proc_address_list_t *gl, + 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_box_t *box); extern void __internal_linkage -glitz_geometry_disable (glitz_gl_proc_address_list_t *gl, - glitz_surface_t *dst); +glitz_geometry_disable (glitz_surface_t *dst); +extern void __internal_linkage +glitz_geometry_draw_arrays (glitz_gl_proc_address_list_t *gl, + glitz_surface_t *dst, + glitz_geometry_type_t type, + glitz_box_t *bounds, + int damage); #define MAXSHORT SHRT_MAX #define MINSHORT SHRT_MIN @@ -856,9 +906,16 @@ slim_hidden_proto(glitz_surface_get_status) 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_surface_translate_point) +slim_hidden_proto(glitz_surface_set_clip_region) slim_hidden_proto(glitz_set_rectangle) slim_hidden_proto(glitz_set_rectangles) slim_hidden_proto(glitz_set_geometry) +slim_hidden_proto(glitz_set_array) +slim_hidden_proto(glitz_multi_array_create) +slim_hidden_proto(glitz_multi_array_add) +slim_hidden_proto(glitz_multi_array_reset) +slim_hidden_proto(glitz_set_multi_array) slim_hidden_proto(glitz_buffer_set_data) slim_hidden_proto(glitz_buffer_get_data) diff --git a/src/glx/glitz-glx.h b/src/glx/glitz-glx.h index 818906c..cdfebb4 100644 --- a/src/glx/glitz-glx.h +++ b/src/glx/glitz-glx.h @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifndef GLITZ_GLX_H_INCLUDED @@ -66,15 +66,15 @@ glitz_glx_create_drawable_for_window (Display *display, int screen, glitz_drawable_format_t *format, Window window, - int width, - int height); + unsigned int width, + unsigned 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); +glitz_glx_create_pbuffer_drawable (Display *display, + int screen, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); #if defined(__cplusplus) || defined(c_plusplus) diff --git a/src/glx/glitz_glx_context.c b/src/glx/glitz_glx_context.c index b251ee2..b28f149 100644 --- a/src/glx/glitz_glx_context.c +++ b/src/glx/glitz_glx_context.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H diff --git a/src/glx/glitz_glx_drawable.c b/src/glx/glitz_glx_drawable.c index 7c70a14..e6c2232 100644 --- a/src/glx/glitz_glx_drawable.c +++ b/src/glx/glitz_glx_drawable.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -80,14 +80,13 @@ _glitz_glx_create_drawable (glitz_glx_screen_info_t *screen_info, } 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_create_pbuffer_drawable (glitz_glx_screen_info_t *screen_info, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { glitz_glx_drawable_t *drawable; glitz_glx_context_t *context; - unsigned int width, height; GLXPbuffer pbuffer; if (!format->types.pbuffer) @@ -98,8 +97,7 @@ _glitz_glx_create_pbuffer_drawable (glitz_glx_screen_info_t *screen_info, return NULL; pbuffer = glitz_glx_pbuffer_create (screen_info, context->fbconfig, - attributes, mask, - &width, &height); + (int) width, (int) height); if (!pbuffer) return NULL; @@ -115,15 +113,15 @@ _glitz_glx_create_pbuffer_drawable (glitz_glx_screen_info_t *screen_info, } 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_create_pbuffer (void *abstract_templ, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { glitz_glx_drawable_t *templ = (glitz_glx_drawable_t *) abstract_templ; return _glitz_glx_create_pbuffer_drawable (templ->screen_info, format, - attributes, mask); + width, height); } glitz_drawable_t * @@ -131,8 +129,8 @@ glitz_glx_create_drawable_for_window (Display *display, int screen, glitz_drawable_format_t *format, Window window, - int width, - int height) + unsigned int width, + unsigned int height) { glitz_glx_drawable_t *drawable; glitz_glx_screen_info_t *screen_info; @@ -157,11 +155,11 @@ glitz_glx_create_drawable_for_window (Display *display, 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_create_pbuffer_drawable (Display *display, + int screen, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height) { glitz_glx_screen_info_t *screen_info; @@ -170,7 +168,7 @@ glitz_glx_create_pbuffer_drawable (Display *display, return NULL; return _glitz_glx_create_pbuffer_drawable (screen_info, format, - attributes, mask); + width, height); } slim_hidden_def(glitz_glx_create_pbuffer_drawable); diff --git a/src/glx/glitz_glx_extension.c b/src/glx/glitz_glx_extension.c index efa089f..42d6748 100644 --- a/src/glx/glitz_glx_extension.c +++ b/src/glx/glitz_glx_extension.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H diff --git a/src/glx/glitz_glx_format.c b/src/glx/glitz_glx_format.c index f4aaf0b..563bb74 100644 --- a/src/glx/glitz_glx_format.c +++ b/src/glx/glitz_glx_format.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H diff --git a/src/glx/glitz_glx_info.c b/src/glx/glitz_glx_info.c index 47bef56..0e95e8d 100644 --- a/src/glx/glitz_glx_info.c +++ b/src/glx/glitz_glx_info.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -42,6 +42,7 @@ glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address = { (glitz_gl_enable_client_state_t) glEnableClientState, (glitz_gl_disable_client_state_t) glDisableClientState, (glitz_gl_vertex_pointer_t) glVertexPointer, + (glitz_gl_tex_coord_pointer_t) glTexCoordPointer, (glitz_gl_draw_arrays_t) glDrawArrays, (glitz_gl_tex_env_f_t) glTexEnvf, (glitz_gl_tex_env_fv_t) glTexEnvfv, @@ -96,6 +97,8 @@ glitz_gl_proc_address_list_t _glitz_glx_gl_proc_address = { /* extensions */ (glitz_gl_blend_color_t) 0, (glitz_gl_active_texture_t) 0, + (glitz_gl_client_active_texture_t) 0, + (glitz_gl_multi_draw_arrays_t) 0, (glitz_gl_gen_programs_t) 0, (glitz_gl_delete_programs_t) 0, (glitz_gl_program_string_t) 0, diff --git a/src/glx/glitz_glx_pbuffer.c b/src/glx/glitz_glx_pbuffer.c index 9506322..3af899f 100644 --- a/src/glx/glitz_glx_pbuffer.c +++ b/src/glx/glitz_glx_pbuffer.c @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifdef HAVE_CONFIG_H @@ -30,49 +30,30 @@ #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) +glitz_glx_pbuffer_create (glitz_glx_screen_info_t *screen_info, + GLXFBConfig fbconfig, + int width, + int height) { if (fbconfig) { - GLXPbuffer pbuffer; - int pbuffer_attr[13]; - int i = 0; + int attributes[9]; - 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; + attributes[0] = GLX_PBUFFER_WIDTH; + attributes[1] = 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; + attributes[2] = GLX_PBUFFER_HEIGHT; + attributes[3] = height; - pbuffer_attr[i++] = GLX_LARGEST_PBUFFER; - pbuffer_attr[i++] = 1; + attributes[4] = GLX_LARGEST_PBUFFER; + attributes[5] = 0; - pbuffer_attr[i++] = GLX_PRESERVED_CONTENTS; - pbuffer_attr[i++] = 1; - pbuffer_attr[i++] = 0; + attributes[6] = GLX_PRESERVED_CONTENTS; + attributes[7] = 1; + attributes[8] = 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; + return + screen_info->glx.create_pbuffer (screen_info->display_info->display, + fbconfig, attributes); } else return (GLXPbuffer) 0; } diff --git a/src/glx/glitz_glxext.h b/src/glx/glitz_glxext.h index 9d3bea4..fd8bde0 100644 --- a/src/glx/glitz_glxext.h +++ b/src/glx/glitz_glxext.h @@ -1,5 +1,5 @@ /* - * Copyright © 2004 David Reveman, Peter Nilsson + * 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 @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * - * Authors: David Reveman + * Authors: David Reveman * Peter Nilsson */ diff --git a/src/glx/glitz_glxint.h b/src/glx/glitz_glxint.h index 9814511..27190cc 100644 --- a/src/glx/glitz_glxint.h +++ b/src/glx/glitz_glxint.h @@ -1,11 +1,11 @@ /* - * Copyright © 2004 David Reveman + * 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 + * appear in supporting documentation, and that the name of * David Reveman not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * David Reveman makes no representations about the suitability of this @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Author: David Reveman + * Author: David Reveman */ #ifndef GLITZ_GLXINT_H_INCLUDED @@ -121,7 +121,7 @@ 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 +extern glitz_glx_screen_info_t __internal_linkage * glitz_glx_screen_info_get (Display *display, int screen); @@ -129,7 +129,7 @@ extern glitz_function_pointer_t __internal_linkage glitz_glx_get_proc_address (const char *name, void *closure); -extern glitz_glx_context_t *__internal_linkage +extern glitz_glx_context_t __internal_linkage * glitz_glx_context_get (glitz_glx_screen_info_t *screen_info, glitz_drawable_format_t *format); @@ -143,27 +143,25 @@ 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); + int width, + 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 glitz_drawable_t __internal_linkage * +glitz_glx_create_pbuffer (void *abstract_templ, + glitz_drawable_format_t *format, + unsigned int width, + unsigned int height); 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 +extern glitz_surface_t __internal_linkage * glitz_glx_pop_current (void *abstract_drawable); extern glitz_status_t __internal_linkage -- cgit v1.2.3