summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog118
-rw-r--r--README22
-rw-r--r--TODO12
-rw-r--r--configure.in30
-rw-r--r--src/glitz.c1028
-rw-r--r--src/glitz.h99
-rw-r--r--src/glitz_agl_context.c8
-rw-r--r--src/glitz_agl_extension.c27
-rw-r--r--src/glitz_agl_info.c60
-rw-r--r--src/glitz_agl_surface.c4
-rw-r--r--src/glitz_aglint.h23
-rw-r--r--src/glitz_color_range.c108
-rw-r--r--src/glitz_format.c16
-rw-r--r--src/glitz_gl.h155
-rw-r--r--src/glitz_glx_context.c76
-rw-r--r--src/glitz_glx_extension.c27
-rw-r--r--src/glitz_glx_info.c71
-rw-r--r--src/glitz_glx_surface.c74
-rw-r--r--src/glitz_glxext.h6
-rw-r--r--src/glitz_glxint.h19
-rw-r--r--src/glitz_pixel.c411
-rw-r--r--src/glitz_program.c1106
-rw-r--r--src/glitz_programmatic.c113
-rw-r--r--src/glitz_render.c819
-rw-r--r--src/glitz_surface.c39
-rw-r--r--src/glitz_texture.c4
-rw-r--r--src/glitzint.h321
27 files changed, 2835 insertions, 1961 deletions
diff --git a/ChangeLog b/ChangeLog
index fa6da77..bb7cb5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,121 @@
+2004-07-20 David Reveman <c99drn@cs.umu.se>
+
+ * src/glitzint.h: Added glTexEnvfv, glColor4d and pixel buffer
+ functions to glitz_gl_proc_address_list_t.
+ Moved some stuff into glitz_color_range.c.
+ Added new glitz_render_op_t infrastructure.
+ Added component-alpha support.
+ Fixed some macros.
+ Added reference counting to glitz_surface_t.
+ programs -> program_map.
+ SHORT_MODULATE -> SHORT_MULT.
+
+ * src/glitz_surface.c (glitz_surface_init): programs -> program_map.
+ Added reference counting to surfaces.
+ Added glitz_surface_set_component_alpha.
+
+ * src/glitz_render.c: Added new glitz_render_op_t infrastructure.
+ This is a major improvement to the old mess. This new infrastructure
+ scales very well, is much easier to understand and is more efficient.
+
+ * src/glitz_programmatic.c: GLITZ_PROGRAMMATIC_SURFACE_LINEAR_TYPE ->
+ GLITZ_PROGRAMMATIC_SURFACE_TYPE_LINEAR and
+ GLITZ_PROGRAMMATIC_SURFACE_RADIAL_TYPE ->
+ GLITZ_PROGRAMMATIC_SURFACE_TYPE_RADIAL.
+ (_glitz_programmatic_surface_create): Use MAXSHORT for static surface
+ size.
+ Removed glitz_programmatic_surface_setup.
+ Removed glitz_programmatic_surface_bind as that code should now be
+ in glitz_render.c.
+
+ * src/glitz_program.c: Cleaned up and moved some that should be in
+ glitz_render.c. Added support for component-alpha.
+
+ * src/glitz_pixel.c: Added new pixel buffer interface, which
+ allows for asynchronous pixel transfers and access to
+ high-performance memory. Modified pixel transfer functions
+ to use the new pixel buffer interface.
+
+ * src/glitz_glxint.h: Added
+ GLITZ_GLX_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK,
+ GLITZ_GLX_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK,
+ GLITZ_GLX_FEATURE_PIXEL_BUFFER_OBJECT_MASK;
+ programs -> program_map.
+
+ * src/glitz_glx_surface.c (_glitz_glx_set_features): Better check
+ for multi-texturing and check pixel buffer object extension
+ support.
+ programs -> program_map.
+
+ * src/glitz_glx_info.c: Added glTexEnvfv, glColor4d and pixel buffer
+ functions to _glitz_glx_gl_proc_address.
+ (glitz_glx_thread_info_get): Fixed thread specific data
+ allocation.
+ (glitz_glx_display_destroy): Fixed memory leak.
+ (glitz_glx_screen_info_get): Use glitz_program_map_init to
+ initialize program map.
+ (glitz_glx_screen_destroy): Use glitz_program_map_fini to
+ clean up program map.
+
+ * src/glitz_glx_extension.c: Check for GL_ARB_texture_env_combine,
+ GL_ARB_texture_env_dot3 and GL_EXT_pixel_buffer_object.
+
+ * src/glitz_glx_context.c (glitz_glx_context_proc_address_lookup):
+ Lookup pixel buffer object function pointers.
+
+ * src/glitz_gl.h: Added a bunch of new tokens and function
+ declarations.
+
+ * src/glitz_format.c: OpenGL GL_ALPHA formats are now used for
+ alpha textures instead of GL_INTENSITY.
+
+ * src/glitz_color_range.c: Moved some stuff from glitzint.h to this
+ file and use the new pixel buffer interface for asynchronous
+ color range data transfers.
+
+ * src/glitz_aglint.h: Added
+ GLITZ_AGL_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK,
+ GLITZ_AGL_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK,
+ GLITZ_AGL_FEATURE_PIXEL_BUFFER_OBJECT_MASK.
+ programs -> program_map.
+
+ * src/glitz_agl_surface.c: programs -> program_map.
+
+ * src/glitz_agl_info.c: Added glTexEnvfv, glColor4d and pixel buffer
+ functions to _glitz_agl_gl_proc_address.
+ (glitz_agl_thread_info_get): Fixed thread specific data
+ allocation.
+ (glitz_agl_thread_info_init): Use glitz_program_map_init to
+ initialize program map.
+ (glitz_agl_thread_info_fini): Use glitz_program_map_fini to
+ clean up program map.
+ (glitz_agl_thread_info_fini): Do not free thread specific data here.
+
+ * src/glitz_agl_extension.c: Check for GL_ARB_texture_env_combine,
+ GL_ARB_texture_env_dot3 and GL_EXT_pixel_buffer_object.
+
+ * src/glitz.h: glitz_color_range_create now needs a surface
+ reference.
+ Added glitz_surface_set_component_alpha.
+ Added skip_lines to glitz_pixel_format_t.
+ Added new pixel buffer interface, which allows for asynchronous
+ pixel transfers and access to high-performance memory.
+
+ * src/glitz.h: Added GLITZ_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK,
+ GLITZ_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK,
+ GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK,
+ GLITZ_FEATURE_COMPONENT_ALPHA_MASK.
+
+ * src/glitz.c: Moved in my new glitz.c code, much of it is similar
+ to the old glitz.c code. However, this new code uses the new
+ glitz_render_op_t infrastructure and supports component alpha.
+
+ * configure.in: Added GCC warning flags.
+
+ * TODO: Updated todo list.
+
+ * README: Added a short description of glitz.
+
2004-06-21 David Reveman <c99drn@cs.umu.se>
* src/glitz.h (GLITZ_REVISION): Bump version to 0.1.5.
diff --git a/README b/README
index 27319e8..597cc35 100644
--- a/README
+++ b/README
@@ -1 +1,21 @@
-glitz - OpenGL compositing library
+glitz - OpenGL image compositing library
+
+Glitz is an OpenGL image compositing library. Glitz provides
+Porter/Duff compositing of images and implicit mask generation for
+geometric primitives including trapezoids, triangles, and rectangles.
+
+The semantics of glitz are designed to precisely match the
+specification of the X Render extension. Glitz does not only implement
+X Render features like component alpha and image transformations, but
+also support additional features like convolution filters and color
+gradients, which are not currently part of the X Render specification.
+
+The performance and capabilities of glitz are much dependent on
+graphics hardware. Glitz does not in any way handle software
+fall-backs when graphics hardware is insufficient. However, glitz
+will report if any requested operation cannot be carried out by
+graphics hardware, hence making a higher level software layer
+responsible for appropriate actions.
+
+David Reveman
+c99drn@cs.umu.se
diff --git a/TODO b/TODO
index 6a760c4..ea907ef 100644
--- a/TODO
+++ b/TODO
@@ -1,11 +1,9 @@
-* Text support. Glyph set management, glyph and string compositing
- operations. Some ideas: Multi-texturing for compositing multiple glyphs
- per render pass, Sub-pixel rendering, vector text; glyphs loaded into
- display lists.
-
-* A programmable surface type which can store a set of rendering operations
- in a display list.
+* GL_MESA_pack_invert support.
* Projective transformations.
+* Retained-mode rendering.
+
* WGL (Windows GL) backend.
+
+* Mesa-solo backend.
diff --git a/configure.in b/configure.in
index e5a8ca9..935dd00 100644
--- a/configure.in
+++ b/configure.in
@@ -46,6 +46,36 @@ if test "x$GCC" = "xyes"; then
*) CFLAGS="$CFLAGS -Wall" ;;
esac
+ case " $CFLAGS " in
+ *[[\ \ ]]-Wpointer-arith[[\ \ ]]*) ;;
+ *) CFLAGS="$CFLAGS -Wpointer-arith" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[[\ \ ]]-Wstrict-prototypes[[\ \ ]]*) ;;
+ *) CFLAGS="$CFLAGS -Wstrict-prototypes" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[[\ \ ]]-Wmissing-prototypes[[\ \ ]]*) ;;
+ *) CFLAGS="$CFLAGS -Wmissing-prototypes" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[[\ \ ]]-Wmissing-declarations[[\ \ ]]*) ;;
+ *) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[[\ \ ]]-Wnested-externs[[\ \ ]]*) ;;
+ *) CFLAGS="$CFLAGS -Wnested-externs" ;;
+ esac
+
+ case " $CFLAGS " in
+ *[[\ \ ]]-fno-strict-aliasing[[\ \ ]]*) ;;
+ *) CFLAGS="$CFLAGS -fno-strict-aliasing" ;;
+ esac
+
if test "x$enable_ansi" = "xyes"; then
case " $CFLAGS " in
*[[\ \ ]]-ansi[[\ \ ]]*) ;;
diff --git a/src/glitz.c b/src/glitz.c
index ce90099..861b633 100644
--- a/src/glitz.c
+++ b/src/glitz.c
@@ -1,28 +1,26 @@
/*
- * Copyright © 2004 David Reveman, Peter Nilsson
- *
+ * Copyright © 2004 David Reveman
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the names of
- * David Reveman and Peter Nilsson not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. David Reveman and Peter Nilsson
- * makes no representations about the suitability of this software for
- * any purpose. It is provided "as is" without express or implied warranty.
+ * David Reveman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * David Reveman makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
*
- * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
- * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
- * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Authors: David Reveman <c99drn@cs.umu.se>
- * Peter Nilsson <c99pnn@cs.umu.se>
+ * Author: David Reveman <c99drn@cs.umu.se>
*/
#ifdef HAVE_CONFIG_H
@@ -31,259 +29,6 @@
#include "glitzint.h"
-#include <math.h>
-
-#define SURFACE_GLREPEAT(surface, texture) \
- (SURFACE_REPEAT (surface) && texture->repeatable)
-
-#define SURFACE_MANUALREPEAT(surface, texture) \
- ((surface->hint_mask & GLITZ_INT_HINT_REPEAT_MASK) && (!texture->repeatable))
-
-#define SURFACE_ROTATE(surface) \
- (surface->transform && \
- ((surface->transform->m[0][1] != 0.0) || \
- (surface->transform->m[1][0] != 0.0)))
-
-/* This version of composite uses multi-texturing for direct
- Porter-Duff compositing. It cannot handle rotating transformations
- and will fall back to regular composite function if this is the case. */
-static glitz_bool_t
-_glitz_composite_direct (glitz_operator_t op,
- glitz_surface_t *src,
- glitz_surface_t *mask,
- glitz_surface_t *dst,
- int x_src,
- int y_src,
- int x_mask,
- int y_mask,
- int x_dst,
- int y_dst,
- int width,
- int height)
-{
- glitz_gl_proc_address_list_t *gl;
- glitz_texture_t *src_texture;
- glitz_texture_t *mask_texture;
- glitz_bounding_box_double_t src_box, mask_box, dst_box;
- glitz_bounding_box_t dirty_box;
- glitz_point_t src_tl, src_br, mask_tl, mask_br;
- glitz_render_type_t type;
-
- gl = dst->gl;
-
- type = glitz_render_type (src, mask, dst);
-
- if (type == GLITZ_RENDER_TYPE_NOT_SUPPORTED)
- return 0;
-
- /* We cannot continue if we have a rotating transformation. */
- if (SURFACE_ROTATE (src) || SURFACE_ROTATE (mask))
- return 0;
-
- src_texture = glitz_surface_get_texture (src);
- mask_texture = glitz_surface_get_texture (mask);
-
- /* Texture has not been allocated, hence source and the result of this
- operation is undefined. So lets do nothing. */
- if ((!src_texture) || (!mask_texture))
- return 1;
-
- if (SURFACE_MANUALREPEAT (src, src_texture) ||
- SURFACE_MANUALREPEAT (mask, mask_texture))
- return 0;
-
- if (!glitz_surface_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) {
- glitz_surface_pop_current (dst);
- return 0;
- }
-
- gl->disable (GLITZ_GL_SCISSOR_TEST);
-
- glitz_render_enable (type,
- src, mask, dst,
- src_texture, mask_texture, 0xffff);
-
- glitz_set_operator (gl, op);
-
- gl->active_texture_arb (GLITZ_GL_TEXTURE0_ARB);
- glitz_texture_bind (gl, src_texture);
-
- gl->tex_env_f (GLITZ_GL_TEXTURE_ENV,
- GLITZ_GL_TEXTURE_ENV_MODE,
- GLITZ_GL_REPLACE);
-
- if (src->transform)
- glitz_texture_ensure_filter (gl, src_texture, src->filter);
- else
- glitz_texture_ensure_filter (gl, src_texture, GLITZ_FILTER_NEAREST);
-
- glitz_texture_ensure_repeat (gl,
- src_texture,
- src->hint_mask & GLITZ_INT_HINT_REPEAT_MASK);
-
- dst->gl->active_texture_arb (GLITZ_GL_TEXTURE1_ARB);
- glitz_texture_bind (gl, mask_texture);
-
- gl->tex_env_f (GLITZ_GL_TEXTURE_ENV,
- GLITZ_GL_TEXTURE_ENV_MODE,
- GLITZ_GL_MODULATE);
-
- if (mask->transform)
- glitz_texture_ensure_filter (gl, mask_texture, mask->filter);
- else
- glitz_texture_ensure_filter (gl, mask_texture, GLITZ_FILTER_NEAREST);
-
- dst_box.x1 = x_dst;
- dst_box.y1 = y_dst;
- dst_box.x2 = dst_box.x1 + width;
- dst_box.y2 = dst_box.y1 + height;
-
- if (!SURFACE_REPEAT (src)) {
- src_box.x1 = src_box.y1 = 0.0;
- src_box.x2 = src->width;
- src_box.y2 = src->height;
-
- if (src->transform)
- glitz_matrix_transform_bounding_box (src->transform,
- &src_box.x1, &src_box.y1,
- &src_box.x2, &src_box.y2);
-
- src_box.x1 += x_dst - x_src;
- src_box.x2 += x_dst - x_src;
- src_box.y1 += y_dst - y_src;
- src_box.y2 += y_dst - y_src;
-
- if (!SURFACE_PROGRAMMATIC (src))
- glitz_intersect_bounding_box_double (&dst_box, &src_box, &dst_box);
- }
-
- if (!SURFACE_REPEAT (mask)) {
- mask_box.x1 = mask_box.y1 = 0.0;
- mask_box.x2 = mask->width;
- mask_box.y2 = mask->height;
-
- if (mask->transform)
- glitz_matrix_transform_bounding_box (mask->transform,
- &mask_box.x1, &mask_box.y1,
- &mask_box.x2, &mask_box.y2);
-
- mask_box.x1 += x_dst - x_mask;
- mask_box.x2 += x_dst - x_mask;
- mask_box.y1 += y_dst - y_mask;
- mask_box.y2 += y_dst - y_mask;
-
- if (!SURFACE_PROGRAMMATIC (mask))
- glitz_intersect_bounding_box_double (&dst_box, &mask_box, &dst_box);
- }
-
- if ((dst_box.x2 - dst_box.x1) <= 0 || (dst_box.y2 - dst_box.y1) <= 0)
- return 1;
-
- if (SURFACE_REPEAT (src)) {
- src_br.y = src->height -
- (((y_src % src->height) + (int) (dst_box.y2 - dst_box.y1)) %
- src->height);
- src_tl.y = (dst_box.y2 - dst_box.y1) + src_br.y;
- src_tl.x = x_src % src->width;
- src_br.x = (dst_box.x2 - dst_box.x1) + src_tl.x;
- } else {
- glitz_intersect_bounding_box_double (&src_box, &dst_box, &src_box);
-
- src_tl.x = src_box.x1 - x_dst + x_src;
- src_br.x = src_box.x2 - x_dst + x_src;
- src_tl.y = src_box.y1 - y_dst + y_src;
- src_br.y = src_box.y2 - y_dst + y_src;
-
- if (src->transform) {
- glitz_matrix_transform_point (src->inverse_transform,
- &src_tl.x, &src_tl.y);
- glitz_matrix_transform_point (src->inverse_transform,
- &src_br.x, &src_br.y);
- }
- }
-
- src_tl.x = (src_tl.x / src->width) * src_texture->texcoord_width;
- src_tl.y = (src_tl.y / src->height) * src_texture->texcoord_height;
- src_br.x = (src_br.x / src->width) * src_texture->texcoord_width;
- src_br.y = (src_br.y / src->height) * src_texture->texcoord_height;
-
- if (!SURFACE_REPEAT (src)) {
- src_tl.y = src_texture->texcoord_height - src_tl.y;
- src_br.y = src_texture->texcoord_height - src_br.y;
- }
-
- if (SURFACE_REPEAT (mask)) {
- mask_br.y = mask->height -
- (((y_mask % mask->height) + (int) (dst_box.y2 - dst_box.y1)) %
- mask->height);
- mask_tl.y = (dst_box.y2 - dst_box.y1) + mask_br.y;
- mask_tl.x = x_mask % mask->width;
- mask_br.x = (dst_box.x2 - dst_box.x1) + mask_tl.x;
- } else {
- glitz_intersect_bounding_box_double (&mask_box, &dst_box, &mask_box);
-
- mask_tl.x = mask_box.x1 - x_dst + x_mask;
- mask_br.x = mask_box.x2 - x_dst + x_mask;
- mask_tl.y = mask_box.y1 - y_dst + y_mask;
- mask_br.y = mask_box.y2 - y_dst + y_mask;
-
- if (mask->transform) {
- glitz_matrix_transform_point (mask->inverse_transform,
- &mask_tl.x, &mask_tl.y);
- glitz_matrix_transform_point (mask->inverse_transform,
- &mask_br.x, &mask_br.y);
- }
- }
-
- mask_tl.x = (mask_tl.x / mask->width) * mask_texture->texcoord_width;
- mask_tl.y = (mask_tl.y / mask->height) * mask_texture->texcoord_height;
- mask_br.x = (mask_br.x / mask->width) * mask_texture->texcoord_width;
- mask_br.y = (mask_br.y / mask->height) * mask_texture->texcoord_height;
-
- if (!SURFACE_REPEAT (mask)) {
- mask_tl.y = mask_texture->texcoord_height - mask_tl.y;
- mask_br.y = mask_texture->texcoord_height - mask_br.y;
- }
-
- gl->begin (GLITZ_GL_QUADS);
-
- gl->multi_tex_coord_2d_arb (GLITZ_GL_TEXTURE0_ARB, src_tl.x, src_tl.y);
- gl->multi_tex_coord_2d_arb (GLITZ_GL_TEXTURE1_ARB, mask_tl.x, mask_tl.y);
- gl->vertex_2d (dst_box.x1, dst_box.y1);
-
- gl->multi_tex_coord_2d_arb (GLITZ_GL_TEXTURE0_ARB, src_br.x, src_tl.y);
- gl->multi_tex_coord_2d_arb (GLITZ_GL_TEXTURE1_ARB, mask_br.x, mask_tl.y);
- gl->vertex_2d (dst_box.x2, dst_box.y1);
-
- gl->multi_tex_coord_2d_arb (GLITZ_GL_TEXTURE0_ARB, src_br.x, src_br.y);
- gl->multi_tex_coord_2d_arb (GLITZ_GL_TEXTURE1_ARB, mask_br.x, mask_br.y);
- gl->vertex_2d (dst_box.x2, dst_box.y2);
-
- gl->multi_tex_coord_2d_arb (GLITZ_GL_TEXTURE0_ARB, src_tl.x, src_br.y);
- gl->multi_tex_coord_2d_arb (GLITZ_GL_TEXTURE1_ARB, mask_tl.x, mask_br.y);
- gl->vertex_2d (dst_box.x1, dst_box.y2);
-
- gl->end ();
-
- gl->active_texture_arb (GLITZ_GL_TEXTURE1_ARB);
- glitz_texture_unbind (gl, mask_texture);
-
- gl->active_texture_arb (GLITZ_GL_TEXTURE0_ARB);
- glitz_texture_unbind (gl, src_texture);
-
- glitz_render_disable (type, dst);
-
- dirty_box.x1 = floor (dst_box.x1);
- dirty_box.y1 = floor (dst_box.y1);
- dirty_box.x2 = ceil (dst_box.x2);
- dirty_box.y2 = ceil (dst_box.y2);
- glitz_surface_dirty (dst, &dirty_box);
-
- glitz_surface_pop_current (dst);
-
- return 1;
-}
-
static void
glitz_mask_bounds (glitz_surface_t *src,
glitz_surface_t *mask,
@@ -375,6 +120,13 @@ glitz_mask_bounds (glitz_surface_t *src,
}
}
+glitz_gl_uint_t _texture_units[] = {
+ 0,
+ GLITZ_GL_TEXTURE0,
+ GLITZ_GL_TEXTURE1,
+ GLITZ_GL_TEXTURE2
+};
+
typedef enum {
GLITZ_REPEAT_NONE = 0,
GLITZ_REPEAT_SOUTHEAST,
@@ -397,49 +149,27 @@ glitz_composite (glitz_operator_t op,
int width,
int height)
{
- glitz_gl_proc_address_list_t *gl;
+ glitz_gl_proc_address_list_t *gl = dst->gl;
glitz_surface_t *intermediate = NULL;
- glitz_texture_t *texture;
+ glitz_texture_t *texture, *mask_texture = NULL;
glitz_point_t tl, bl, br, tr;
glitz_bounding_box_t clip;
- glitz_render_type_t type;
+ glitz_render_op_t render_op;
glitz_gl_uint_t list = 0;
- unsigned short opacity = 0xffff;
-
- gl = dst->gl;
+ int texture_unit = 0;
- if (SURFACE_PROGRAMMATIC (src))
- glitz_programmatic_surface_setup (src,
- width + abs (x_src),
- height + abs (y_src));
-
- if (mask) {
- if (SURFACE_PROGRAMMATIC (mask)) {
- glitz_programmatic_surface_setup (mask,
- width + abs (x_mask),
- height + abs (y_mask));
-
- if (SURFACE_SOLID (mask)) {
- opacity = ((glitz_programmatic_surface_t *) mask)->u.solid.color.alpha;
- mask = NULL;
- }
- }
+ glitz_render_op_init (&render_op, &src, &mask, dst,
+ &x_src, &y_src, &x_mask, &y_mask);
+ if (render_op.type == GLITZ_RENDER_TYPE_NA) {
+ glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK);
+ return;
}
-
- if (mask) {
+
+ if (render_op.type == GLITZ_RENDER_TYPE_INTERMEDIATE) {
glitz_bounding_box_t dst_bounds, mask_bounds;
glitz_intermediate_t intermediate_type;
static glitz_color_t clear_color = { 0x0000, 0x0000, 0x0000, 0x0000 };
- if ((dst->feature_mask & GLITZ_FEATURE_ARB_MULTITEXTURE_MASK) &&
- _glitz_composite_direct (op,
- src, mask, dst,
- x_src, y_src,
- x_mask, y_mask,
- x_dst, y_dst,
- width, height))
- return;
-
dst_bounds.x1 = x_dst;
dst_bounds.x2 = x_dst + width;
dst_bounds.y1 = y_dst;
@@ -450,7 +180,7 @@ glitz_composite (glitz_operator_t op,
&dst_bounds, &mask_bounds);
if ((mask_bounds.x2 - x_dst) <= 0 || (mask_bounds.y2 - y_dst) <= 0)
return;
-
+
if (src->transform && (!SURFACE_REPEAT (src)))
intermediate_type = GLITZ_INTERMEDIATE_RGBA_STENCIL;
else
@@ -496,12 +226,21 @@ glitz_composite (glitz_operator_t op,
width = intermediate->width;
height = intermediate->height;
src = intermediate;
+ mask = NULL;
x_src = y_src = 0;
- }
+ glitz_render_op_init (&render_op, &src, &mask, dst,
+ &x_src, &y_src, &x_mask, &y_mask);
+ if (render_op.type == GLITZ_RENDER_TYPE_NA) {
+ glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK);
+ glitz_surface_destroy (intermediate);
+ return;
+ }
+ }
+
texture = glitz_surface_get_texture (src);
- /* Texture has not been allocated, hence source and the result of this
+ /* Source texture has not been allocated, hence source and the result of this
operation is undefined. So lets do nothing. */
if (!texture)
return;
@@ -510,258 +249,497 @@ glitz_composite (glitz_operator_t op,
glitz_surface_pop_current (dst);
return;
}
+
+ if (mask) { /* MULTI-TEXTURE */
+ glitz_bounding_box_double_t src_box, mask_box, dst_box;
+ glitz_point_t src_tl, src_br, mask_tl, mask_br;
+ glitz_gl_enum_t src_texture_unit = 0;
- glitz_texture_bind (gl, texture);
-
- clip.x1 = x_dst;
- clip.y1 = y_dst;
- clip.x2 = clip.x1 + width;
- clip.y2 = clip.y1 + height;
+ mask_texture = glitz_surface_get_texture (mask);
+
+ /* Mask texture has not been allocated, hence source and the result of this
+ operation is undefined. So lets do nothing. */
+ if (!mask_texture) {
+ glitz_surface_pop_current (dst);
+ return;
+ }
+
+ dst_box.x1 = x_dst;
+ dst_box.y1 = y_dst;
+ dst_box.x2 = dst_box.x1 + width;
+ dst_box.y2 = dst_box.y1 + height;
+
+ if (!SURFACE_REPEAT (src)) {
+ src_box.x1 = src_box.y1 = 0.0;
+ src_box.x2 = src->width;
+ src_box.y2 = src->height;
+
+ if (src->transform)
+ glitz_matrix_transform_bounding_box (src->transform,
+ &src_box.x1, &src_box.y1,
+ &src_box.x2, &src_box.y2);
+
+ src_box.x1 += x_dst - x_src;
+ src_box.x2 += x_dst - x_src;
+ src_box.y1 += y_dst - y_src;
+ src_box.y2 += y_dst - y_src;
- if (SURFACE_CLEAR_EXTERIOR (dst)) {
- gl->clear_stencil (0x0);
- gl->clear (GLITZ_GL_STENCIL_BUFFER_BIT);
- glitz_set_stencil_operator (gl, GLITZ_STENCIL_OPERATOR_SET, 0x1);
- }
+ if (!SURFACE_PROGRAMMATIC (src))
+ glitz_intersect_bounding_box_double (&dst_box, &src_box, &dst_box);
+ }
- type = glitz_render_type (src, NULL, dst);
-
- gl->scissor (clip.x1, dst->height - (clip.y1 + height), width, height);
-
- glitz_set_operator (gl, op);
-
- glitz_render_enable (type, src, NULL, dst, texture, NULL, opacity);
+ if (!SURFACE_REPEAT (mask)) {
+ mask_box.x1 = mask_box.y1 = 0.0;
+ mask_box.x2 = mask->width;
+ mask_box.y2 = mask->height;
+
+ if (mask->transform)
+ glitz_matrix_transform_bounding_box (mask->transform,
+ &mask_box.x1, &mask_box.y1,
+ &mask_box.x2, &mask_box.y2);
- if ((!src->transform) && SURFACE_GLREPEAT (src, texture)) {
- /* CASE 1: Repeat, no transformation and power of two sized texture,
- GL can do repeat for us. */
- double repeat_factor_x, repeat_factor_y;
-
- glitz_texture_ensure_repeat (gl, texture, 1);
- glitz_texture_ensure_filter (gl, texture, GLITZ_FILTER_NEAREST);
-
- bl.x = tl.x = x_dst;
- tr.y = tl.y = y_dst;
- tr.x = br.x = x_dst + width;
- bl.y = br.y = y_dst + height;
-
- /* Shift coordinates with source offset */
- if (x_src) {
- x_src = (x_src % src->width);
- tl.x -= x_src;
- bl.x -= x_src;
+ mask_box.x1 += x_dst - x_mask;
+ mask_box.x2 += x_dst - x_mask;
+ mask_box.y1 += y_dst - y_mask;
+ mask_box.y2 += y_dst - y_mask;
+
+ if (!SURFACE_PROGRAMMATIC (mask))
+ glitz_intersect_bounding_box_double (&dst_box, &mask_box, &dst_box);
}
- if (y_src) {
- y_src = (y_src % src->height);
- tl.y -= y_src;
- tr.y -= y_src;
+
+ if ((dst_box.x2 - dst_box.x1) <= 0 || (dst_box.y2 - dst_box.y1) <= 0) {
+ glitz_surface_pop_current (dst);
+ return;
}
- /* Align with top left edge */
- bl.y += texture->height - (((int) (br.y - tl.y)) % texture->height);
- br.y += texture->height - (((int) (br.y - tl.y)) % texture->height);
-
- repeat_factor_x = (br.x - tl.x) / (double) texture->width;
- repeat_factor_y = (br.y - tl.y) / (double) texture->height;
+ if (SURFACE_REPEAT (src)) {
+ src_br.y = src->height -
+ (((y_src % src->height) + (int) (dst_box.y2 - dst_box.y1)) %
+ src->height);
+ src_tl.y = (dst_box.y2 - dst_box.y1) + src_br.y;
+ src_tl.x = x_src % src->width;
+ src_br.x = (dst_box.x2 - dst_box.x1) + src_tl.x;
+ } else {
+ glitz_intersect_bounding_box_double (&src_box, &dst_box, &src_box);
+
+ src_tl.x = src_box.x1 - x_dst + x_src;
+ src_br.x = src_box.x2 - x_dst + x_src;
+ src_tl.y = src_box.y1 - y_dst + y_src;
+ src_br.y = src_box.y2 - y_dst + y_src;
+
+ if (src->transform) {
+ glitz_matrix_transform_point (src->inverse_transform,
+ &src_tl.x, &src_tl.y);
+ glitz_matrix_transform_point (src->inverse_transform,
+ &src_br.x, &src_br.y);
+ }
+ }
- if (dst->multi_sample) {
- list = dst->gl->gen_lists (1);
- dst->gl->new_list (list, GLITZ_GL_COMPILE);
+ src_tl.x = (src_tl.x / src->width) * texture->texcoord_width;
+ src_tl.y = (src_tl.y / src->height) * texture->texcoord_height;
+ src_br.x = (src_br.x / src->width) * texture->texcoord_width;
+ src_br.y = (src_br.y / src->height) * texture->texcoord_height;
+
+ if (!SURFACE_REPEAT (src)) {
+ src_tl.y = texture->texcoord_height - src_tl.y;
+ src_br.y = texture->texcoord_height - src_br.y;
+ }
+
+ if (SURFACE_REPEAT (mask)) {
+ mask_br.y = mask->height -
+ (((y_mask % mask->height) + (int) (dst_box.y2 - dst_box.y1)) %
+ mask->height);
+ mask_tl.y = (dst_box.y2 - dst_box.y1) + mask_br.y;
+ mask_tl.x = x_mask % mask->width;
+ mask_br.x = (dst_box.x2 - dst_box.x1) + mask_tl.x;
+ } else {
+ glitz_intersect_bounding_box_double (&mask_box, &dst_box, &mask_box);
+
+ mask_tl.x = mask_box.x1 - x_dst + x_mask;
+ mask_br.x = mask_box.x2 - x_dst + x_mask;
+ mask_tl.y = mask_box.y1 - y_dst + y_mask;
+ mask_br.y = mask_box.y2 - y_dst + y_mask;
+
+ if (mask->transform) {
+ glitz_matrix_transform_point (mask->inverse_transform,
+ &mask_tl.x, &mask_tl.y);
+ glitz_matrix_transform_point (mask->inverse_transform,
+ &mask_br.x, &mask_br.y);
+ }
}
-
- gl->begin (GLITZ_GL_QUADS);
- gl->tex_coord_2d (0.0, repeat_factor_y);
- gl->vertex_2d (tl.x, tl.y);
- gl->tex_coord_2d (repeat_factor_x, repeat_factor_y);
- gl->vertex_2d (tr.x, tr.y);
- gl->tex_coord_2d (repeat_factor_x, 0.0);
- gl->vertex_2d (br.x, br.y);
- gl->tex_coord_2d (0.0, 0.0);
- gl->vertex_2d (bl.x, bl.y);
- gl->end ();
-
- } else {
- /* CASE 2: Either none power of two sized texture or
- transformation is set. */
- glitz_point_t base_tl, base_bl, base_br, base_tr;
- int x_dir, y_dir, continue_y, continue_x, x_is_ok, y_is_ok,
- in_destination_area;
- double save_base_x1, save_base_x2;
- glitz_repeat_direction_t repeat_direction;
- glitz_texture_ensure_repeat (gl, texture, 0);
+ mask_tl.x = (mask_tl.x / mask->width) * mask_texture->texcoord_width;
+ mask_tl.y = (mask_tl.y / mask->height) * mask_texture->texcoord_height;
+ mask_br.x = (mask_br.x / mask->width) * mask_texture->texcoord_width;
+ mask_br.y = (mask_br.y / mask->height) * mask_texture->texcoord_height;
- base_bl.x = base_tl.x = 0;
- base_tr.y = base_tl.y = 0;
- base_tr.x = base_br.x = src->width;
- base_bl.y = base_br.y = src->height;
+ if (!SURFACE_REPEAT (mask)) {
+ mask_tl.y = mask_texture->texcoord_height - mask_tl.y;
+ mask_br.y = mask_texture->texcoord_height - mask_br.y;
+ }
+
+ gl->disable (GLITZ_GL_SCISSOR_TEST);
+
+ texture_unit++;
+ glitz_texture_bind (gl, mask_texture);
+
+ if (mask->transform)
+ glitz_texture_ensure_filter (gl, mask_texture, mask->filter);
+ else
+ glitz_texture_ensure_filter (gl, mask_texture, GLITZ_FILTER_NEAREST);
+
+ glitz_texture_ensure_repeat (gl, mask_texture, SURFACE_REPEAT (mask));
- /* Start repeating in southeast direction */
- repeat_direction = GLITZ_REPEAT_SOUTHEAST;
- x_dir = y_dir = 1;
+ while (texture_unit < render_op.render->texture_units) {
+ src_texture_unit = _texture_units[++texture_unit];
+ gl->active_texture (src_texture_unit);
+ glitz_texture_bind (gl, texture);
+ }
if (src->transform)
glitz_texture_ensure_filter (gl, texture, src->filter);
else
glitz_texture_ensure_filter (gl, texture, GLITZ_FILTER_NEAREST);
- if (dst->multi_sample) {
- list = dst->gl->gen_lists (1);
- dst->gl->new_list (list, GLITZ_GL_COMPILE);
+ glitz_texture_ensure_repeat (gl, texture, SURFACE_REPEAT (src));
+
+ glitz_render_op_set_textures (&render_op, texture, mask_texture);
+ glitz_set_operator (gl, op);
+
+ if (render_op.component_alpha) {
+ list = gl->gen_lists (1);
+ gl->new_list (list, GLITZ_GL_COMPILE);
+ } else
+ glitz_render_enable (&render_op);
+
+ gl->begin (GLITZ_GL_QUADS);
+
+ gl->multi_tex_coord_2d (GLITZ_GL_TEXTURE0, mask_tl.x, mask_tl.y);
+ gl->multi_tex_coord_2d (src_texture_unit, src_tl.x, src_tl.y);
+ gl->vertex_2d (dst_box.x1, dst_box.y1);
+
+ gl->multi_tex_coord_2d (GLITZ_GL_TEXTURE0, mask_br.x, mask_tl.y);
+ gl->multi_tex_coord_2d (src_texture_unit, src_br.x, src_tl.y);
+ gl->vertex_2d (dst_box.x2, dst_box.y1);
+
+ gl->multi_tex_coord_2d (GLITZ_GL_TEXTURE0, mask_br.x, mask_br.y);
+ gl->multi_tex_coord_2d (src_texture_unit, src_br.x, src_br.y);
+ gl->vertex_2d (dst_box.x2, dst_box.y2);
+
+ gl->multi_tex_coord_2d (GLITZ_GL_TEXTURE0, mask_tl.x, mask_br.y);
+ gl->multi_tex_coord_2d (src_texture_unit, src_tl.x, src_br.y);
+ gl->vertex_2d (dst_box.x1, dst_box.y2);
+
+ gl->end ();
+
+ clip.x1 = dst_box.x1;
+ clip.y1 = dst_box.y1;
+ clip.x2 = dst_box.x2 + 0.5;
+ clip.y2 = dst_box.y2 + 0.5;
+
+ } else { /* SINGLE-TEXTURE */
+
+ while (texture_unit < render_op.render->texture_units) {
+ if (texture_unit++)
+ gl->active_texture (_texture_units[texture_unit]);
+ glitz_texture_bind (gl, texture);
}
+
+ clip.x1 = x_dst;
+ clip.y1 = y_dst;
+ clip.x2 = clip.x1 + width;
+ clip.y2 = clip.y1 + height;
+
+ if (SURFACE_CLEAR_EXTERIOR (dst)) {
+ gl->clear_stencil (0x0);
+ gl->clear (GLITZ_GL_STENCIL_BUFFER_BIT);
+ glitz_set_stencil_operator (gl, GLITZ_STENCIL_OPERATOR_SET, 0x1);
+ }
+
+ gl->scissor (clip.x1, dst->height - (clip.y1 + height), width, height);
+
+ glitz_render_op_set_textures (&render_op, texture, NULL);
+ glitz_set_operator (gl, op);
+
+ if (dst->multi_sample || render_op.component_alpha)
+ list = gl->gen_lists (1);
+
+ if ((!src->transform) && SURFACE_REPEAT (src) && texture->repeatable) {
+ /* CASE 1: Repeat, no transformation and power of two sized texture,
+ GL can do repeat for us. */
+ double repeat_factor_x, repeat_factor_y;
+
+ glitz_texture_ensure_repeat (gl, texture, 1);
+ glitz_texture_ensure_filter (gl, texture, GLITZ_FILTER_NEAREST);
+
+ bl.x = tl.x = x_dst;
+ tr.y = tl.y = y_dst;
+ tr.x = br.x = x_dst + width;
+ bl.y = br.y = y_dst + height;
+
+ /* Shift coordinates with source offset */
+ if (x_src) {
+ x_src = (x_src % src->width);
+ tl.x -= x_src;
+ bl.x -= x_src;
+ }
+ if (y_src) {
+ y_src = (y_src % src->height);
+ tl.y -= y_src;
+ tr.y -= y_src;
+ }
- while (repeat_direction) {
- save_base_x1 = base_tl.x;
- save_base_x2 = base_tr.x;
+ /* Align with top left edge */
+ bl.y += texture->height - (((int) (br.y - tl.y)) % texture->height);
+ br.y += texture->height - (((int) (br.y - tl.y)) % texture->height);
+
+ repeat_factor_x = (br.x - tl.x) / (double) texture->width;
+ repeat_factor_y = (br.y - tl.y) / (double) texture->height;
+
+ if (list)
+ gl->new_list (list, GLITZ_GL_COMPILE);
+ else
+ glitz_render_enable (&render_op);
+
+ gl->begin (GLITZ_GL_QUADS);
+ gl->tex_coord_2d (0.0, repeat_factor_y);
+ gl->vertex_2d (tl.x, tl.y);
+ gl->tex_coord_2d (repeat_factor_x, repeat_factor_y);
+ gl->vertex_2d (tr.x, tr.y);
+ gl->tex_coord_2d (repeat_factor_x, 0.0);
+ gl->vertex_2d (br.x, br.y);
+ gl->tex_coord_2d (0.0, 0.0);
+ gl->vertex_2d (bl.x, bl.y);
+ gl->end ();
+
+ } else {
+ /* CASE 2: Either none power of two sized texture or
+ transformation is set. */
+ glitz_point_t base_tl, base_bl, base_br, base_tr;
+ int x_dir, y_dir, continue_y, continue_x, x_is_ok, y_is_ok,
+ in_destination_area;
+ double save_base_x1, save_base_x2, min, max;
+ glitz_repeat_direction_t repeat_direction;
+
+ glitz_texture_ensure_repeat (gl, texture, 0);
+
+ base_bl.x = base_tl.x = 0;
+ base_tr.y = base_tl.y = 0;
+ base_tr.x = base_br.x = src->width;
+ base_bl.y = base_br.y = src->height;
+
+ /* Start repeating in southeast direction */
+ repeat_direction = GLITZ_REPEAT_SOUTHEAST;
+ x_dir = y_dir = 1;
+
+ if (src->transform)
+ glitz_texture_ensure_filter (gl, texture, src->filter);
+ else
+ glitz_texture_ensure_filter (gl, texture, GLITZ_FILTER_NEAREST);
+
+ if (list)
+ gl->new_list (list, GLITZ_GL_COMPILE);
+ else
+ glitz_render_enable (&render_op);
+
+ while (repeat_direction) {
+ save_base_x1 = base_tl.x;
+ save_base_x2 = base_tr.x;
- do {
- continue_y = continue_x = in_destination_area = 0;
do {
- bl = base_bl;
- br = base_br;
- tl = base_tl;
- tr = base_tr;
+ continue_y = continue_x = in_destination_area = 0;
+ do {
+ bl = base_bl;
+ br = base_br;
+ tl = base_tl;
+ tr = base_tr;
- if (src->transform) {
- glitz_matrix_transform_point (src->transform, &tl.x, &tl.y);
- glitz_matrix_transform_point (src->transform, &bl.x, &bl.y);
- glitz_matrix_transform_point (src->transform, &tr.x, &tr.y);
- glitz_matrix_transform_point (src->transform, &br.x, &br.y);
- }
-
- tl.x += x_dst - x_src;
- bl.x += x_dst - x_src;
- tr.x += x_dst - x_src;
- br.x += x_dst - x_src;
-
- tl.y += y_dst - y_src;
- bl.y += y_dst - y_src;
- tr.y += y_dst - y_src;
- br.y += y_dst - y_src;
+ if (src->transform) {
+ glitz_matrix_transform_point (src->transform, &tl.x, &tl.y);
+ glitz_matrix_transform_point (src->transform, &bl.x, &bl.y);
+ glitz_matrix_transform_point (src->transform, &tr.x, &tr.y);
+ glitz_matrix_transform_point (src->transform, &br.x, &br.y);
+ }
+
+ tl.x += x_dst - x_src;
+ bl.x += x_dst - x_src;
+ tr.x += x_dst - x_src;
+ br.x += x_dst - x_src;
- if ((tl.x > (x_dst + width) && bl.x > (x_dst + width)) ||
- (tr.x < x_dst && br.x < x_dst))
- x_is_ok = 0;
- else
- x_is_ok = 1;
-
- if ((tl.y > (y_dst + height) && tr.y > (y_dst + height)) ||
- (bl.y < y_dst && br.y < y_dst))
- y_is_ok = 0;
- else
- y_is_ok = 1;
-
- if (x_is_ok && y_is_ok) {
- gl->begin (GLITZ_GL_QUADS);
- gl->tex_coord_2d (0.0, texture->texcoord_height);
- gl->vertex_2d (tl.x, tl.y);
- gl->tex_coord_2d (texture->texcoord_width,
- texture->texcoord_height);
- gl->vertex_2d (tr.x, tr.y);
- gl->tex_coord_2d (texture->texcoord_width, 0.0);
- gl->vertex_2d (br.x, br.y);
- gl->tex_coord_2d (0.0, 0.0);
- gl->vertex_2d (bl.x, bl.y);
- gl->end ();
- in_destination_area = 1;
- }
+ tl.y += y_dst - y_src;
+ bl.y += y_dst - y_src;
+ tr.y += y_dst - y_src;
+ br.y += y_dst - y_src;
- if (SURFACE_REPEAT (src)) {
- base_bl.x += src->width * x_dir;
- base_tl.x += src->width * x_dir;
- base_tr.x += src->width * x_dir;
- base_br.x += src->width * x_dir;
+ min = MIN (tl.x, MIN (bl.x, MIN (tr.x, br.x)));
+ max = MAX (tl.x, MAX (bl.x, MAX (tr.x, br.x)));
+
+ if ((min > (x_dst + width)) || (max < x_dst))
+ x_is_ok = 0;
+ else
+ x_is_ok = 1;
- if (y_is_ok)
- continue_y = 1;
+ min = MIN (tl.y, MIN (bl.y, MIN (tr.y, br.y)));
+ max = MAX (tl.y, MAX (bl.y, MAX (tr.y, br.y)));
- if (in_destination_area)
- continue_x = (x_is_ok && y_is_ok);
+ if ((min > (y_dst + height)) || (max < y_dst))
+ y_is_ok = 0;
else
- continue_x = (x_is_ok || y_is_ok);
+ y_is_ok = 1;
+
+ if (x_is_ok && y_is_ok) {
+ gl->begin (GLITZ_GL_QUADS);
+ gl->tex_coord_2d (0.0, texture->texcoord_height);
+ gl->vertex_2d (tl.x, tl.y);
+ gl->tex_coord_2d (texture->texcoord_width,
+ texture->texcoord_height);
+ gl->vertex_2d (tr.x, tr.y);
+ gl->tex_coord_2d (texture->texcoord_width, 0.0);
+ gl->vertex_2d (br.x, br.y);
+ gl->tex_coord_2d (0.0, 0.0);
+ gl->vertex_2d (bl.x, bl.y);
+ gl->end ();
+ in_destination_area = 1;
+ }
+
+ if (SURFACE_REPEAT (src)) {
+ base_bl.x += src->width * x_dir;
+ base_tl.x += src->width * x_dir;
+ base_tr.x += src->width * x_dir;
+ base_br.x += src->width * x_dir;
+
+ if (y_is_ok)
+ continue_y = 1;
+
+ if (in_destination_area)
+ continue_x = (x_is_ok && y_is_ok);
+ else
+ continue_x = (x_is_ok || y_is_ok);
+ }
+ } while (SURFACE_REPEAT (src) && continue_x);
+
+ if (SURFACE_REPEAT (src)) {
+ base_bl.y += src->height * y_dir;
+ base_tl.y += src->height * y_dir;
+ base_tr.y += src->height * y_dir;
+ base_br.y += src->height * y_dir;
+
+ base_tl.x = base_bl.x = save_base_x1;
+ base_tr.x = base_br.x = save_base_x2;
+ }
+ } while (SURFACE_REPEAT (src) && continue_y);
+
+ if (src->transform && SURFACE_REPEAT (src)) {
+ switch (repeat_direction) {
+ case GLITZ_REPEAT_SOUTHEAST:
+ y_dir = -1;
+ base_tl.y = base_tr.y = -src->height;
+ base_bl.y = base_br.y = 0.0;
+ repeat_direction = GLITZ_REPEAT_SOUTHWEST;
+ break;
+ case GLITZ_REPEAT_SOUTHWEST:
+ x_dir = -1;
+ base_tl.y = base_tr.y = -src->height;
+ base_bl.y = base_br.y = 0.0;
+ base_tl.x = base_bl.x = -src->width;
+ base_tr.x = base_br.x = 0.0;
+ repeat_direction = GLITZ_REPEAT_NORTHEAST;
+ break;
+ case GLITZ_REPEAT_NORTHEAST:
+ y_dir = 1;
+ base_tl.y = base_tr.y = 0.0;
+ base_bl.y = base_br.y = src->height;
+ base_tl.x = base_bl.x = -src->width;
+ base_tr.x = base_br.x = 0.0;
+ repeat_direction = GLITZ_REPEAT_NORTHWEST;
+ break;
+ case GLITZ_REPEAT_NORTHWEST:
+ repeat_direction = GLITZ_REPEAT_NONE;
+ break;
+ case GLITZ_REPEAT_NONE:
+ break;
}
- } while (SURFACE_REPEAT (src) && continue_x);
-
- if (SURFACE_REPEAT (src)) {
- base_bl.y += src->height * y_dir;
- base_tl.y += src->height * y_dir;
- base_tr.y += src->height * y_dir;
- base_br.y += src->height * y_dir;
-
- base_tl.x = base_bl.x = save_base_x1;
- base_tr.x = base_br.x = save_base_x2;
- }
- } while (SURFACE_REPEAT (src) && continue_y);
-
- if (src->transform && SURFACE_REPEAT (src)) {
- switch (repeat_direction) {
- case GLITZ_REPEAT_SOUTHEAST:
- y_dir = -1;
- base_tl.y = base_tr.y = -src->height;
- base_bl.y = base_br.y = 0.0;
- repeat_direction = GLITZ_REPEAT_SOUTHWEST;
- break;
- case GLITZ_REPEAT_SOUTHWEST:
- x_dir = -1;
- base_tl.y = base_tr.y = -src->height;
- base_bl.y = base_br.y = 0.0;
- base_tl.x = base_bl.x = -src->width;
- base_tr.x = base_br.x = 0.0;
- repeat_direction = GLITZ_REPEAT_NORTHEAST;
- break;
- case GLITZ_REPEAT_NORTHEAST:
- y_dir = 1;
- base_tl.y = base_tr.y = 0.0;
- base_bl.y = base_br.y = src->height;
- base_tl.x = base_bl.x = -src->width;
- base_tr.x = base_br.x = 0.0;
- repeat_direction = GLITZ_REPEAT_NORTHWEST;
- break;
- case GLITZ_REPEAT_NORTHWEST:
+ } else
repeat_direction = GLITZ_REPEAT_NONE;
- break;
- case GLITZ_REPEAT_NONE:
- break;
- }
- } else
- repeat_direction = GLITZ_REPEAT_NONE;
+ }
}
}
if (list) {
- int i;
- unsigned int mask = *dst->stencil_mask & ~0x1;
-
gl->end_list ();
- for (i = 0; i < dst->multi_sample->n_samples; i++) {
- if ((i + 1) == dst->multi_sample->n_samples)
- glitz_set_stencil_operator (gl, GLITZ_STENCIL_OPERATOR_CLIP,
- mask | (i + 1));
- else
- glitz_set_stencil_operator (gl, GLITZ_STENCIL_OPERATOR_CLIP_EQUAL,
- mask | (i + 1));
-
- glitz_render_enable (type, src, NULL, dst, texture, NULL,
- SHORT_MODULATE (dst->multi_sample->weights[i],
- opacity));
-
+ if (dst->multi_sample) {
+ unsigned int mask = *dst->stencil_mask & ~0x1;
+ unsigned short alpha, opacity;
+ int i;
+
+ glitz_render_op_get_alpha_mask (&render_op, NULL, NULL, NULL, &opacity);
+
+ for (i = 0; i < dst->multi_sample->n_samples; i++) {
+ if ((i + 1) == dst->multi_sample->n_samples)
+ glitz_set_stencil_operator (gl, GLITZ_STENCIL_OPERATOR_CLIP,
+ mask | (i + 1));
+ else
+ glitz_set_stencil_operator (gl, GLITZ_STENCIL_OPERATOR_CLIP_EQUAL,
+ mask | (i + 1));
+
+ alpha = SHORT_MULT (dst->multi_sample->weights[i], opacity);
+ glitz_render_op_set_alpha_mask (&render_op, 0x0, 0x0, 0x0, alpha);
+
+ glitz_render_enable (&render_op);
+
+ gl->call_list (list);
+ }
+ } else {
+ glitz_render_op_set_alpha_mask (&render_op, 0xffff, 0x0, 0x0, 0x0);
+ glitz_render_enable (&render_op);
+ gl->color_mask (1, 0, 0, 0);
+ gl->call_list (list);
+
+ glitz_render_op_set_alpha_mask (&render_op, 0x0, 0x0, 0xffff, 0x0);
+ glitz_render_enable (&render_op);
+ gl->color_mask (0, 0, 1, 0);
gl->call_list (list);
+
+ if (render_op.component_alpha == GLITZ_COMPONENT_ALPHA_ARGB) {
+ glitz_render_op_set_alpha_mask (&render_op, 0x0, 0xffff, 0x0, 0x0);
+ glitz_render_enable (&render_op);
+ gl->color_mask (0, 1, 0, 0);
+ gl->call_list (list);
+
+ glitz_render_op_set_alpha_mask (&render_op, 0x0, 0x0, 0x0, 0xffff);
+ glitz_render_enable (&render_op);
+ gl->color_mask (0, 0, 0, 1);
+ gl->call_list (list);
+ } else {
+ glitz_render_op_set_alpha_mask (&render_op, 0x0, 0xffff, 0x0, 0x0);
+ glitz_render_enable (&render_op);
+ gl->color_mask (0, 1, 0, 1);
+ gl->call_list (list);
+ }
}
gl->delete_lists (list, 1);
}
-
- glitz_render_disable (type, dst);
-
- glitz_texture_unbind (gl, texture);
+ glitz_render_disable (&render_op);
+
+ for (; texture_unit; texture_unit--) {
+ if (texture_unit == 1 && mask)
+ glitz_texture_unbind (gl, mask_texture);
+ else
+ glitz_texture_unbind (gl, texture);
+
+ if (texture_unit > 1)
+ gl->active_texture (_texture_units[texture_unit - 1]);
+ }
+
if (SURFACE_CLEAR_EXTERIOR (dst)) {
glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
- glitz_set_stencil_operator (dst->gl,
- GLITZ_STENCIL_OPERATOR_CLIP_EQUAL, 0x0);
+ glitz_set_stencil_operator (gl, GLITZ_STENCIL_OPERATOR_CLIP_EQUAL, 0x0);
- gl->color_4us (0x0000, 0x0000, 0x0000, 0x0000);
+ gl->color_mask (1, 1, 1, 1);
+ gl->color_4us (0x0, 0x0, 0x0, 0x0);
gl->begin (GLITZ_GL_QUADS);
gl->vertex_2d (0.0, 0.0);
@@ -774,7 +752,7 @@ glitz_composite (glitz_operator_t op,
glitz_surface_dirty (dst, &clip);
glitz_surface_pop_current (dst);
-
+
if (intermediate)
glitz_surface_destroy (intermediate);
}
@@ -920,8 +898,6 @@ glitz_copy_area (glitz_surface_t *src,
}
if (!status) {
- int rowstride = 1;
- char *data;
static glitz_pixel_format_t pf = {
{
32,
@@ -930,20 +906,24 @@ glitz_copy_area (glitz_surface_t *src,
0x0000ff00,
0x000000ff
},
- 0, 0,
+ 0, 0, 0,
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
};
-
- rowstride = (rowstride + 3) & -4;
- data = malloc (height * rowstride);
- if (!data) {
+ glitz_pixel_buffer_t *buffer =
+ glitz_pixel_buffer_create (src,
+ NULL,
+ width * height * 4,
+ GLITZ_PIXEL_BUFFER_HINT_STATIC_COPY);
+ if (!buffer) {
glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK);
return;
}
+
+ glitz_pixel_buffer_set_format (buffer, &pf);
- glitz_get_pixels (src, x_src, y_src, width, height, &pf, data);
- glitz_put_pixels (dst, x_dst, y_dst, width, height, &pf, data);
+ glitz_get_pixels (src, x_src, y_src, width, height, buffer);
+ glitz_put_pixels (dst, x_dst, y_dst, width, height, buffer);
- free (data);
+ glitz_pixel_buffer_destroy (buffer);
}
}
diff --git a/src/glitz.h b/src/glitz.h
index 217c490..63ef283 100644
--- a/src/glitz.h
+++ b/src/glitz.h
@@ -131,16 +131,20 @@ typedef enum {
GLITZ_OPERATOR_SATURATE
} glitz_operator_t;
-#define GLITZ_FEATURE_OFFSCREEN_DRAWING_MASK (1L << 0)
-#define GLITZ_FEATURE_CONVOLUTION_FILTER_MASK (1L << 1)
-#define GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 2)
-#define GLITZ_FEATURE_TEXTURE_NPOT_MASK (1L << 3)
-#define GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 4)
-#define GLITZ_FEATURE_MULTISAMPLE_MASK (1L << 5)
-#define GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK (1L << 6)
-#define GLITZ_FEATURE_ARB_MULTITEXTURE_MASK (1L << 7)
-#define GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 8)
-#define GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 9)
+#define GLITZ_FEATURE_OFFSCREEN_DRAWING_MASK (1L << 0)
+#define GLITZ_FEATURE_CONVOLUTION_FILTER_MASK (1L << 1)
+#define GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 2)
+#define GLITZ_FEATURE_TEXTURE_NPOT_MASK (1L << 3)
+#define GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 4)
+#define GLITZ_FEATURE_MULTISAMPLE_MASK (1L << 5)
+#define GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK (1L << 6)
+#define GLITZ_FEATURE_ARB_MULTITEXTURE_MASK (1L << 7)
+#define GLITZ_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK (1L << 8)
+#define GLITZ_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK (1L << 9)
+#define GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 10)
+#define GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 11)
+#define GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK (1L << 12)
+#define GLITZ_FEATURE_COMPONENT_ALPHA_MASK (1L << 13)
typedef enum {
GLITZ_STANDARD_ARGB32,
@@ -215,10 +219,12 @@ typedef enum {
const char *
glitz_status_string (glitz_status_t status);
+
/* glitz_color_range.c */
+typedef struct _glitz_surface glitz_surface_t;
typedef struct _glitz_color_range glitz_color_range_t;
-
+
typedef enum {
GLITZ_EXTEND_PAD,
GLITZ_EXTEND_REPEAT,
@@ -226,12 +232,13 @@ typedef enum {
} glitz_extend_t;
glitz_color_range_t *
-glitz_color_range_create (unsigned int size);
+glitz_color_range_create (glitz_surface_t *surface,
+ unsigned int size);
void
glitz_color_range_destroy (glitz_color_range_t *color_range);
-unsigned char *
+char *
glitz_color_range_get_data (glitz_color_range_t *color_range);
void
@@ -248,8 +255,6 @@ glitz_color_range_set_extend (glitz_color_range_t *color_range,
/* glitz_surface.c */
-typedef struct _glitz_surface glitz_surface_t;
-
typedef enum {
GLITZ_POLYEDGE_SHARP,
GLITZ_POLYEDGE_SMOOTH
@@ -285,6 +290,10 @@ glitz_surface_set_repeat (glitz_surface_t *surface,
glitz_bool_t repeat);
void
+glitz_surface_set_component_alpha (glitz_surface_t *surface,
+ glitz_bool_t component_alpha);
+
+void
glitz_surface_set_filter (glitz_surface_t *surface,
glitz_filter_t filter);
@@ -405,7 +414,7 @@ glitz_surface_create_similar (glitz_surface_t *templ,
unsigned long
glitz_surface_get_hints (glitz_surface_t *surface);
-
+
/* glitz_pixel.c */
@@ -425,18 +434,67 @@ typedef struct _glitz_pixel_masks {
typedef struct _glitz_pixel_format {
glitz_pixel_masks_t masks;
int xoffset;
+ int skip_lines;
int bytes_per_line;
glitz_pixel_scanline_order_t scanline_order;
} glitz_pixel_format_t;
+typedef struct _glitz_pixel_buffer glitz_pixel_buffer_t;
+
+typedef enum {
+ GLITZ_PIXEL_BUFFER_HINT_STREAM_DRAW,
+ GLITZ_PIXEL_BUFFER_HINT_STREAM_READ,
+ GLITZ_PIXEL_BUFFER_HINT_STREAM_COPY,
+ GLITZ_PIXEL_BUFFER_HINT_STATIC_DRAW,
+ GLITZ_PIXEL_BUFFER_HINT_STATIC_READ,
+ GLITZ_PIXEL_BUFFER_HINT_STATIC_COPY,
+ GLITZ_PIXEL_BUFFER_HINT_DYNAMIC_DRAW,
+ GLITZ_PIXEL_BUFFER_HINT_DYNAMIC_READ,
+ GLITZ_PIXEL_BUFFER_HINT_DYNAMIC_COPY
+} glitz_buffer_hint_t;
+
+glitz_pixel_buffer_t *
+glitz_pixel_buffer_create (glitz_surface_t *surface,
+ char *data,
+ unsigned int size,
+ glitz_buffer_hint_t hint);
+
+glitz_pixel_buffer_t *
+glitz_pixel_buffer_create_for_data (char *data,
+ glitz_pixel_format_t *format);
+
+void
+glitz_pixel_buffer_destroy (glitz_pixel_buffer_t *buffer);
+
+void
+glitz_pixel_buffer_set_format (glitz_pixel_buffer_t *buffer,
+ glitz_pixel_format_t *format);
+
+void
+glitz_pixel_buffer_get_format (glitz_pixel_buffer_t *buffer,
+ glitz_pixel_format_t *format);
+
+typedef enum {
+ GLITZ_PIXEL_BUFFER_ACCESS_READ_ONLY,
+ GLITZ_PIXEL_BUFFER_ACCESS_WRITE_ONLY,
+ GLITZ_PIXEL_BUFFER_ACCESS_READ_WRITE
+} glitz_pixel_buffer_access_t;
+
+char *
+glitz_pixel_buffer_get_data (glitz_pixel_buffer_t *buffer,
+ glitz_pixel_buffer_access_t access);
+
+void
+glitz_pixel_buffer_put_back_data (glitz_pixel_buffer_t *buffer);
+
void
glitz_put_pixels (glitz_surface_t *dst,
int x_dst,
int y_dst,
int width,
int height,
- glitz_pixel_format_t *format,
- char *pixels);
+ glitz_pixel_buffer_t *buffer);
+
void
glitz_get_pixels (glitz_surface_t *src,
@@ -444,9 +502,8 @@ glitz_get_pixels (glitz_surface_t *src,
int y_src,
int width,
int height,
- glitz_pixel_format_t *format,
- char *pixels);
-
+ glitz_pixel_buffer_t *buffer);
+
/* glitz_rect.c */
diff --git a/src/glitz_agl_context.c b/src/glitz_agl_context.c
index e25c11e..01e5c3c 100644
--- a/src/glitz_agl_context.c
+++ b/src/glitz_agl_context.c
@@ -88,17 +88,17 @@ glitz_agl_context_set_surface_anti_aliasing (glitz_agl_surface_t *surface)
{
if (surface->base.format->multisample.supported) {
if (surface->base.polyedge == GLITZ_POLYEDGE_SMOOTH) {
- glEnable (GLITZ_GL_MULTISAMPLE_ARB);
+ glEnable (GLITZ_GL_MULTISAMPLE);
if (surface->thread_info->agl_feature_mask &
GLITZ_AGL_FEATURE_MULTISAMPLE_FILTER_MASK) {
if (surface->base.polyedge_smooth_hint ==
GLITZ_POLYEDGE_SMOOTH_HINT_FAST)
- glHint (GLITZ_GL_MULTISAMPLE_FILTER_HINT_NV, GLITZ_GL_FASTEST);
+ glHint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_FASTEST);
else
- glHint (GLITZ_GL_MULTISAMPLE_FILTER_HINT_NV, GLITZ_GL_NICEST);
+ glHint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_NICEST);
}
} else
- glDisable (GLITZ_GL_MULTISAMPLE_ARB);
+ glDisable (GLITZ_GL_MULTISAMPLE);
}
}
diff --git a/src/glitz_agl_extension.c b/src/glitz_agl_extension.c
index afc2f52..296b3ec 100644
--- a/src/glitz_agl_extension.c
+++ b/src/glitz_agl_extension.c
@@ -38,12 +38,16 @@ static glitz_extension_map gl_extensions[] = {
{ "GL_ARB_texture_non_power_of_two", GLITZ_AGL_FEATURE_TEXTURE_NPOT_MASK },
{ "GL_ARB_texture_mirrored_repeat",
GLITZ_AGL_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK },
+ { "GL_ARB_texture_env_combine",
+ GLITZ_AGL_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK },
+ { "GL_ARB_texture_env_dot3", GLITZ_AGL_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK },
{ "GL_ARB_multisample", GLITZ_AGL_FEATURE_MULTISAMPLE_MASK },
{ "GL_NV_multisample_filter_hint",
GLITZ_AGL_FEATURE_MULTISAMPLE_FILTER_MASK },
{ "GL_ARB_multitexture", GLITZ_AGL_FEATURE_ARB_MULTITEXTURE_MASK },
{ "GL_ARB_vertex_program", GLITZ_AGL_FEATURE_ARB_VERTEX_PROGRAM_MASK },
{ "GL_ARB_fragment_program", GLITZ_AGL_FEATURE_ARB_FRAGMENT_PROGRAM_MASK },
+ { "GL_EXT_pixel_buffer_object", GLITZ_AGL_FEATURE_PIXEL_BUFFER_OBJECT_MASK },
{ NULL, 0 }
};
@@ -98,6 +102,25 @@ glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info)
if (thread_info->agl_feature_mask &
GLITZ_AGL_FEATURE_ARB_MULTITEXTURE_MASK) {
thread_info->feature_mask |= GLITZ_FEATURE_ARB_MULTITEXTURE_MASK;
+
+ if (thread_info->agl_feature_mask &
+ GLITZ_AGL_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK)
+ thread_info->feature_mask |= GLITZ_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK;
+
+ if (thread_info->agl_feature_mask &
+ GLITZ_AGL_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK)
+ thread_info->feature_mask |= GLITZ_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK;
+
+ if ((thread_info->feature_mask &
+ GLITZ_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK) &&
+ (thread_info->feature_mask &
+ GLITZ_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK)) {
+ GLint max_texture_units;
+
+ glGetIntegerv (GLITZ_GL_MAX_TEXTURE_UNITS, &max_texture_units);
+ if (max_texture_units >= 3)
+ thread_info->feature_mask |= GLITZ_FEATURE_COMPONENT_ALPHA_MASK;
+ }
if (thread_info->agl_feature_mask &
GLITZ_AGL_FEATURE_ARB_VERTEX_PROGRAM_MASK)
@@ -107,4 +130,8 @@ glitz_agl_query_extensions (glitz_agl_thread_info_t *thread_info)
GLITZ_AGL_FEATURE_ARB_FRAGMENT_PROGRAM_MASK)
thread_info->feature_mask |= GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK;
}
+
+ if (thread_info->agl_feature_mask &
+ GLITZ_AGL_FEATURE_PIXEL_BUFFER_OBJECT_MASK)
+ thread_info->feature_mask |= GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK;
}
diff --git a/src/glitz_agl_info.c b/src/glitz_agl_info.c
index 26e4cda..06d098a 100644
--- a/src/glitz_agl_info.c
+++ b/src/glitz_agl_info.c
@@ -41,8 +41,10 @@ glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address = {
(glitz_gl_vertex_2i_t) glVertex2i,
(glitz_gl_vertex_2d_t) glVertex2d,
(glitz_gl_tex_env_f_t) glTexEnvf,
+ (glitz_gl_tex_env_fv_t) glTexEnvfv,
(glitz_gl_tex_coord_2d_t) glTexCoord2d,
(glitz_gl_color_4us_t) glColor4us,
+ (glitz_gl_color_4d_t) glColor4d,
(glitz_gl_scissor_t) glScissor,
(glitz_gl_blend_func_t) glBlendFunc,
(glitz_gl_clear_t) glClear,
@@ -91,14 +93,20 @@ glitz_gl_proc_address_list_t _glitz_agl_gl_proc_address = {
(glitz_gl_end_list_t) glEndList,
(glitz_gl_call_list_t) glCallList,
- (glitz_gl_active_texture_arb_t) glActiveTextureARB,
- (glitz_gl_multi_tex_coord_2d_arb_t) glMultiTexCoord2dARB,
- (glitz_gl_gen_programs_arb_t) glGenProgramsARB,
- (glitz_gl_delete_programs_arb_t) glDeleteProgramsARB,
- (glitz_gl_program_string_arb_t) glProgramStringARB,
- (glitz_gl_bind_program_arb_t) glBindProgramARB,
- (glitz_gl_program_local_param_4d_arb_t) glProgramLocalParameter4dARB,
- (glitz_gl_get_program_iv_arb_t) glGetProgramivARB,
+ (glitz_gl_active_texture_t) glActiveTextureARB,
+ (glitz_gl_multi_tex_coord_2d_t) glMultiTexCoord2dARB,
+ (glitz_gl_gen_programs_t) glGenProgramsARB,
+ (glitz_gl_delete_programs_t) glDeleteProgramsARB,
+ (glitz_gl_program_string_t) glProgramStringARB,
+ (glitz_gl_bind_program_t) glBindProgramARB,
+ (glitz_gl_program_local_param_4d_t) glProgramLocalParameter4dARB,
+ (glitz_gl_get_program_iv_t) glGetProgramivARB,
+ (glitz_gl_gen_buffers_t) 0,
+ (glitz_gl_delete_buffers_t) 0,
+ (glitz_gl_bind_buffer_t) 0,
+ (glitz_gl_buffer_data_t) 0,
+ (glitz_gl_map_buffer_t) 0,
+ (glitz_gl_unmap_buffer_t) 0,
0
};
@@ -127,17 +135,25 @@ glitz_agl_thread_info_destroy (void *p)
glitz_agl_thread_info_t *
glitz_agl_thread_info_get (void)
{
+ glitz_agl_thread_info_t *thread_info;
+ void *p;
+
if (!tsd_initialized) {
- glitz_agl_thread_info_t *info = malloc (sizeof (glitz_agl_thread_info_t));
- glitz_agl_thread_info_init (info);
-
pthread_key_create (&info_tsd, glitz_agl_thread_info_destroy);
- pthread_setspecific (info_tsd, info);
-
tsd_initialized = 1;
- return info;
+ }
+
+ p = pthread_getspecific (info_tsd);
+
+ if (p == NULL) {
+ thread_info = malloc (sizeof (glitz_agl_thread_info_t));
+ glitz_agl_thread_info_init (thread_info);
+
+ pthread_setspecific (info_tsd, thread_info);
} else
- return (glitz_agl_thread_info_t *) pthread_getspecific (info_tsd);
+ thread_info = (glitz_agl_thread_info_t *) p;
+
+ return thread_info;
}
#else
@@ -185,7 +201,7 @@ glitz_agl_thread_info_init (glitz_agl_thread_info_t *thread_info)
thread_info->contexts = NULL;
thread_info->n_contexts = 0;
- memset (&thread_info->programs, 0, sizeof (glitz_programs_t));
+ glitz_program_map_init (&thread_info->program_map);
thread_info->root_context.pixel_format =
aglChoosePixelFormat (NULL, 0, attrib);
@@ -201,9 +217,9 @@ glitz_agl_thread_info_init (glitz_agl_thread_info_t *thread_info)
GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK)) {
glitz_gl_uint_t texture_indirections;
- _glitz_agl_gl_proc_address.get_program_iv_arb
- (GLITZ_GL_FRAGMENT_PROGRAM_ARB,
- GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB,
+ _glitz_agl_gl_proc_address.get_program_iv
+ (GLITZ_GL_FRAGMENT_PROGRAM,
+ GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS,
&texture_indirections);
/* Convolution filter programs require support for at least nine
@@ -226,8 +242,8 @@ glitz_agl_thread_info_fini (glitz_agl_thread_info_t *thread_info)
int i;
aglSetCurrentContext (thread_info->root_context.context);
- glitz_programs_fini (&_glitz_agl_gl_proc_address,
- &thread_info->programs);
+ glitz_program_map_fini (&_glitz_agl_gl_proc_address,
+ &thread_info->program_map);
aglSetCurrentContext (NULL);
if (thread_info->context_stack)
@@ -246,8 +262,6 @@ glitz_agl_thread_info_fini (glitz_agl_thread_info_t *thread_info)
free (thread_info->format_ids);
aglDestroyContext (thread_info->root_context.context);
-
- free (thread_info);
}
void
diff --git a/src/glitz_agl_surface.c b/src/glitz_agl_surface.c
index 6c0cfef..e97bdb3 100644
--- a/src/glitz_agl_surface.c
+++ b/src/glitz_agl_surface.c
@@ -215,7 +215,7 @@ _glitz_agl_surface_create (glitz_agl_thread_info_t *thread_info,
thread_info->n_formats,
width,
height,
- &thread_info->programs,
+ &thread_info->program_map,
texture_mask);
surface->thread_info = thread_info;
@@ -279,7 +279,7 @@ glitz_agl_surface_create_for_window (glitz_format_t *format,
thread_info->n_formats,
width,
height,
- &thread_info->programs,
+ &thread_info->program_map,
thread_info->texture_mask);
surface->thread_info = thread_info;
diff --git a/src/glitz_aglint.h b/src/glitz_aglint.h
index 913a30e..cec527d 100644
--- a/src/glitz_aglint.h
+++ b/src/glitz_aglint.h
@@ -36,15 +36,18 @@
#include <Carbon/Carbon.h>
#include <AGL/agl.h>
-#define GLITZ_AGL_FEATURE_PBUFFER_MASK (1L << 0)
-#define GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 1)
-#define GLITZ_AGL_FEATURE_TEXTURE_NPOT_MASK (1L << 2)
-#define GLITZ_AGL_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 3)
-#define GLITZ_AGL_FEATURE_MULTISAMPLE_MASK (1L << 4)
-#define GLITZ_AGL_FEATURE_MULTISAMPLE_FILTER_MASK (1L << 5)
-#define GLITZ_AGL_FEATURE_ARB_MULTITEXTURE_MASK (1L << 6)
-#define GLITZ_AGL_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 7)
-#define GLITZ_AGL_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 8)
+#define GLITZ_AGL_FEATURE_PBUFFER_MASK (1L << 0)
+#define GLITZ_AGL_FEATURE_TEXTURE_RECTANGLE_MASK (1L << 1)
+#define GLITZ_AGL_FEATURE_TEXTURE_NPOT_MASK (1L << 2)
+#define GLITZ_AGL_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK (1L << 3)
+#define GLITZ_AGL_FEATURE_MULTISAMPLE_MASK (1L << 4)
+#define GLITZ_AGL_FEATURE_MULTISAMPLE_FILTER_MASK (1L << 5)
+#define GLITZ_AGL_FEATURE_ARB_MULTITEXTURE_MASK (1L << 6)
+#define GLITZ_AGL_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK (1L << 7)
+#define GLITZ_AGL_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK (1L << 8)
+#define GLITZ_AGL_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 9)
+#define GLITZ_AGL_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 10)
+#define GLITZ_AGL_FEATURE_PIXEL_BUFFER_OBJECT_MASK (1L << 11)
typedef struct _glitz_agl_surface_t glitz_agl_surface_t;
@@ -77,7 +80,7 @@ typedef struct _glitz_agl_thread_info_t {
long int agl_feature_mask;
long int texture_mask;
- glitz_programs_t programs;
+ glitz_program_map_t program_map;
} glitz_agl_thread_info_t;
struct _glitz_agl_surface_t {
diff --git a/src/glitz_color_range.c b/src/glitz_color_range.c
index 62a91a5..d31a45a 100644
--- a/src/glitz_color_range.c
+++ b/src/glitz_color_range.c
@@ -31,32 +31,25 @@
#include "glitzint.h"
-static void
-glitz_color_range_init (glitz_color_range_t *color_range,
- unsigned int size)
-{
- color_range->texture = 0;
- color_range->filter = GLITZ_FILTER_NEAREST;
- color_range->extend = GLITZ_EXTEND_PAD;
- color_range->ref_count = 1;
- color_range->data = malloc (size * 4);
- color_range->size = size;
- color_range->update_mask = GLITZ_COLOR_RANGE_UPDATE_ALL_MASK;
- color_range->delete_textures = NULL;
-}
-
-static void
-glitz_color_range_fini (glitz_color_range_t *color_range)
-{
- if (color_range->texture)
- color_range->delete_textures (1, &color_range->texture);
-
- if (color_range->data)
- free (color_range->data);
-}
+#define GLITZ_COLOR_RANGE_UPDATE_TEXTURE_MASK (1L << 0)
+#define GLITZ_COLOR_RANGE_UPDATE_FILTER_MASK (1L << 1)
+#define GLITZ_COLOR_RANGE_UPDATE_EXTEND_MASK (1L << 2)
+#define GLITZ_COLOR_RANGE_UPDATE_ALL_MASK ((1L << 3) - 1)
+
+struct _glitz_color_range {
+ unsigned int size;
+ glitz_gl_uint_t texture;
+ glitz_filter_t filter;
+ glitz_extend_t extend;
+ unsigned long update_mask;
+ unsigned int ref_count;
+ glitz_pixel_buffer_t *buffer;
+ glitz_surface_t *surface;
+};
glitz_color_range_t *
-glitz_color_range_create (unsigned int size)
+glitz_color_range_create (glitz_surface_t *surface,
+ unsigned int size)
{
glitz_color_range_t *color_range;
@@ -64,13 +57,30 @@ glitz_color_range_create (unsigned int size)
if (!color_range)
return NULL;
- glitz_color_range_init (color_range, size);
+ color_range->texture = 0;
+ color_range->filter = GLITZ_FILTER_NEAREST;
+ color_range->extend = GLITZ_EXTEND_PAD;
+ color_range->ref_count = 1;
- if (!color_range->data) {
+ /* If data is not POT and NPOT texture support is missing we force
+ the size to POT */
+ if ((!(surface->feature_mask & GLITZ_FEATURE_TEXTURE_NPOT_MASK)) &&
+ (!glitz_uint_is_power_of_two (size)))
+ glitz_uint_to_power_of_two (&size);
+
+ color_range->size = size;
+ color_range->buffer =
+ glitz_pixel_buffer_create (surface, NULL, size * 4 /* ARGB32 */,
+ GLITZ_PIXEL_BUFFER_HINT_STATIC_DRAW);
+ if (color_range->buffer == NULL) {
free (color_range);
return NULL;
}
+ color_range->update_mask = GLITZ_COLOR_RANGE_UPDATE_ALL_MASK;
+ color_range->surface = surface;
+ glitz_surface_reference (surface);
+
return color_range;
}
slim_hidden_def(glitz_color_range_create);
@@ -79,7 +89,7 @@ void
glitz_color_range_reference (glitz_color_range_t *color_range)
{
if (color_range == NULL)
- return;
+ return;
color_range->ref_count++;
}
@@ -94,7 +104,19 @@ glitz_color_range_destroy (glitz_color_range_t *color_range)
if (color_range->ref_count)
return;
- glitz_color_range_fini (color_range);
+ glitz_pixel_buffer_destroy (color_range->buffer);
+
+ if (color_range->texture) {
+ glitz_surface_push_current (color_range->surface,
+ GLITZ_CN_ANY_CONTEXT_CURRENT);
+
+ color_range->surface->gl->delete_textures (1, &color_range->texture);
+
+ glitz_surface_pop_current (color_range->surface);
+ }
+
+ glitz_surface_destroy (color_range->surface);
+
free (color_range);
}
@@ -104,23 +126,16 @@ glitz_color_range_bind (glitz_gl_proc_address_list_t *gl,
unsigned long feature_mask)
{
if (color_range->update_mask & GLITZ_COLOR_RANGE_UPDATE_TEXTURE_MASK) {
+ char *data;
- if (!color_range->texture) {
+ if (!color_range->texture)
gl->gen_textures (1, &color_range->texture);
- color_range->delete_textures = gl->delete_textures;
- }
gl->enable (GLITZ_GL_TEXTURE_1D);
gl->bind_texture (GLITZ_GL_TEXTURE_1D, color_range->texture);
-
- /* If data is not POT and NPOT texture support is missing we reallocate
- a POT sized memory block for glTexImage1D */
- if ((!(feature_mask & GLITZ_FEATURE_TEXTURE_NPOT_MASK)) &&
- (!glitz_uint_is_power_of_two (color_range->size))) {
- glitz_uint_to_power_of_two (&color_range->size);
-
- color_range->data = realloc (color_range->data, color_range->size * 4);
- }
+
+ data = glitz_pixel_buffer_bind (color_range->buffer,
+ GLITZ_GL_PIXEL_UNPACK_BUFFER);
gl->tex_image_1d (GLITZ_GL_TEXTURE_1D, 0, GLITZ_GL_RGBA,
color_range->size, 0,
@@ -132,7 +147,9 @@ glitz_color_range_bind (glitz_gl_proc_address_list_t *gl,
GLITZ_GL_UNSIGNED_BYTE,
#endif
- color_range->data);
+ data);
+
+ glitz_pixel_buffer_unbind (color_range->buffer);
color_range->update_mask &= ~GLITZ_COLOR_RANGE_UPDATE_TEXTURE_MASK;
} else {
@@ -185,7 +202,7 @@ glitz_color_range_bind (glitz_gl_proc_address_list_t *gl,
if (feature_mask & GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK)
gl->tex_parameter_i (GLITZ_GL_TEXTURE_1D,
GLITZ_GL_TEXTURE_WRAP_S,
- GLITZ_GL_MIRRORED_REPEAT_ARB);
+ GLITZ_GL_MIRRORED_REPEAT);
else
gl->tex_parameter_i (GLITZ_GL_TEXTURE_1D,
GLITZ_GL_TEXTURE_WRAP_S,
@@ -196,16 +213,19 @@ glitz_color_range_bind (glitz_gl_proc_address_list_t *gl,
}
}
-unsigned char *
+char *
glitz_color_range_get_data (glitz_color_range_t *color_range)
{
- return color_range->data;
+ return glitz_pixel_buffer_get_data (color_range->buffer,
+ GLITZ_PIXEL_BUFFER_ACCESS_WRITE_ONLY);
}
slim_hidden_def(glitz_color_range_get_data);
void
glitz_color_range_put_back_data (glitz_color_range_t *color_range)
{
+ glitz_pixel_buffer_put_back_data (color_range->buffer);
+
color_range->update_mask |= GLITZ_COLOR_RANGE_UPDATE_TEXTURE_MASK;
}
slim_hidden_def(glitz_color_range_put_back_data);
diff --git a/src/glitz_format.c b/src/glitz_format.c
index 48d530c..f77bf80 100644
--- a/src/glitz_format.c
+++ b/src/glitz_format.c
@@ -35,13 +35,13 @@
static glitz_format_t _texture_formats[] = {
{
- GLITZ_GL_INTENSITY4, 0, 0, 0, 4, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
+ GLITZ_GL_ALPHA4, 0, 0, 0, 4, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
}, {
- GLITZ_GL_INTENSITY8, 0, 0, 0, 8, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
+ GLITZ_GL_ALPHA8, 0, 0, 0, 8, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
}, {
- GLITZ_GL_INTENSITY12, 0, 0, 0, 12, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
+ GLITZ_GL_ALPHA12, 0, 0, 0, 12, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
}, {
- GLITZ_GL_INTENSITY16, 0, 0, 0, 16, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
+ GLITZ_GL_ALPHA16, 0, 0, 0, 16, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
}, {
GLITZ_GL_R3_G3_B2, 3, 3, 2, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
}, {
@@ -106,12 +106,8 @@ glitz_format_for_each_texture_format (glitz_format_call_back_t call_back,
gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
GLITZ_GL_TEXTURE_ALPHA_SIZE, &value);
- if (value != _texture_formats[i].alpha_size) {
- gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
- GLITZ_GL_TEXTURE_INTENSITY_SIZE, &value);
- if (value != _texture_formats[i].alpha_size)
- continue;
- }
+ if (value != _texture_formats[i].alpha_size)
+ continue;
call_back (&_texture_formats[i], ptr);
}
diff --git a/src/glitz_gl.h b/src/glitz_gl.h
index 82f2d99..43a673d 100644
--- a/src/glitz_gl.h
+++ b/src/glitz_gl.h
@@ -28,6 +28,8 @@
#ifndef GLITZ_GL_H_INCLUDED
#define GLITZ_GL_H_INCLUDED
+#include <stddef.h>
+
typedef unsigned int glitz_gl_enum_t;
typedef unsigned char glitz_gl_boolean_t;
typedef void glitz_gl_void_t;
@@ -41,6 +43,8 @@ typedef unsigned int glitz_gl_bitfield_t;
typedef double glitz_gl_clampd_t;
typedef float glitz_gl_clampf_t;
typedef unsigned char glitz_gl_ubyte_t;
+typedef ptrdiff_t glitz_gl_sizeiptr_t;
+
#define GLITZ_GL_FALSE 0x0
#define GLITZ_GL_TRUE 0x1
@@ -83,6 +87,7 @@ typedef unsigned char glitz_gl_ubyte_t;
#define GLITZ_GL_TEXTURE_WRAP_T 0x2803
#define GLITZ_GL_TEXTURE_MAG_FILTER 0x2800
#define GLITZ_GL_TEXTURE_MIN_FILTER 0x2801
+#define GLITZ_GL_TEXTURE_ENV_COLOR 0x2201
#define GLITZ_GL_MODULATE 0x2100
#define GLITZ_GL_NEAREST 0x2600
#define GLITZ_GL_LINEAR 0x2601
@@ -92,7 +97,34 @@ typedef unsigned char glitz_gl_ubyte_t;
#define GLITZ_GL_TEXTURE_GREEN_SIZE 0x805D
#define GLITZ_GL_TEXTURE_BLUE_SIZE 0x805E
#define GLITZ_GL_TEXTURE_ALPHA_SIZE 0x805F
-#define GLITZ_GL_TEXTURE_INTENSITY_SIZE 0x8061
+
+#define GLITZ_GL_TEXTURE 0x1702
+#define GLITZ_GL_SRC_COLOR 0x0300
+
+#define GLITZ_GL_COMBINE 0x8570
+#define GLITZ_GL_COMBINE_RGB 0x8571
+#define GLITZ_GL_COMBINE_ALPHA 0x8572
+#define GLITZ_GL_SOURCE0_RGB 0x8580
+#define GLITZ_GL_SOURCE1_RGB 0x8581
+#define GLITZ_GL_SOURCE2_RGB 0x8582
+#define GLITZ_GL_SOURCE0_ALPHA 0x8588
+#define GLITZ_GL_SOURCE1_ALPHA 0x8589
+#define GLITZ_GL_SOURCE2_ALPHA 0x858A
+#define GLITZ_GL_OPERAND0_RGB 0x8590
+#define GLITZ_GL_OPERAND1_RGB 0x8591
+#define GLITZ_GL_OPERAND2_RGB 0x8592
+#define GLITZ_GL_OPERAND0_ALPHA 0x8598
+#define GLITZ_GL_OPERAND1_ALPHA 0x8599
+#define GLITZ_GL_OPERAND2_ALPHA 0x859A
+#define GLITZ_GL_RGB_SCALE 0x8573
+#define GLITZ_GL_ADD_SIGNED 0x8574
+#define GLITZ_GL_INTERPOLATE 0x8575
+#define GLITZ_GL_SUBTRACT 0x84E7
+#define GLITZ_GL_CONSTANT 0x8576
+#define GLITZ_GL_PRIMARY_COLOR 0x8577
+#define GLITZ_GL_PREVIOUS 0x8578
+#define GLITZ_GL_DOT3_RGB 0x86AE
+#define GLITZ_GL_DOT3_RGBA 0x86AF
#define GLITZ_GL_STENCIL_TEST 0x0B90
#define GLITZ_GL_KEEP 0x1E00
@@ -120,25 +152,24 @@ typedef unsigned char glitz_gl_ubyte_t;
#define GLITZ_GL_BGR 0x80E0
#define GLITZ_GL_BGRA 0x80E1
-#define GLITZ_GL_INTENSITY 0x8049
-#define GLITZ_GL_INTENSITY4 0x804A
-#define GLITZ_GL_INTENSITY8 0x804B
-#define GLITZ_GL_INTENSITY12 0x804C
-#define GLITZ_GL_INTENSITY16 0x804D
-#define GLITZ_GL_R3_G3_B2 0x2A10
-#define GLITZ_GL_RGB4 0x804F
-#define GLITZ_GL_RGB5 0x8050
-#define GLITZ_GL_RGB8 0x8051
-#define GLITZ_GL_RGB10 0x8052
-#define GLITZ_GL_RGB12 0x8053
-#define GLITZ_GL_RGB16 0x8054
-#define GLITZ_GL_RGBA2 0x8055
-#define GLITZ_GL_RGBA4 0x8056
-#define GLITZ_GL_RGB5_A1 0x8057
-#define GLITZ_GL_RGBA8 0x8058
-#define GLITZ_GL_RGB10_A2 0x8059
-#define GLITZ_GL_RGBA12 0x805A
-#define GLITZ_GL_RGBA16 0x805B
+#define GLITZ_GL_ALPHA4 0x803B
+#define GLITZ_GL_ALPHA8 0x803C
+#define GLITZ_GL_ALPHA12 0x803D
+#define GLITZ_GL_ALPHA16 0x803E
+#define GLITZ_GL_R3_G3_B2 0x2A10
+#define GLITZ_GL_RGB4 0x804F
+#define GLITZ_GL_RGB5 0x8050
+#define GLITZ_GL_RGB8 0x8051
+#define GLITZ_GL_RGB10 0x8052
+#define GLITZ_GL_RGB12 0x8053
+#define GLITZ_GL_RGB16 0x8054
+#define GLITZ_GL_RGBA2 0x8055
+#define GLITZ_GL_RGBA4 0x8056
+#define GLITZ_GL_RGB5_A1 0x8057
+#define GLITZ_GL_RGBA8 0x8058
+#define GLITZ_GL_RGB10_A2 0x8059
+#define GLITZ_GL_RGBA12 0x805A
+#define GLITZ_GL_RGBA16 0x805B
#define GLITZ_GL_FRONT_AND_BACK 0x0408
#define GLITZ_GL_FLAT 0x1D00
@@ -168,26 +199,45 @@ typedef unsigned char glitz_gl_ubyte_t;
#define GLITZ_GL_COMPILE 0x1300
-#define GLITZ_GL_TEXTURE_RECTANGLE_EXT 0x84F5
+#define GLITZ_GL_TEXTURE_RECTANGLE 0x84F5
+
+#define GLITZ_GL_MIRRORED_REPEAT 0x8370
-#define GLITZ_GL_MIRRORED_REPEAT_ARB 0x8370
+#define GLITZ_GL_TEXTURE0 0x84C0
+#define GLITZ_GL_TEXTURE1 0x84C1
+#define GLITZ_GL_TEXTURE2 0x84C2
+#define GLITZ_GL_ACTIVE_TEXTURE 0x84E0
+#define GLITZ_GL_MAX_TEXTURE_UNITS 0x84E2
-#define GLITZ_GL_TEXTURE0_ARB 0x84C0
-#define GLITZ_GL_TEXTURE1_ARB 0x84C1
-#define GLITZ_GL_TEXTURE2_ARB 0x84C2
-#define GLITZ_GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GLITZ_GL_MULTISAMPLE 0x809D
-#define GLITZ_GL_MULTISAMPLE_ARB 0x809D
+#define GLITZ_GL_MULTISAMPLE_FILTER_HINT 0x8534
-#define GLITZ_GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
+#define GLITZ_GL_VERTEX_PROGRAM 0x8620
+#define GLITZ_GL_PROGRAM_STRING 0x8628
+#define GLITZ_GL_PROGRAM_FORMAT_ASCII 0x8875
+#define GLITZ_GL_PROGRAM_ERROR_POSITION 0x864B
-#define GLITZ_GL_VERTEX_PROGRAM_ARB 0x8620
-#define GLITZ_GL_PROGRAM_STRING_ARB 0x8628
-#define GLITZ_GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
-#define GLITZ_GL_PROGRAM_ERROR_POSITION_ARB 0x864B
+#define GLITZ_GL_FRAGMENT_PROGRAM 0x8804
+#define GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS 0x880D
+
+#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
+#define GLITZ_GL_STREAM_COPY 0x88E2
+#define GLITZ_GL_STATIC_DRAW 0x88E4
+#define GLITZ_GL_STATIC_READ 0x88E5
+#define GLITZ_GL_STATIC_COPY 0x88E6
+#define GLITZ_GL_DYNAMIC_DRAW 0x88E8
+#define GLITZ_GL_DYNAMIC_READ 0x88E9
+#define GLITZ_GL_DYNAMIC_COPY 0x88EA
+
+#define GLITZ_GL_READ_ONLY 0x88B8
+#define GLITZ_GL_WRITE_ONLY 0x88B9
+#define GLITZ_GL_READ_WRITE 0x88BA
-#define GLITZ_GL_FRAGMENT_PROGRAM_ARB 0x8804
-#define GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
typedef glitz_gl_void_t (* glitz_gl_enable_t)
(glitz_gl_enum_t cap);
@@ -203,6 +253,9 @@ typedef glitz_gl_void_t (* glitz_gl_vertex_2d_t)
(glitz_gl_double_t x, glitz_gl_double_t y);
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)
+ (glitz_gl_enum_t target, glitz_gl_enum_t pname,
+ const glitz_gl_float_t *params);
typedef glitz_gl_void_t (* glitz_gl_tex_coord_2d_t)
(glitz_gl_double_t s, glitz_gl_double_t t);
typedef glitz_gl_void_t (* glitz_gl_scissor_t)
@@ -211,6 +264,9 @@ typedef glitz_gl_void_t (* glitz_gl_scissor_t)
typedef glitz_gl_void_t (* glitz_gl_color_4us_t)
(glitz_gl_ushort_t red, glitz_gl_ushort_t green, glitz_gl_ushort_t blue,
glitz_gl_ushort_t alpha);
+typedef glitz_gl_void_t (* glitz_gl_color_4d_t)
+ (glitz_gl_double_t red, glitz_gl_double_t green, glitz_gl_double_t blue,
+ glitz_gl_double_t alpha);
typedef glitz_gl_void_t (* glitz_gl_blend_func_t)
(glitz_gl_enum_t sfactor, glitz_gl_enum_t dfactor);
typedef glitz_gl_void_t (* glitz_gl_clear_t)
@@ -326,6 +382,8 @@ typedef glitz_gl_void_t (* glitz_gl_copy_tex_sub_image_2d_t)
glitz_gl_sizei_t width, glitz_gl_sizei_t height);
typedef glitz_gl_void_t (* glitz_gl_get_integer_v_t)
(glitz_gl_enum_t pname, glitz_gl_int_t *params);
+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_delete_lists_t)
(glitz_gl_uint_t list, glitz_gl_sizei_t range);
typedef glitz_gl_uint_t (* glitz_gl_gen_lists_t)
@@ -336,24 +394,37 @@ typedef glitz_gl_void_t (* glitz_gl_end_list_t)
(glitz_gl_void_t);
typedef glitz_gl_void_t (* glitz_gl_call_list_t)
(glitz_gl_uint_t list);
-typedef glitz_gl_void_t (* glitz_gl_active_texture_arb_t)
+typedef glitz_gl_void_t (* glitz_gl_active_texture_t)
(glitz_gl_enum_t);
-typedef glitz_gl_void_t (* glitz_gl_multi_tex_coord_2d_arb_t)
+typedef glitz_gl_void_t (* glitz_gl_multi_tex_coord_2d_t)
(glitz_gl_enum_t, glitz_gl_double_t, glitz_gl_double_t);
-typedef glitz_gl_void_t (* glitz_gl_gen_programs_arb_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_arb_t)
+typedef glitz_gl_void_t (* glitz_gl_delete_programs_t)
(glitz_gl_sizei_t, const glitz_gl_uint_t *);
-typedef glitz_gl_void_t (* glitz_gl_program_string_arb_t)
+typedef glitz_gl_void_t (* glitz_gl_program_string_t)
(glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_sizei_t,
const glitz_gl_void_t *);
-typedef glitz_gl_void_t (* glitz_gl_bind_program_arb_t)
+typedef glitz_gl_void_t (* glitz_gl_bind_program_t)
(glitz_gl_enum_t, glitz_gl_uint_t);
-typedef glitz_gl_void_t (* glitz_gl_program_local_param_4d_arb_t)
+typedef glitz_gl_void_t (* glitz_gl_program_local_param_4d_t)
(glitz_gl_enum_t, glitz_gl_uint_t,
glitz_gl_double_t, glitz_gl_double_t,
glitz_gl_double_t, glitz_gl_double_t);
-typedef glitz_gl_void_t (* glitz_gl_get_program_iv_arb_t)
+typedef glitz_gl_void_t (* glitz_gl_get_program_iv_t)
(glitz_gl_enum_t, glitz_gl_enum_t, glitz_gl_uint_t *);
+typedef glitz_gl_void_t (* glitz_gl_gen_buffers_t)
+ (glitz_gl_sizei_t, glitz_gl_uint_t *buffers);
+typedef glitz_gl_void_t (* glitz_gl_delete_buffers_t)
+ (glitz_gl_sizei_t, const glitz_gl_uint_t *buffers);
+typedef glitz_gl_void_t (* glitz_gl_bind_buffer_t)
+ (glitz_gl_enum_t, glitz_gl_uint_t buffer);
+typedef glitz_gl_void_t (* glitz_gl_buffer_data_t)
+ (glitz_gl_enum_t, glitz_gl_sizeiptr_t, const glitz_gl_void_t *,
+ glitz_gl_enum_t);
+typedef glitz_gl_void_t *(* glitz_gl_map_buffer_t)
+ (glitz_gl_enum_t, glitz_gl_enum_t);
+typedef glitz_gl_boolean_t (* glitz_gl_unmap_buffer_t)
+ (glitz_gl_enum_t);
#endif /* GLITZ_GL_H_INCLUDED */
diff --git a/src/glitz_glx_context.c b/src/glitz_glx_context.c
index c062038..711ca13 100644
--- a/src/glitz_glx_context.c
+++ b/src/glitz_glx_context.c
@@ -203,45 +203,63 @@ glitz_glx_context_proc_address_lookup (glitz_glx_screen_info_t *screen_info,
glitz_glx_thread_info_t *thread_info =
screen_info->display_info->thread_info;
- context->glx.bind_tex_image_arb =
- (glitz_glx_bind_tex_image_arb_t)
+ context->glx.bind_tex_image =
+ (glitz_glx_bind_tex_image_t)
glitz_glx_get_proc_address (thread_info, "glXBindTexImageARB");
- context->glx.release_tex_image_arb =
- (glitz_glx_release_tex_image_arb_t)
+ context->glx.release_tex_image =
+ (glitz_glx_release_tex_image_t)
glitz_glx_get_proc_address (thread_info, "glXReleaseTexImageARB");
- context->gl.active_texture_arb =
- (glitz_gl_active_texture_arb_t)
+ context->gl.active_texture =
+ (glitz_gl_active_texture_t)
glitz_glx_get_proc_address (thread_info, "glActiveTextureARB");
- context->gl.multi_tex_coord_2d_arb =
- (glitz_gl_multi_tex_coord_2d_arb_t)
+ context->gl.multi_tex_coord_2d =
+ (glitz_gl_multi_tex_coord_2d_t)
glitz_glx_get_proc_address (thread_info, "glMultiTexCoord2dARB");
- context->gl.gen_programs_arb =
- (glitz_gl_gen_programs_arb_t)
+ context->gl.gen_programs =
+ (glitz_gl_gen_programs_t)
glitz_glx_get_proc_address (thread_info, "glGenProgramsARB");
- context->gl.delete_programs_arb =
- (glitz_gl_delete_programs_arb_t)
+ context->gl.delete_programs =
+ (glitz_gl_delete_programs_t)
glitz_glx_get_proc_address (thread_info, "glDeleteProgramsARB");
- context->gl.program_string_arb =
- (glitz_gl_program_string_arb_t)
+ context->gl.program_string =
+ (glitz_gl_program_string_t)
glitz_glx_get_proc_address (thread_info, "glProgramStringARB");
- context->gl.bind_program_arb =
- (glitz_gl_bind_program_arb_t)
+ context->gl.bind_program =
+ (glitz_gl_bind_program_t)
glitz_glx_get_proc_address (thread_info, "glBindProgramARB");
- context->gl.program_local_param_4d_arb =
- (glitz_gl_program_local_param_4d_arb_t)
+ context->gl.program_local_param_4d =
+ (glitz_gl_program_local_param_4d_t)
glitz_glx_get_proc_address (thread_info, "glProgramLocalParameter4dARB");
- context->gl.get_program_iv_arb =
- (glitz_gl_get_program_iv_arb_t)
+ context->gl.get_program_iv =
+ (glitz_gl_get_program_iv_t)
glitz_glx_get_proc_address (thread_info, "glGetProgramivARB");
+ context->gl.gen_buffers =
+ (glitz_gl_gen_buffers_t)
+ glitz_glx_get_proc_address (thread_info, "glGenBuffers");
+ context->gl.delete_buffers =
+ (glitz_gl_delete_buffers_t)
+ glitz_glx_get_proc_address (thread_info, "glDeleteBuffers");
+ context->gl.bind_buffer =
+ (glitz_gl_bind_buffer_t)
+ glitz_glx_get_proc_address (thread_info, "glBindBuffer");
+ context->gl.buffer_data =
+ (glitz_gl_buffer_data_t)
+ glitz_glx_get_proc_address (thread_info, "glBufferData");
+ context->gl.map_buffer =
+ (glitz_gl_map_buffer_t)
+ glitz_glx_get_proc_address (thread_info, "glMapBuffer");
+ context->gl.unmap_buffer =
+ (glitz_gl_unmap_buffer_t)
+ glitz_glx_get_proc_address (thread_info, "glUnmapBuffer");
+
if (screen_info->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) {
- if (context->gl.get_program_iv_arb) {
- context->gl.get_program_iv_arb
- (GLITZ_GL_FRAGMENT_PROGRAM_ARB,
- GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB,
- &context->texture_indirections);
+ if (context->gl.get_program_iv) {
+ context->gl.get_program_iv (GLITZ_GL_FRAGMENT_PROGRAM,
+ GLITZ_GL_MAX_PROGRAM_TEX_INDIRECTIONS,
+ &context->texture_indirections);
}
}
@@ -254,17 +272,17 @@ glitz_glx_context_set_surface_anti_aliasing (glitz_glx_surface_t *surface)
{
if (surface->base.format->multisample.supported) {
if (surface->base.polyedge == GLITZ_POLYEDGE_SMOOTH) {
- glEnable (GLITZ_GL_MULTISAMPLE_ARB);
+ glEnable (GLITZ_GL_MULTISAMPLE);
if (surface->screen_info->glx_feature_mask &
GLITZ_GLX_FEATURE_MULTISAMPLE_FILTER_MASK) {
if (surface->base.polyedge_smooth_hint ==
GLITZ_POLYEDGE_SMOOTH_HINT_FAST)
- glHint (GLITZ_GL_MULTISAMPLE_FILTER_HINT_NV, GLITZ_GL_FASTEST);
+ glHint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_FASTEST);
else
- glHint (GLITZ_GL_MULTISAMPLE_FILTER_HINT_NV, GLITZ_GL_NICEST);
+ glHint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_NICEST);
}
} else
- glDisable (GLITZ_GL_MULTISAMPLE_ARB);
+ glDisable (GLITZ_GL_MULTISAMPLE);
}
}
diff --git a/src/glitz_glx_extension.c b/src/glitz_glx_extension.c
index af5f2df..c7064a9 100644
--- a/src/glitz_glx_extension.c
+++ b/src/glitz_glx_extension.c
@@ -43,12 +43,16 @@ static glitz_extension_map client_glx_extensions[] = {
{ "GL_ARB_texture_non_power_of_two", GLITZ_GLX_FEATURE_TEXTURE_NPOT_MASK },
{ "GL_ARB_texture_mirrored_repeat",
GLITZ_GLX_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK },
+ { "GL_ARB_texture_env_combine",
+ GLITZ_GLX_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK },
+ { "GL_ARB_texture_env_dot3", GLITZ_GLX_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK },
{ "GL_ARB_multisample", GLITZ_GLX_FEATURE_MULTISAMPLE_MASK },
{ "GL_NV_multisample_filter_hint",
GLITZ_GLX_FEATURE_MULTISAMPLE_FILTER_MASK },
{ "GL_ARB_multitexture", GLITZ_GLX_FEATURE_ARB_MULTITEXTURE_MASK },
{ "GL_ARB_vertex_program", GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK },
{ "GL_ARB_fragment_program", GLITZ_GLX_FEATURE_ARB_FRAGMENT_PROGRAM_MASK },
+ { "GL_EXT_pixel_buffer_object", GLITZ_GLX_FEATURE_PIXEL_BUFFER_OBJECT_MASK },
{ NULL, 0 }
};
@@ -134,6 +138,25 @@ glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info)
screen_info->feature_mask |= GLITZ_FEATURE_ARB_MULTITEXTURE_MASK;
if (screen_info->glx_feature_mask &
+ GLITZ_GLX_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK)
+ screen_info->feature_mask |= GLITZ_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK;
+
+ if (screen_info->glx_feature_mask &
+ GLITZ_GLX_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK)
+ screen_info->feature_mask |= GLITZ_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK;
+
+ if ((screen_info->feature_mask &
+ GLITZ_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK) &&
+ (screen_info->feature_mask &
+ GLITZ_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK)) {
+ glitz_gl_int_t max_texture_units;
+
+ glGetIntegerv (GLITZ_GL_MAX_TEXTURE_UNITS, &max_texture_units);
+ if (max_texture_units >= 3)
+ screen_info->feature_mask |= GLITZ_FEATURE_COMPONENT_ALPHA_MASK;
+ }
+
+ if (screen_info->glx_feature_mask &
GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK)
screen_info->feature_mask |= GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK;
@@ -145,4 +168,8 @@ glitz_glx_query_extensions (glitz_glx_screen_info_t *screen_info)
(screen_info->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK))
screen_info->feature_mask |= GLITZ_FEATURE_CONVOLUTION_FILTER_MASK;
}
+
+ if (screen_info->glx_feature_mask &
+ GLITZ_GLX_FEATURE_PIXEL_BUFFER_OBJECT_MASK)
+ screen_info->feature_mask |= GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK;
}
diff --git a/src/glitz_glx_info.c b/src/glitz_glx_info.c
index 143df1d..23eb5e3 100644
--- a/src/glitz_glx_info.c
+++ b/src/glitz_glx_info.c
@@ -42,8 +42,10 @@ glitz_gl_proc_address_list_t _glitz_gl_proc_address = {
(glitz_gl_vertex_2i_t) glVertex2i,
(glitz_gl_vertex_2d_t) glVertex2d,
(glitz_gl_tex_env_f_t) glTexEnvf,
+ (glitz_gl_tex_env_fv_t) glTexEnvfv,
(glitz_gl_tex_coord_2d_t) glTexCoord2d,
(glitz_gl_color_4us_t) glColor4us,
+ (glitz_gl_color_4d_t) glColor4d,
(glitz_gl_scissor_t) glScissor,
(glitz_gl_blend_func_t) glBlendFunc,
(glitz_gl_clear_t) glClear,
@@ -92,14 +94,20 @@ glitz_gl_proc_address_list_t _glitz_gl_proc_address = {
(glitz_gl_end_list_t) glEndList,
(glitz_gl_call_list_t) glCallList,
- (glitz_gl_active_texture_arb_t) 0,
- (glitz_gl_multi_tex_coord_2d_arb_t) 0,
- (glitz_gl_gen_programs_arb_t) 0,
- (glitz_gl_delete_programs_arb_t) 0,
- (glitz_gl_program_string_arb_t) 0,
- (glitz_gl_bind_program_arb_t) 0,
- (glitz_gl_program_local_param_4d_arb_t) 0,
- (glitz_gl_get_program_iv_arb_t) 0,
+ (glitz_gl_active_texture_t) 0,
+ (glitz_gl_multi_tex_coord_2d_t) 0,
+ (glitz_gl_gen_programs_t) 0,
+ (glitz_gl_delete_programs_t) 0,
+ (glitz_gl_program_string_t) 0,
+ (glitz_gl_bind_program_t) 0,
+ (glitz_gl_program_local_param_4d_t) 0,
+ (glitz_gl_get_program_iv_t) 0,
+ (glitz_gl_gen_buffers_t) 0,
+ (glitz_gl_delete_buffers_t) 0,
+ (glitz_gl_bind_buffer_t) 0,
+ (glitz_gl_buffer_data_t) 0,
+ (glitz_gl_map_buffer_t) 0,
+ (glitz_gl_unmap_buffer_t) 0,
1
};
@@ -108,8 +116,8 @@ glitz_glx_get_proc_address (glitz_glx_thread_info_t *info, const char *name)
{
glitz_function_pointer_t address = NULL;
- if (info->glx.get_proc_address_arb)
- address = info->glx.get_proc_address_arb ((glitz_gl_ubyte_t *) name);
+ if (info->glx.get_proc_address)
+ address = info->glx.get_proc_address ((glitz_gl_ubyte_t *) name);
if (!address) {
if (!info->dlhand)
@@ -141,7 +149,7 @@ glitz_glx_proc_address_lookup (glitz_glx_thread_info_t *info)
glitz_glx_get_proc_address (info, "glXDestroyPbuffer");
info->glx.make_context_current = (glitz_glx_make_context_current_t)
glitz_glx_get_proc_address (info, "glXMakeContextCurrent");
- info->glx.get_proc_address_arb = (glitz_glx_get_proc_address_arb_t)
+ info->glx.get_proc_address = (glitz_glx_get_proc_address_t)
glitz_glx_get_proc_address (info, "glXGetProcAddressARB");
info->glx.need_lookup = 0;
@@ -211,25 +219,33 @@ static glitz_glx_thread_info_t *
glitz_glx_thread_info_get (const char *gl_library)
{
glitz_glx_thread_info_t *thread_info;
+ void *p;
if (!tsd_initialized) {
- thread_info = malloc (sizeof (glitz_glx_thread_info_t));
- glitz_glx_thread_info_init (thread_info);
-
xthread_key_create (&info_tsd, glitz_glx_thread_info_destroy);
- xthread_set_specific (info_tsd, thread_info);
-
tsd_initialized = 1;
- } else {
- void *p;
+ }
- xthread_get_specific (info_tsd, &p);
+ xthread_get_specific (info_tsd, &p);
+
+ if (p == NULL) {
+ thread_info = malloc (sizeof (glitz_glx_thread_info_t));
+ glitz_glx_thread_info_init (thread_info);
+
+ xthread_set_specific (info_tsd, thread_info);
+ } else
thread_info = (glitz_glx_thread_info_t *) p;
- }
if (thread_info->glx.need_lookup) {
- if (gl_library)
- thread_info->gl_library = strdup (gl_library);
+ if (gl_library) {
+ int len = strlen (gl_library);
+
+ thread_info->gl_library = malloc (len + 1);
+ if (thread_info->gl_library) {
+ memcpy (thread_info->gl_library, gl_library, len);
+ thread_info->gl_library[len] = '\0';
+ }
+ }
glitz_glx_proc_address_lookup (thread_info);
}
@@ -300,7 +316,10 @@ glitz_glx_display_destroy (glitz_glx_display_info_t *display_info)
for (i = 0; i < display_info->n_screens; i++)
glitz_glx_screen_destroy (display_info->screens[i]);
- free (display_info->screens);
+ if (display_info->screens)
+ free (display_info->screens);
+
+ free (display_info);
}
static void
@@ -402,7 +421,7 @@ glitz_glx_screen_info_get (Display *display,
screen_info->contexts = NULL;
screen_info->n_contexts = 0;
- memset (&screen_info->programs, 0, sizeof (glitz_programs_t));
+ glitz_program_map_init (&screen_info->program_map);
glitz_glx_create_root_context (screen_info);
@@ -439,8 +458,8 @@ glitz_glx_screen_destroy (glitz_glx_screen_info_t *screen_info)
glXMakeCurrent (screen_info->display_info->display,
screen_info->root_drawable,
screen_info->root_context.context)) {
- glitz_programs_fini (&screen_info->root_context.gl,
- &screen_info->programs);
+ glitz_program_map_fini (&screen_info->root_context.gl,
+ &screen_info->program_map);
}
glXMakeCurrent (display, None, NULL);
diff --git a/src/glitz_glx_surface.c b/src/glitz_glx_surface.c
index b2230ab..f603f1c 100644
--- a/src/glitz_glx_surface.c
+++ b/src/glitz_glx_surface.c
@@ -171,11 +171,11 @@ _glitz_glx_set_features (glitz_glx_surface_t *surface)
{
surface->base.feature_mask = surface->screen_info->feature_mask;
+ surface->base.feature_mask &= ~GLITZ_FEATURE_ARB_MULTITEXTURE_MASK;
surface->base.feature_mask &= ~GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK;
surface->base.feature_mask &= ~GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK;
surface->base.feature_mask &= ~GLITZ_FEATURE_CONVOLUTION_FILTER_MASK;
- surface->base.feature_mask &= ~GLITZ_FEATURE_MULTISAMPLE_MASK;
- surface->base.feature_mask &= ~GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK;
+ surface->base.feature_mask &= ~GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK;
if (surface->context->glx.need_lookup) {
glitz_surface_push_current (&surface->base,
@@ -185,41 +185,49 @@ _glitz_glx_set_features (glitz_glx_surface_t *surface)
if ((surface->screen_info->glx_feature_mask &
GLITZ_GLX_FEATURE_ARB_RENDER_TEXTURE_MASK) &&
- surface->context->glx.bind_tex_image_arb &&
- surface->context->glx.release_tex_image_arb)
+ surface->context->glx.bind_tex_image &&
+ surface->context->glx.release_tex_image)
surface->render_texture = 1;
- if (surface->context->gl.active_texture_arb &&
- surface->context->gl.multi_tex_coord_2d_arb &&
- surface->context->gl.gen_programs_arb &&
- surface->context->gl.delete_programs_arb &&
- surface->context->gl.program_string_arb &&
- surface->context->gl.bind_program_arb) {
- if (surface->screen_info->feature_mask &
- GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK)
- surface->base.feature_mask |= GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK;
-
- if (surface->screen_info->feature_mask &
- GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK)
- surface->base.feature_mask |= GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK;
+ if (surface->context->gl.active_texture &&
+ surface->context->gl.multi_tex_coord_2d) {
+ surface->base.feature_mask |= GLITZ_FEATURE_ARB_MULTITEXTURE_MASK;
+
+ if (surface->context->gl.gen_programs &&
+ surface->context->gl.delete_programs &&
+ surface->context->gl.program_string &&
+ surface->context->gl.bind_program &&
+ surface->context->gl.program_local_param_4d) {
+
+ if (surface->screen_info->feature_mask &
+ GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK)
+ surface->base.feature_mask |= GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK;
+
+ if (surface->screen_info->feature_mask &
+ GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK)
+ surface->base.feature_mask |= GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK;
- if ((surface->base.feature_mask & GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK) &&
- (surface->base.feature_mask &
- GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) &&
- surface->context->gl.program_local_param_4d_arb &&
- surface->context->texture_indirections >= 9) {
- /* Convolution filter programs require support for at least nine
- texture indirections. */
- surface->base.feature_mask |= GLITZ_FEATURE_CONVOLUTION_FILTER_MASK;
+ if ((surface->base.feature_mask &
+ GLITZ_FEATURE_ARB_VERTEX_PROGRAM_MASK) &&
+ (surface->base.feature_mask &
+ GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) &&
+ surface->context->texture_indirections >= 9) {
+ /* Convolution filter programs require support for at least nine
+ texture indirections. */
+ surface->base.feature_mask |= GLITZ_FEATURE_CONVOLUTION_FILTER_MASK;
+ }
}
}
- if (surface->screen_info->feature_mask & GLITZ_FEATURE_MULTISAMPLE_MASK)
- surface->base.feature_mask |= GLITZ_FEATURE_MULTISAMPLE_MASK;
-
- if (surface->screen_info->feature_mask &
- GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK)
- surface->base.feature_mask |= GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK;
+ if (surface->context->gl.gen_buffers &&
+ surface->context->gl.delete_buffers &&
+ surface->context->gl.bind_buffer &&
+ surface->context->gl.buffer_data &&
+ surface->context->gl.map_buffer &&
+ surface->context->gl.unmap_buffer)
+ if (surface->screen_info->feature_mask &
+ GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)
+ surface->base.feature_mask |= GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK;
}
static glitz_surface_t *
@@ -247,7 +255,7 @@ _glitz_glx_surface_create (glitz_glx_screen_info_t *screen_info,
screen_info->n_formats,
width,
height,
- &screen_info->programs,
+ &screen_info->program_map,
screen_info->texture_mask);
surface->screen_info = screen_info;
@@ -318,7 +326,7 @@ glitz_glx_surface_create_for_window (Display *display,
screen_info->n_formats,
width,
height,
- &screen_info->programs,
+ &screen_info->program_map,
screen_info->texture_mask);
surface->screen_info = screen_info;
diff --git a/src/glitz_glxext.h b/src/glitz_glxext.h
index 22fbcc1..58266e0 100644
--- a/src/glitz_glxext.h
+++ b/src/glitz_glxext.h
@@ -94,7 +94,7 @@ typedef XID GLXPbuffer;
#endif
-typedef glitz_function_pointer_t (* glitz_glx_get_proc_address_arb_t)
+typedef glitz_function_pointer_t (* glitz_glx_get_proc_address_t)
(const glitz_gl_ubyte_t *);
typedef GLXFBConfig *(* glitz_glx_get_fbconfigs_t)
(Display *display, int screen, int *n_elements);
@@ -114,9 +114,9 @@ typedef Bool (* glitz_glx_make_context_current_t)
#define GLX_SAMPLES_ARB 0x186a1
#endif
-typedef Bool *(* glitz_glx_bind_tex_image_arb_t)
+typedef Bool *(* glitz_glx_bind_tex_image_t)
(Display *display, GLXPbuffer pbuffer, int buffer);
-typedef Bool (* glitz_glx_release_tex_image_arb_t)
+typedef Bool (* glitz_glx_release_tex_image_t)
(Display *display, GLXPbuffer pbuffer, int buffer);
#endif /* GLITZ_GLXEXT_H_INCLUDED */
diff --git a/src/glitz_glxint.h b/src/glitz_glxint.h
index f091eaf..7f2b54e 100644
--- a/src/glitz_glxint.h
+++ b/src/glitz_glxint.h
@@ -44,17 +44,20 @@
#define GLITZ_GLX_FEATURE_CLIENT_MULTISAMPLE_MASK (1L << 4)
#define GLITZ_GLX_FEATURE_MULTISAMPLE_FILTER_MASK (1L << 5)
#define GLITZ_GLX_FEATURE_ARB_MULTITEXTURE_MASK (1L << 6)
-#define GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 7)
-#define GLITZ_GLX_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 8)
-#define GLITZ_GLX_FEATURE_GLX13_MASK (1L << 9)
-#define GLITZ_GLX_FEATURE_ARB_RENDER_TEXTURE_MASK (1L << 10)
+#define GLITZ_GLX_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK (1L << 7)
+#define GLITZ_GLX_FEATURE_ARB_TEXTURE_ENV_DOT3_MASK (1L << 8)
+#define GLITZ_GLX_FEATURE_ARB_VERTEX_PROGRAM_MASK (1L << 9)
+#define GLITZ_GLX_FEATURE_ARB_FRAGMENT_PROGRAM_MASK (1L << 10)
+#define GLITZ_GLX_FEATURE_GLX13_MASK (1L << 11)
+#define GLITZ_GLX_FEATURE_ARB_RENDER_TEXTURE_MASK (1L << 12)
+#define GLITZ_GLX_FEATURE_PIXEL_BUFFER_OBJECT_MASK (1L << 13)
typedef struct _glitz_glx_surface glitz_glx_surface_t;
typedef struct _glitz_glx_screen_info_t glitz_glx_screen_info_t;
typedef struct _glitz_glx_display_info_t glitz_glx_display_info_t;
typedef struct _glitz_glx_static_proc_address_list_t {
- glitz_glx_get_proc_address_arb_t get_proc_address_arb;
+ glitz_glx_get_proc_address_t get_proc_address;
glitz_glx_get_fbconfigs_t get_fbconfigs;
glitz_glx_get_fbconfig_attrib_t get_fbconfig_attrib;
glitz_glx_get_visual_from_fbconfig_t get_visual_from_fbconfig;
@@ -65,8 +68,8 @@ typedef struct _glitz_glx_static_proc_address_list_t {
} glitz_glx_static_proc_address_list_t;
typedef struct _glitz_glx_proc_address_list_t {
- glitz_glx_bind_tex_image_arb_t bind_tex_image_arb;
- glitz_glx_release_tex_image_arb_t release_tex_image_arb;
+ glitz_glx_bind_tex_image_t bind_tex_image;
+ glitz_glx_release_tex_image_t release_tex_image;
glitz_bool_t need_lookup;
} glitz_glx_proc_address_list_t;
@@ -120,7 +123,7 @@ struct _glitz_glx_screen_info_t {
long int glx_feature_mask;
long int texture_mask;
- glitz_programs_t programs;
+ glitz_program_map_t program_map;
};
struct _glitz_glx_surface {
diff --git a/src/glitz_pixel.c b/src/glitz_pixel.c
index 419c99d..77fe0a6 100644
--- a/src/glitz_pixel.c
+++ b/src/glitz_pixel.c
@@ -1,25 +1,24 @@
/*
- * Copyright © 2004 David Reveman, Peter Nilsson
- *
+ * Copyright © 2004 David Reveman
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the names of
- * David Reveman and Peter Nilsson not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. David Reveman and Peter Nilsson
- * makes no representations about the suitability of this software for
- * any purpose. It is provided "as is" without express or implied warranty.
+ * David Reveman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * David Reveman makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
*
- * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
- * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
- * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <c99drn@cs.umu.se>
*/
@@ -48,7 +47,7 @@ static struct _glitz_gl_pixel_format {
0x00000000,
0x00000000
},
- 0, 0,
+ 0, 0, 0,
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
},
GLITZ_GL_ALPHA,
@@ -62,7 +61,7 @@ static struct _glitz_gl_pixel_format {
0x0000ff00,
0x000000ff
},
- 0, 0,
+ 0, 0, 0,
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
},
@@ -73,7 +72,6 @@ static struct _glitz_gl_pixel_format {
#endif
GLITZ_GL_UNSIGNED_BYTE
-
}, {
{
{
@@ -83,7 +81,7 @@ static struct _glitz_gl_pixel_format {
0x0000ff00,
0x000000ff
},
- 0, 0,
+ 0, 0, 0,
GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
},
GLITZ_GL_BGRA,
@@ -289,9 +287,7 @@ _glitz_pixel_transform (unsigned long transform,
glitz_image_t *src,
glitz_image_t *dst,
int x_src,
- int y_src,
int x_dst,
- int y_dst,
int width,
int height)
{
@@ -356,11 +352,11 @@ _glitz_pixel_transform (unsigned long transform,
for (y = 0; y < height; y++) {
if (src->format->scanline_order != dst->format->scanline_order)
- src_op.line = &src->data[(src->height - (y + y_src) - 1) * src_stride];
+ src_op.line = &src->data[(src->height - y - 1) * src_stride];
else
- src_op.line = &src->data[(y + y_src) * src_stride];
+ src_op.line = &src->data[y * src_stride];
- dst_op.line = &dst->data[(y + y_dst) * dst_stride];
+ dst_op.line = &dst->data[y * dst_stride];
if (transform & GLITZ_TRANSFORM_PIXELS_MASK) {
for (x = 0; x < width; x++) {
@@ -410,21 +406,257 @@ _glitz_best_gl_pixel_format (glitz_format_t *format)
return &_gl_format_map[GLITZ_GL_FORMAT_A];
}
+struct _glitz_pixel_buffer {
+ glitz_gl_sizei_t size;
+ glitz_gl_uint_t name;
+ glitz_gl_enum_t target;
+ char *data;
+ int owns_data;
+ glitz_surface_t *surface;
+ glitz_pixel_format_t format;
+};
+
+glitz_pixel_buffer_t *
+glitz_pixel_buffer_create (glitz_surface_t *surface,
+ char *data,
+ unsigned int size,
+ glitz_buffer_hint_t hint)
+{
+ glitz_pixel_buffer_t *buffer;
+ glitz_gl_enum_t usage;
+
+ buffer = malloc (sizeof (glitz_pixel_buffer_t));
+ if (buffer == NULL)
+ return NULL;
+
+ buffer->size = size;
+ buffer->name = 0;
+
+ switch (hint) {
+ case GLITZ_PIXEL_BUFFER_HINT_STREAM_DRAW:
+ usage = GLITZ_GL_STREAM_DRAW;
+ buffer->target = GLITZ_GL_PIXEL_UNPACK_BUFFER;
+ break;
+ case GLITZ_PIXEL_BUFFER_HINT_STREAM_READ:
+ usage = GLITZ_GL_STREAM_READ;
+ buffer->target = GLITZ_GL_PIXEL_PACK_BUFFER;
+ break;
+ case GLITZ_PIXEL_BUFFER_HINT_STREAM_COPY:
+ usage = GLITZ_GL_STREAM_COPY;
+ buffer->target = GLITZ_GL_PIXEL_UNPACK_BUFFER;
+ break;
+ case GLITZ_PIXEL_BUFFER_HINT_STATIC_DRAW:
+ usage = GLITZ_GL_STATIC_DRAW;
+ buffer->target = GLITZ_GL_PIXEL_UNPACK_BUFFER;
+ break;
+ case GLITZ_PIXEL_BUFFER_HINT_STATIC_READ:
+ usage = GLITZ_GL_STATIC_READ;
+ buffer->target = GLITZ_GL_PIXEL_PACK_BUFFER;
+ break;
+ case GLITZ_PIXEL_BUFFER_HINT_STATIC_COPY:
+ usage = GLITZ_GL_STATIC_COPY;
+ buffer->target = GLITZ_GL_PIXEL_UNPACK_BUFFER;
+ break;
+ case GLITZ_PIXEL_BUFFER_HINT_DYNAMIC_DRAW:
+ usage = GLITZ_GL_DYNAMIC_DRAW;
+ buffer->target = GLITZ_GL_PIXEL_UNPACK_BUFFER;
+ break;
+ case GLITZ_PIXEL_BUFFER_HINT_DYNAMIC_READ:
+ usage = GLITZ_GL_DYNAMIC_READ;
+ buffer->target = GLITZ_GL_PIXEL_PACK_BUFFER;
+ break;
+ default:
+ usage = GLITZ_GL_DYNAMIC_COPY;
+ buffer->target = GLITZ_GL_PIXEL_UNPACK_BUFFER;
+ break;
+ }
+
+ if (surface->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK) {
+ buffer->surface = surface;
+ glitz_surface_reference (surface);
+
+ glitz_surface_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
+
+ surface->gl->gen_buffers (1, &buffer->name);
+ if (buffer->name) {
+ surface->gl->bind_buffer (buffer->target, buffer->name);
+ surface->gl->buffer_data (buffer->target, size, data, usage);
+ }
+
+ glitz_surface_pop_current (surface);
+ } else
+ buffer->surface = NULL;
+
+ if (buffer->name == 0) {
+ buffer->data = malloc (size);
+ if (buffer->data == NULL) {
+ free (buffer);
+ return NULL;
+ }
+
+ if (data)
+ memcpy (buffer->data, data, size);
+
+ buffer->owns_data = 1;
+ }
+
+ buffer->format = _glitz_best_gl_pixel_format (surface->format)->pixel;
+
+ return buffer;
+}
+
+glitz_pixel_buffer_t *
+glitz_pixel_buffer_create_for_data (char *data,
+ glitz_pixel_format_t *format)
+{
+ glitz_pixel_buffer_t *buffer;
+
+ buffer = malloc (sizeof (glitz_pixel_buffer_t));
+ if (buffer == NULL)
+ return NULL;
+
+ buffer->name = 0;
+ buffer->size = 0;
+ buffer->data = data;
+ buffer->owns_data = 0;
+ buffer->surface = NULL;
+ buffer->target = 0;
+ buffer->format = *format;
+
+ return buffer;
+}
+
+void
+glitz_pixel_buffer_destroy (glitz_pixel_buffer_t *buffer)
+{
+ glitz_surface_t *surface = buffer->surface;
+
+ if (surface &&
+ surface->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK) {
+ glitz_surface_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
+
+ surface->gl->delete_buffers (1, &buffer->name);
+
+ glitz_surface_pop_current (surface);
+
+ glitz_surface_destroy (surface);
+ } else if (buffer->owns_data)
+ free (buffer->data);
+
+ free (buffer);
+}
+
+void
+glitz_pixel_buffer_set_format (glitz_pixel_buffer_t *buffer,
+ glitz_pixel_format_t *format)
+{
+ buffer->format = *format;
+}
+
+void
+glitz_pixel_buffer_get_format (glitz_pixel_buffer_t *buffer,
+ glitz_pixel_format_t *format)
+{
+ *format = buffer->format;
+}
+
+char *
+glitz_pixel_buffer_get_data (glitz_pixel_buffer_t *buffer,
+ glitz_pixel_buffer_access_t access)
+{
+ char *pointer = NULL;
+ glitz_surface_t *surface = buffer->surface;
+
+ if (surface &&
+ surface->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK) {
+ glitz_gl_enum_t buffer_access;
+
+ glitz_surface_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
+
+ switch (access) {
+ case GLITZ_PIXEL_BUFFER_ACCESS_READ_ONLY:
+ buffer_access = GLITZ_GL_READ_ONLY;
+ break;
+ case GLITZ_PIXEL_BUFFER_ACCESS_WRITE_ONLY:
+ buffer_access = GLITZ_GL_WRITE_ONLY;
+ break;
+ default:
+ buffer_access = GLITZ_GL_READ_WRITE;
+ break;
+ }
+
+ surface->gl->bind_buffer (buffer->target, buffer->name);
+ pointer = (char *) surface->gl->map_buffer (buffer->target,
+ buffer_access);
+
+ glitz_surface_pop_current (surface);
+ }
+
+ if (pointer == NULL)
+ pointer = buffer->data;
+
+ return pointer;
+}
+
+void
+glitz_pixel_buffer_put_back_data (glitz_pixel_buffer_t *buffer)
+{
+ glitz_surface_t *surface = buffer->surface;
+
+ if (surface &&
+ surface->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK) {
+ glitz_surface_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
+
+ if (surface->gl->unmap_buffer (buffer->target)) {
+ /* don't know what to do here, maybe glitz_pixel_buffer_put_back_data
+ should return a status value */
+ }
+ surface->gl->bind_buffer (buffer->target, 0);
+
+ glitz_surface_pop_current (surface);
+ }
+}
+
+char *
+glitz_pixel_buffer_bind (glitz_pixel_buffer_t *buffer,
+ glitz_gl_enum_t target)
+{
+ glitz_surface_t *surface = buffer->surface;
+
+ if (surface &&
+ surface->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK) {
+ surface->gl->bind_buffer (target, buffer->name);
+ buffer->target = target;
+
+ return NULL;
+ }
+
+ return buffer->data;
+}
+
+void
+glitz_pixel_buffer_unbind (glitz_pixel_buffer_t *buffer)
+{
+ glitz_surface_t *surface = buffer->surface;
+
+ if (surface &&
+ surface->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)
+ surface->gl->bind_buffer (buffer->target, 0);
+}
+
void
glitz_put_pixels (glitz_surface_t *dst,
int x_dst,
int y_dst,
int width,
int height,
- glitz_pixel_format_t *format,
- char *pixels)
+ glitz_pixel_buffer_t *buffer)
{
glitz_gl_proc_address_list_t *gl;
glitz_bool_t drawable;
- char *data = NULL;
- glitz_gl_pixel_format_t *gl_format = NULL;
+ char *pixels, *data = NULL;
+ glitz_gl_pixel_format_t *format = NULL;
unsigned long transform = 0;
- glitz_gl_enum_t image_format;
int xoffset, bytes_per_line;
if (SURFACE_PROGRAMMATIC (dst))
@@ -438,21 +670,26 @@ glitz_put_pixels (glitz_surface_t *dst,
gl = dst->gl;
- if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
+ if (buffer->format.scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK;
/* find direct format */
- gl_format = _glitz_find_gl_pixel_format (format);
- if (gl_format == NULL) {
+ format = _glitz_find_gl_pixel_format (&buffer->format);
+ if (format == NULL) {
transform |= GLITZ_TRANSFORM_PIXELS_MASK;
- gl_format = _glitz_best_gl_pixel_format (dst->format);
+ format = _glitz_best_gl_pixel_format (dst->format);
}
+
+ if (glitz_surface_try_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT))
+ drawable = 1;
+ else
+ drawable = 0;
if (transform) {
glitz_image_t src_image, dst_image;
int stride;
- stride = (((width * gl_format->pixel.masks.bpp) / 8) + 3) & -4;
+ stride = (((width * format->pixel.masks.bpp) / 8) + 3) & -4;
data = malloc (stride * height);
if (!data) {
@@ -461,34 +698,38 @@ glitz_put_pixels (glitz_surface_t *dst,
}
dst_image.data = data;
- dst_image.format = &gl_format->pixel;
+ dst_image.format = &format->pixel;
dst_image.width = width;
dst_image.height = height;
- src_image.data = pixels;
- src_image.format = format;
+ src_image.data =
+ glitz_pixel_buffer_get_data (buffer,
+ GLITZ_PIXEL_BUFFER_ACCESS_READ_ONLY);
+ src_image.data += buffer->format.skip_lines *
+ buffer->format.bytes_per_line;
+ src_image.format = &buffer->format;
src_image.width = width;
src_image.height = height;
_glitz_pixel_transform (transform,
&src_image,
&dst_image,
- format->xoffset, 0,
- 0, 0,
+ buffer->format.xoffset,
+ 0,
width, height);
+
+ glitz_pixel_buffer_put_back_data (buffer);
+
pixels = data;
xoffset = 0;
bytes_per_line = stride;
} else {
- xoffset = format->xoffset;
- bytes_per_line = format->bytes_per_line;
+ xoffset = buffer->format.xoffset;
+ bytes_per_line = buffer->format.bytes_per_line;
+ pixels = glitz_pixel_buffer_bind (buffer, GLITZ_GL_PIXEL_UNPACK_BUFFER);
+ pixels += buffer->format.skip_lines * bytes_per_line;
}
-
- if (glitz_surface_try_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT))
- drawable = 1;
- else
- drawable = 0;
-
+
glitz_texture_bind (gl, &dst->texture);
gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0);
@@ -505,24 +746,18 @@ glitz_put_pixels (glitz_surface_t *dst,
else
gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 2);
} else
- gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1);
-
- if (gl_format->format == GLITZ_GL_ALPHA)
- image_format = GLITZ_GL_LUMINANCE;
- else
- image_format = gl_format->format;
+ gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1);
gl->tex_sub_image_2d (dst->texture.target, 0,
x_dst, dst->height - y_dst - height,
width, height,
- image_format, gl_format->type,
+ format->format, format->type,
pixels);
-
+
if (drawable) {
glitz_point_t tl, br;
- gl->tex_env_f (GLITZ_GL_TEXTURE_ENV,
- GLITZ_GL_TEXTURE_ENV_MODE,
+ gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
GLITZ_GL_REPLACE);
dst->gl->color_4us (0x0, 0x0, 0x0, 0xffff);
@@ -559,6 +794,9 @@ glitz_put_pixels (glitz_surface_t *dst,
}
glitz_texture_unbind (dst->gl, &dst->texture);
+
+ if (transform == 0)
+ glitz_pixel_buffer_unbind (buffer);
glitz_surface_pop_current (dst);
@@ -572,14 +810,13 @@ glitz_get_pixels (glitz_surface_t *src,
int y_src,
int width,
int height,
- glitz_pixel_format_t *format,
- char *pixels)
+ glitz_pixel_buffer_t *buffer)
{
glitz_gl_proc_address_list_t *gl;
glitz_bool_t drawable;
glitz_texture_t *texture = NULL;
- char *p, *data = NULL;
- glitz_gl_pixel_format_t *gl_format = NULL;
+ char *pixels, *data = NULL;
+ glitz_gl_pixel_format_t *format = NULL;
unsigned long transform = 0;
int src_x = 0, src_y = 0, src_w = width, src_h = height;
int xoffset, bytes_per_line;
@@ -609,14 +846,14 @@ glitz_get_pixels (glitz_surface_t *src,
transform |= GLITZ_TRANSFORM_COPY_REGION_MASK;
}
- if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
+ if (buffer->format.scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK;
/* find direct format */
- gl_format = _glitz_find_gl_pixel_format (format);
- if (gl_format == NULL) {
+ format = _glitz_find_gl_pixel_format (&buffer->format);
+ if (format == NULL) {
transform |= GLITZ_TRANSFORM_PIXELS_MASK;
- gl_format = _glitz_best_gl_pixel_format (src->format);
+ format = _glitz_best_gl_pixel_format (src->format);
}
if (transform) {
@@ -629,20 +866,21 @@ glitz_get_pixels (glitz_surface_t *src,
src_y = y_src;
}
- stride = (((src_w * gl_format->pixel.masks.bpp) / 8) + 3) & -4;
+ stride = (((src_w * format->pixel.masks.bpp) / 8) + 3) & -4;
data = malloc (stride * src_h);
if (!data) {
glitz_surface_status_add (src, GLITZ_STATUS_NO_MEMORY_MASK);
return;
}
- p = data;
+ pixels = data;
xoffset = 0;
bytes_per_line = stride;
} else {
- xoffset = format->xoffset;
- bytes_per_line = format->bytes_per_line;
- p = pixels;
+ xoffset = buffer->format.xoffset;
+ bytes_per_line = buffer->format.bytes_per_line;
+ pixels = glitz_pixel_buffer_bind (buffer, GLITZ_GL_PIXEL_PACK_BUFFER);
+ pixels += buffer->format.skip_lines * bytes_per_line;
}
gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, 0);
@@ -664,38 +902,45 @@ glitz_get_pixels (glitz_surface_t *src,
if (drawable) {
gl->read_pixels (x_src, src->height - y_src - height,
width, height,
- gl_format->format, gl_format->type,
- p);
+ format->format, format->type,
+ pixels);
} else {
glitz_texture_bind (gl, texture);
gl->get_tex_image (texture->target, 0,
- gl_format->format, gl_format->type,
- p);
+ format->format, format->type,
+ pixels);
glitz_texture_unbind (gl, texture);
}
- glitz_surface_pop_current (src);
-
if (transform) {
glitz_image_t src_image, dst_image;
- src_image.data = data;
- src_image.format = &gl_format->pixel;
+ src_image.data = data + src_y * format->pixel.bytes_per_line;
+ src_image.format = &format->pixel;
src_image.width = src_w;
src_image.height = src_h;
- dst_image.data = pixels;
- dst_image.format = format;
+ dst_image.data =
+ glitz_pixel_buffer_get_data (buffer,
+ GLITZ_PIXEL_BUFFER_ACCESS_WRITE_ONLY);
+ dst_image.data += buffer->format.skip_lines *
+ buffer->format.bytes_per_line;
+ dst_image.format = &buffer->format;
dst_image.width = width;
dst_image.height = height;
_glitz_pixel_transform (transform,
&src_image,
&dst_image,
- src_x, src_y,
- format->xoffset, 0,
+ src_x,
+ buffer->format.xoffset,
width, height);
- }
+
+ glitz_pixel_buffer_put_back_data (buffer);
+ } else
+ glitz_pixel_buffer_unbind (buffer);
+
+ glitz_surface_pop_current (src);
if (data)
free (data);
diff --git a/src/glitz_program.c b/src/glitz_program.c
index 3c0fd16..ef64c8a 100644
--- a/src/glitz_program.c
+++ b/src/glitz_program.c
@@ -1,28 +1,26 @@
/*
- * Copyright © 2004 David Reveman, Peter Nilsson
- *
+ * Copyright © 2004 David Reveman
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the names of
- * David Reveman and Peter Nilsson not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. David Reveman and Peter Nilsson
- * makes no representations about the suitability of this software for
- * any purpose. It is provided "as is" without express or implied warranty.
+ * David Reveman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * David Reveman makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
*
- * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
- * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
- * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Authors: David Reveman <c99drn@cs.umu.se>
- * Peter Nilsson <c99pnn@cs.umu.se>
+ * Author: David Reveman <c99drn@cs.umu.se>
*/
#ifdef HAVE_CONFIG_H
@@ -34,94 +32,69 @@
#include <stdio.h>
#define EXPAND_NONE ""
-#define EXPAND_2D_TEX "2D"
-#define EXPAND_RECT_TEX "RECT"
-#define EXPAND_NO_PD_OP \
- "MOV result.color, color;\n"
-
-#define EXPAND_SRC_TEMP "TEMP src;\n"
-#define EXPAND_SRC_2D_PD_OP \
- "TEX src, fragment.texcoord[0], texture[0], 2D;\n" \
- "MUL result.color, src, color.a;\n"
-#define EXPAND_SRC_RECT_PD_OP \
- "TEX src, fragment.texcoord[0], texture[0], RECT;\n" \
- "MUL result.color, src, color.a;\n"
-
-#define EXPAND_MASK_TEMP "TEMP mask;\n"
-#define EXPAND_MASK_2D_PD_OP \
- "TEX mask, fragment.texcoord[1], texture[1], 2D;\n" \
- "MUL result.color, color, mask.a;\n"
-#define EXPAND_MASK_RECT_PD_OP \
- "TEX mask, fragment.texcoord[1], texture[1], RECT;\n" \
- "MUL result.color, color, mask.a;\n"
+#define EXPAND_2D "2D"
+#define EXPAND_RECT "RECT"
+
+#define EXPAND_NO_IN_OP \
+ "MUL result.color, color, fragment.color.a;"
+
+#define EXPAND_SRC_TEMP "TEMP src;"
+#define EXPAND_SRC_2D_IN_OP \
+ "TEX 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 \
+ "TEX src, fragment.texcoord[1], texture[1], RECT;" \
+ "DP4 color.a, color, fragment.color;" \
+ "MUL result.color, src, color.a;"
+
+#define EXPAND_MASK_TEMP "TEMP mask;"
+#define EXPAND_MASK_2D_IN_OP \
+ "TEX 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 \
+ "TEX mask, fragment.texcoord[0], texture[0], RECT;" \
+ "DP4 mask.a, mask, fragment.color;" \
+ "MUL result.color, color, mask.a;"
typedef struct _glitz_program_expand_t glitz_program_expand_t;
static const struct _glitz_program_expand_t {
- int index;
- char *tex;
- char *temporary;
- char *operation;
-} _program_expand_map[] = {
-
- /* src is operation surface */
-
- /* GLITZ_PROGRAM_2DSRC_2DMASK_OFFSET */
- { 0, EXPAND_2D_TEX, EXPAND_MASK_TEMP, EXPAND_MASK_2D_PD_OP },
-
- /* GLITZ_PROGRAM_RECTSRC_2DMASK_OFFSET */
- { 0, EXPAND_RECT_TEX, EXPAND_MASK_TEMP, EXPAND_MASK_2D_PD_OP },
-
- /* GLITZ_PROGRAM_2DSRC_RECTMASK_OFFSET */
- { 0, EXPAND_2D_TEX, EXPAND_MASK_TEMP, EXPAND_MASK_RECT_PD_OP },
-
- /* GLITZ_PROGRAM_RECTSRC_RECTMASK_OFFSET */
- { 0, EXPAND_RECT_TEX, EXPAND_MASK_TEMP, EXPAND_MASK_RECT_PD_OP },
-
- /* GLITZ_PROGRAM_NOSRC_2DMASK_OFFSET */
- { 0, EXPAND_NONE, EXPAND_MASK_TEMP, EXPAND_MASK_2D_PD_OP },
-
- /* GLITZ_PROGRAM_NOSRC_RECTMASK_OFFSET */
- { 0, EXPAND_NONE, EXPAND_MASK_TEMP, EXPAND_MASK_RECT_PD_OP },
-
- /* GLITZ_PROGRAM_2DSRC_NOMASK_OFFSET */
- { 0, EXPAND_2D_TEX, EXPAND_NONE, EXPAND_NO_PD_OP },
-
- /* GLITZ_PROGRAM_RECTSRC_NOMASK_OFFSET */
- { 0, EXPAND_RECT_TEX, EXPAND_NONE, EXPAND_NO_PD_OP },
-
- /* GLITZ_PROGRAM_NOSRC_NOMASK_OFFSET */
- { 0, EXPAND_NONE, EXPAND_NONE, EXPAND_NO_PD_OP },
-
-
- /* mask is operation surface */
-
- /* GLITZ_PROGRAM_2DSRC_2DMASK_OFFSET */
- { 1, EXPAND_2D_TEX, EXPAND_SRC_TEMP, EXPAND_SRC_2D_PD_OP },
-
- /* GLITZ_PROGRAM_RECTSRC_2DMASK_OFFSET */
- { 1, EXPAND_2D_TEX, EXPAND_SRC_TEMP, EXPAND_SRC_RECT_PD_OP },
-
- /* GLITZ_PROGRAM_2DSRC_RECTMASK_OFFSET */
- { 1, EXPAND_RECT_TEX, EXPAND_SRC_TEMP, EXPAND_SRC_2D_PD_OP },
-
- /* GLITZ_PROGRAM_RECTSRC_RECTMASK_OFFSET */
- { 1, EXPAND_RECT_TEX, EXPAND_SRC_TEMP, EXPAND_SRC_RECT_PD_OP },
-
- /* GLITZ_PROGRAM_NOSRC_2DMASK_OFFSET */
- { 1, EXPAND_2D_TEX, EXPAND_NONE, EXPAND_NO_PD_OP },
-
- /* GLITZ_PROGRAM_NOSRC_RECTMASK_OFFSET */
- { 1, EXPAND_RECT_TEX, EXPAND_NONE, EXPAND_NO_PD_OP },
-
- /* GLITZ_PROGRAM_2DSRC_NOMASK_OFFSET */
- { 1, EXPAND_NONE, EXPAND_SRC_TEMP, EXPAND_SRC_2D_PD_OP },
-
- /* GLITZ_PROGRAM_RECTSRC_NOMASK_OFFSET */
- { 1, EXPAND_NONE, EXPAND_SRC_TEMP, EXPAND_SRC_RECT_PD_OP },
-
- /* GLITZ_PROGRAM_NOSRC_NOMASK_OFFSET */
- { 1, EXPAND_NONE, EXPAND_NONE, EXPAND_NO_PD_OP }
+ char *texture;
+ char *declarations;
+ char *in;
+} _program_expand_map[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST] = {
+ {
+ /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_NONE] */
+ { EXPAND_NONE, EXPAND_NONE, EXPAND_NO_IN_OP },
+
+ /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_2D] */
+ { EXPAND_NONE, EXPAND_MASK_TEMP, EXPAND_MASK_2D_IN_OP },
+
+ /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_RECT] */
+ { EXPAND_NONE, EXPAND_MASK_TEMP, EXPAND_MASK_RECT_IN_OP }
+ }, {
+
+ /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_NONE] */
+ { EXPAND_2D, EXPAND_NONE, EXPAND_NO_IN_OP },
+
+ /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_2D] */
+ { EXPAND_2D, EXPAND_MASK_TEMP, EXPAND_MASK_2D_IN_OP },
+
+ /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_RECT] */
+ { EXPAND_2D, EXPAND_MASK_TEMP, EXPAND_MASK_RECT_IN_OP }
+ }, {
+
+ /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_NONE] */
+ { EXPAND_RECT, EXPAND_NONE, EXPAND_NO_IN_OP },
+
+ /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_2D] */
+ { EXPAND_RECT, EXPAND_MASK_TEMP, EXPAND_MASK_2D_IN_OP },
+
+ /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_RECT] */
+ { EXPAND_RECT, EXPAND_MASK_TEMP, EXPAND_MASK_RECT_IN_OP }
+ }
};
/*
@@ -133,46 +106,20 @@ static const struct _glitz_program_expand_t {
*
* Author: David Reveman <c99drn@cs.umu.se>
*/
-static char *_glitz_vertex_program_convolution =
-"!!ARBvp1.0\n"
-"OPTION ARB_position_invariant;\n"
-"ATTRIB coord = vertex.texcoord[%d];\n"
-"PARAM vertical_offset = program.local[0];\n"
-"PARAM horizontal_offset = program.local[1];\n"
-"MOV result.texcoord[%d], coord;\n"
-"ADD result.texcoord[2], coord, vertical_offset;\n"
-"SUB result.texcoord[3], coord, vertical_offset;\n"
-"ADD result.texcoord[4], coord, horizontal_offset;\n"
-"SUB result.texcoord[5], coord, horizontal_offset;\n"
-"MOV result.texcoord[%d], vertex.texcoord[%d];\n"
-"END";
-
-/*
- * Porter-Duff compositing (SRC in MASK).
- * Texture unit 0 is SRC.
- * Texture unit 1 is MASK.
- *
- * Author: David Reveman <c99drn@cs.umu.se>
- */
-static char *_glitz_fragment_program_simple =
-"!!ARBfp1.0\n"
-"TEMP color;\n"
-
-/* temporary */
-"%s"
-
-/* src texture */
-"TEX color, fragment.texcoord[0], texture[0], %s;\n"
-
-/* pd operation */
-"%s"
-
-"END";
-
-typedef enum {
- GLITZ_CONVOLUTION_3X3_GENERAL = 1,
- GLITZ_CONVOLUTION_3X3_SIMPLE = 2
-} glitz_convolution_type_t;
+static const char *_glitz_vertex_program_convolution[] = {
+ "!!ARBvp1.0",
+ "OPTION ARB_position_invariant;",
+ "ATTRIB coord = vertex.texcoord[%s];",
+ "PARAM vertical_offset = program.local[0];",
+ "PARAM horizontal_offset = program.local[1];",
+ "MOV result.texcoord[%s], coord;",
+ "ADD result.texcoord[2], coord, vertical_offset;",
+ "SUB result.texcoord[3], coord, vertical_offset;",
+ "ADD result.texcoord[4], coord, horizontal_offset;",
+ "SUB result.texcoord[5], coord, horizontal_offset;",
+ "MOV result.texcoord[%s], vertex.texcoord[%s];",
+ "END", NULL
+};
/*
* General 3x3 convolution filter.
@@ -184,286 +131,216 @@ typedef enum {
*
* Author: David Reveman <c99drn@cs.umu.se>
*/
-static char *_glitz_fragment_program_convolution =
-"!!ARBfp1.0\n"
-"ATTRIB east = fragment.texcoord[2];\n"
-"ATTRIB west = fragment.texcoord[3];\n"
-"ATTRIB south = fragment.texcoord[4];\n"
-"ATTRIB north = fragment.texcoord[5];\n"
-"PARAM k0 = program.local[0];\n"
-"PARAM k1 = program.local[1];\n"
-"PARAM k2 = program.local[2];\n"
-"TEMP color, in, coord;\n"
-
-/* temporary */
-"%s"
-
-/* center */
-"TEX in, fragment.texcoord[%d], texture[%d], %s;\n"
-"MUL color, in, k1.y;\n"
-
-/* north west */
-"MOV coord.x, west.x;\n"
-"MOV coord.y, north.y;\n"
-"TEX in, coord, texture[%d], %s;\n"
-"MAD color, in, k0.x, color;\n"
-
-/* north */
-"TEX in, north, texture[%d], %s;\n"
-"MAD color, in, k0.y, color;\n"
-
-/* north east */
-"MOV coord.x, east.x;\n"
-"TEX in, coord, texture[%d], %s;\n"
-"MAD color, in, k0.z, color;\n"
-
-/* east */
-"TEX in, east, texture[%d], %s;\n"
-"MAD color, in, k1.x, color;\n"
-
-/* south east */
-"MOV coord.y, south.y;\n"
-"TEX in, coord, texture[%d], %s;\n"
-"MAD color, in, k2.z, color;\n"
-
-/* south */
-"TEX in, south, texture[%d], %s;\n"
-"MAD color, in, k2.y, color;\n"
-
-/* south west */
-"MOV coord.x, west.x;\n"
-"TEX in, coord, texture[%d], %s;\n"
-"MAD color, in, k2.x, color;\n"
-
-/* west */
-"TEX in, west, texture[%d], %s;\n"
-"MAD color, in, k1.x, color;\n"
-
-/* pd operation */
-"%s"
-
-"END";
+static const char *_glitz_fragment_program_convolution[] = {
+ "!!ARBfp1.0",
+ "ATTRIB east = fragment.texcoord[2];",
+ "ATTRIB west = fragment.texcoord[3];",
+ "ATTRIB south = fragment.texcoord[4];",
+ "ATTRIB north = fragment.texcoord[5];",
+ "PARAM k0 = program.local[0];",
+ "PARAM k1 = program.local[1];",
+ "PARAM k2 = program.local[2];",
+ "TEMP color, in, coord;",
+
+ /* extra declerations */
+ "%s",
+
+ /* center */
+ "TEX in, fragment.texcoord[%s], texture[%s], %s;",
+ "MUL color, in, k1.y;",
+
+ /* north west */
+ "MOV coord.x, west.x;",
+ "MOV coord.y, north.y;",
+ "TEX in, coord, texture[%s], %s;",
+ "MAD color, in, k0.x, color;",
+
+ /* north */
+ "TEX in, north, texture[%s], %s;",
+ "MAD color, in, k0.y, color;",
+
+ /* north east */
+ "MOV coord.x, east.x;",
+ "TEX in, coord, texture[%s], %s;",
+ "MAD color, in, k0.z, color;",
+
+ /* east */
+ "TEX in, east, texture[%s], %s;",
+ "MAD color, in, k1.x, color;",
+
+ /* south east */
+ "MOV coord.y, south.y;",
+ "TEX in, coord, texture[%s], %s;",
+ "MAD color, in, k2.z, color;",
+
+ /* south */
+ "TEX in, south, texture[%s], %s;",
+ "MAD color, in, k2.y, color;",
+
+ /* south west */
+ "MOV coord.x, west.x;",
+ "TEX in, coord, texture[%s], %s;",
+ "MAD color, in, k2.x, color;",
+
+ /* west */
+ "TEX in, west, texture[%s], %s;",
+ "MAD color, in, k1.x, color;",
+
+ /* IN operation */
+ "%s",
+
+ "END", NULL
+};
/*
- * Simple 3x3 convolution filter (corners are zero).
- * Convolution kernel must be normalized.
+ * Linear gradient using 1D texture as color range.
+ * Color range in texture unit 2.
*
- * program.local[0]: Top convolution kernel row
- * program.local[1]: Middle convolution kernel row
- * program.local[2]: Bottom convolution kernel row
+ * program.local[0].x = start offset
+ * program.local[0].y = 1 / length
+ * program.local[0].z = sin (angle)
+ * program.local[0].w = cos (angle)
+ *
+ * transform:
+ * [ a | c | tx ]
+ * [ b | d | ty ]
+ * [ 0 | 0 | 1 ]
+ *
+ * program.local[1].x = a
+ * program.local[1].y = b
+ * program.local[1].z = c
+ * program.local[1].w = d
+ * program.local[2].x = tx
+ * program.local[2].y = ty
+ * program.local[2].z = height
*
* Author: David Reveman <c99drn@cs.umu.se>
*/
-static char *_glitz_fragment_program_convolution_simple =
-"!!ARBfp1.0\n"
-"ATTRIB east = fragment.texcoord[2];\n"
-"ATTRIB west = fragment.texcoord[3];\n"
-"ATTRIB south = fragment.texcoord[4];\n"
-"ATTRIB north = fragment.texcoord[5];\n"
-"PARAM k0 = program.local[0];\n"
-"PARAM k1 = program.local[1];\n"
-"PARAM k2 = program.local[2];\n"
-"TEMP color, in, coord;\n"
-
-/* temporary */
-"%s"
-
-/* center */
-"TEX in, fragment.texcoord[%d], texture[%d], %s;\n"
-"MUL color, in, k1.y;\n"
-
-/* north */
-"TEX in, north, texture[%d], %s;\n"
-"MAD color, in, k0.y, color;\n"
-
-/* east */
-"TEX in, east, texture[%d], %s;\n"
-"MAD color, in, k1.x, color;\n"
-
-/* south */
-"TEX in, south, texture[%d], %s;\n"
-"MAD color, in, k2.y, color;\n"
-
-/* west */
-"TEX in, west, texture[%d], %s;\n"
-"MAD color, in, k1.x, color;\n"
-
-/* pd operation */
-"%s"
-
-"END";
-
-char *_glitz_fragment_program_programmatic[] = {
- /*
- * Solid.
- *
- * fragment.color: color
- *
- * Author: David Reveman <c99drn@cs.umu.se>
- */
- "!!ARBfp1.0\n"
- "ATTRIB color = fragment.color;\n"
-
- /* temporary */
- "%s"
-
- /* pd operation */
- "%s"
-
- "END",
-
- /*
- * Linear gradient using 1D texture as color range.
- * Color range in texture unit 2.
- *
- * program.local[0].x = start offset
- * program.local[0].y = 1 / length
- * program.local[0].z = sin (angle)
- * program.local[0].w = cos (angle)
- *
- * transform:
- * [ a | c | tx ]
- * [ b | d | ty ]
- * [ 0 | 0 | 1 ]
- *
- * program.local[1].x = a
- * program.local[1].y = b
- * program.local[1].z = c
- * program.local[1].w = d
- * program.local[2].x = tx
- * program.local[2].y = ty
- * program.local[2].z = height
- *
- * Author: David Reveman <c99drn@cs.umu.se>
- */
-
- "!!ARBfp1.0\n"
- "PARAM gradient = program.local[0];\n"
- "PARAM transform = program.local[1];\n"
- "PARAM translate = program.local[2];\n"
- "ATTRIB pos = fragment.texcoord[%d];\n"
- "TEMP color, distance, position;\n"
-
- /* temporary */
- "%s"
-
- /* flip Y position */
- "SUB position.y, translate.z, pos.y;\n"
+static const char *_glitz_fragment_program_linear[] = {
+ "!!ARBfp1.0",
+ "PARAM gradient = program.local[0];",
+ "PARAM transform = program.local[1];",
+ "PARAM translate = program.local[2];",
+ "ATTRIB pos = fragment.texcoord[%s];",
+ "TEMP color, distance, position;",
+
+ /* extra declerations */
+ "%s",
+
+ /* flip Y position (this should be done in advance) */
+ "SUB position.y, translate.z, pos.y;",
/* transform X position */
- "MUL position.x, transform.x, pos.x;\n"
- "MAD position.x, transform.z, position.y, position.x;\n"
- "ADD position.x, position.x, translate.x;\n"
+ "MUL position.x, transform.x, pos.x;",
+ "MAD position.x, transform.z, position.y, position.x;",
+ "ADD position.x, position.x, translate.x;",
/* transform Y position */
- "MUL position.y, transform.w, position.y;\n"
- "MAD position.y, transform.y, pos.x, position.y;\n"
- "ADD position.y, position.y, translate.y;\n"
+ "MUL position.y, transform.w, position.y;",
+ "MAD position.y, transform.y, pos.x, position.y;",
+ "ADD position.y, position.y, translate.y;",
/* calculate gradient offset */
- "MUL position.x, gradient.z, position.x;\n"
- "MAD position.x, gradient.w, position.y, position.x;\n"
+ "MUL position.x, gradient.z, position.x;",
+ "MAD position.x, gradient.w, position.y, position.x;",
- "SUB distance.x, position.x, gradient.x;\n"
- "MUL distance.x, distance.x, gradient.y;\n"
+ "SUB distance.x, position.x, gradient.x;",
+ "MUL distance.x, distance.x, gradient.y;",
- "TEX color, distance, texture[2], 1D;\n"
-
- "MUL color, color, fragment.color.a;\n"
+ "TEX color, distance, texture[2], 1D;",
- /* pd operation */
- "%s"
+ /* IN operation */
+ "%s",
- "END",
-
- /*
- * Radial gradient using 1D texture as color range.
- * Color range in texture unit 2.
- *
- * param.local[0].x = center point X coordinate
- * param.local[0].y = center point Y coordinate
- * param.local[0].z = 1 / (radius1 - radius0)
- * param.local[0].w = radius0
- *
- * transform:
- * [ a | c | tx ]
- * [ b | d | ty ]
- * [ 0 | 0 | 1 ]
- *
- * program.local[1].x = a
- * program.local[1].y = b
- * program.local[1].z = c
- * program.local[1].w = d
- * program.local[2].x = tx
- * program.local[2].y = ty
- * program.local[2].z = height
- *
- * Author: David Reveman <c99drn@cs.umu.se>
- */
-
- "!!ARBfp1.0\n"
- "PARAM gradient = program.local[0];\n"
- "PARAM transform = program.local[1];\n"
- "PARAM translate = program.local[2];\n"
- "ATTRIB pos = fragment.texcoord[%d];\n"
- "TEMP color, distance, position;\n"
-
- /* temporary */
- "%s"
-
- /* flip Y position */
- "SUB position.y, translate.z, pos.y;\n"
+ "END", NULL
+};
+/*
+ * Radial gradient using 1D texture as color range.
+ * Color range in texture unit 2.
+ *
+ * param.local[0].x = center point X coordinate
+ * param.local[0].y = center point Y coordinate
+ * param.local[0].z = 1 / (radius1 - radius0)
+ * param.local[0].w = radius0
+ *
+ * transform:
+ * [ a | c | tx ]
+ * [ b | d | ty ]
+ * [ 0 | 0 | 1 ]
+ *
+ * program.local[1].x = a
+ * program.local[1].y = b
+ * program.local[1].z = c
+ * program.local[1].w = d
+ * program.local[2].x = tx
+ * program.local[2].y = ty
+ * program.local[2].z = height
+ *
+ * Author: David Reveman <c99drn@cs.umu.se>
+ */
+static const char *_glitz_fragment_program_radial[] = {
+ "!!ARBfp1.0",
+ "PARAM gradient = program.local[0];",
+ "PARAM transform = program.local[1];",
+ "PARAM translate = program.local[2];",
+ "ATTRIB pos = fragment.texcoord[%s];",
+ "TEMP color, distance, position;",
+
+ /* extra declerations */
+ "%s",
+
+ /* flip Y position (this should be done in advance) */
+ "SUB position.y, translate.z, pos.y;",
+
/* transform X position */
- "MUL position.x, transform.x, pos.x;\n"
- "MAD position.x, transform.z, position.y, position.x;\n"
- "ADD position.x, position.x, translate.x;\n"
+ "MUL position.x, transform.x, pos.x;",
+ "MAD position.x, transform.z, position.y, position.x;",
+ "ADD position.x, position.x, translate.x;",
/* transform Y position */
- "MUL position.y, transform.w, position.y;\n"
- "MAD position.y, transform.y, pos.x, position.y;\n"
- "ADD position.y, position.y, translate.y;\n"
-
+ "MUL position.y, transform.w, position.y;",
+ "MAD position.y, transform.y, pos.x, position.y;",
+ "ADD position.y, position.y, translate.y;",
+
/* calculate gradient offset */
- "SUB distance, position, gradient;\n"
+ "SUB distance, position, gradient;",
- "DP3 distance.x, distance, distance;\n"
- "RSQ distance.w, distance.x;\n"
+ "DP3 distance.x, distance, distance;",
+ "RSQ distance.w, distance.x;",
- "RCP distance.x, distance.w;\n"
- "MUL distance.x, distance.x, distance.x;\n"
- "MUL distance.x, distance.x, distance.w;\n"
-
- "SUB distance.x, distance.x, gradient.w;\n"
- "MUL distance.x, distance.x, gradient.z;\n"
+ "RCP distance.x, distance.w;",
+ "MUL distance.x, distance.x, distance.x;",
+ "MUL distance.x, distance.x, distance.w;",
- "TEX color, distance, texture[2], 1D;\n"
-
- "MUL color, color, fragment.color;\n"
-
- /* pd operation */
- "%s"
+ "SUB distance.x, distance.x, gradient.w;",
+ "MUL distance.x, distance.x, gradient.z;",
- "END"
+ "TEX color, distance, texture[2], 1D;",
+
+ /* IN operation */
+ "%s",
+
+ "END", NULL
};
static glitz_gl_uint_t
-glitz_program_compile_vertex_arb (glitz_gl_proc_address_list_t *gl,
- char *program_string)
+_glitz_compile_arb_vertex_program (glitz_gl_proc_address_list_t *gl,
+ char *program_string)
{
glitz_gl_int_t error;
glitz_gl_uint_t program;
- gl->gen_programs_arb (1, &program);
- gl->bind_program_arb (GLITZ_GL_VERTEX_PROGRAM_ARB, program);
- gl->program_string_arb (GLITZ_GL_VERTEX_PROGRAM_ARB,
- GLITZ_GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen (program_string),
- program_string);
+ gl->gen_programs (1, &program);
+ gl->bind_program (GLITZ_GL_VERTEX_PROGRAM, program);
+ gl->program_string (GLITZ_GL_VERTEX_PROGRAM,
+ GLITZ_GL_PROGRAM_FORMAT_ASCII,
+ strlen (program_string),
+ program_string);
- gl->get_integer_v (GLITZ_GL_PROGRAM_ERROR_POSITION_ARB, &error);
+ gl->get_integer_v (GLITZ_GL_PROGRAM_ERROR_POSITION, &error);
if (error != -1) {
- gl->delete_programs_arb (1, &program);
+ gl->delete_programs (1, &program);
program = 0;
}
@@ -471,351 +348,208 @@ glitz_program_compile_vertex_arb (glitz_gl_proc_address_list_t *gl,
}
static glitz_gl_uint_t
-glitz_program_compile_fragment_arb (glitz_gl_proc_address_list_t *gl,
- char *program_string)
+_glitz_compile_arb_fragment_program (glitz_gl_proc_address_list_t *gl,
+ char *program_string)
{
glitz_gl_int_t error;
glitz_gl_uint_t program;
-
- gl->gen_programs_arb (1, &program);
- gl->bind_program_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, program);
- gl->program_string_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB,
- GLITZ_GL_PROGRAM_FORMAT_ASCII_ARB,
- strlen (program_string),
- program_string);
+
+ gl->gen_programs (1, &program);
+ gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, program);
+ gl->program_string (GLITZ_GL_FRAGMENT_PROGRAM,
+ GLITZ_GL_PROGRAM_FORMAT_ASCII,
+ strlen (program_string),
+ program_string);
- gl->get_integer_v (GLITZ_GL_PROGRAM_ERROR_POSITION_ARB, &error);
+ gl->get_integer_v (GLITZ_GL_PROGRAM_ERROR_POSITION, &error);
if (error != -1) {
- gl->delete_programs_arb (1, &program);
+ gl->delete_programs (1, &program);
program = 0;
}
return program;
}
-static int
-_glitz_program_offset (glitz_texture_t *src_texture,
- glitz_texture_t *mask_texture)
-{
- int offset;
-
- if (src_texture) {
- if (src_texture->target == GLITZ_GL_TEXTURE_2D) {
- offset = GLITZ_PROGRAM_2DSRC_NOMASK_OFFSET;
-
- if (mask_texture)
- offset = (mask_texture->target == GLITZ_GL_TEXTURE_2D)?
- GLITZ_PROGRAM_2DSRC_2DMASK_OFFSET:
- GLITZ_PROGRAM_2DSRC_RECTMASK_OFFSET;
- } else {
- offset = GLITZ_PROGRAM_RECTSRC_NOMASK_OFFSET;
-
- if (mask_texture)
- offset = (mask_texture->target == GLITZ_GL_TEXTURE_2D)?
- GLITZ_PROGRAM_RECTSRC_2DMASK_OFFSET:
- GLITZ_PROGRAM_RECTSRC_RECTMASK_OFFSET;
- }
- } else {
- offset = GLITZ_PROGRAM_NOSRC_NOMASK_OFFSET;
-
- if (mask_texture)
- offset = (mask_texture->target == GLITZ_GL_TEXTURE_2D)?
- GLITZ_PROGRAM_NOSRC_2DMASK_OFFSET: GLITZ_PROGRAM_NOSRC_RECTMASK_OFFSET;
- }
-
- return offset;
-}
-
-static glitz_gl_uint_t
-glitz_program_compile_simple (glitz_gl_proc_address_list_t *gl,
- int offset)
+static void
+_string_array_to_char_array (char *dst, const char *src[])
{
- char program_buffer[256];
- const glitz_program_expand_t *expand = &_program_expand_map[offset];
+ int i, n;
- sprintf (program_buffer,
- _glitz_fragment_program_simple,
- expand->temporary,
- expand->tex,
- expand->operation);
-
- return glitz_program_compile_fragment_arb (gl, program_buffer);
+ for (i = 0; src[i]; i++) {
+ n = strlen (src[i]);
+ memcpy (dst, src[i], n);
+ dst += n;
+ }
}
static glitz_gl_uint_t
-glitz_program_compile_vertex_convolution (glitz_gl_proc_address_list_t *gl,
- int offset)
+_glitz_create_vertex_program (glitz_render_op_t *op,
+ const glitz_program_expand_t *expand)
{
- char program_buffer[512];
- int conv_index = (offset)? 1: 0;
- int other_index = (offset)? 0: 1;
+ char program[512], program_buffer[512];
- sprintf (program_buffer,
- _glitz_vertex_program_convolution,
- conv_index, conv_index,
- other_index, other_index);
-
- return glitz_program_compile_vertex_arb (gl, program_buffer);
-}
-
-static glitz_gl_uint_t
-glitz_program_compile_convolution (glitz_gl_proc_address_list_t *gl,
- int offset,
- int solid_offset,
- glitz_convolution_type_t type)
-{
- static char *solid_op_table[] = {
- "MUL result.color, color, fragment.color.a;\n",
- "MUL result.color, fragment.color, color.a;\n",
- };
- char program_buffer[1280];
- const glitz_program_expand_t *expand = &_program_expand_map[offset];
- char *temporary, *operation;
-
- if (solid_offset) {
- temporary = "";
- operation = solid_op_table[solid_offset - 1];
- } else {
- temporary = expand->temporary;
- operation = expand->operation;
- }
-
- switch (type) {
- case GLITZ_CONVOLUTION_3X3_GENERAL:
- sprintf (program_buffer,
- _glitz_fragment_program_convolution,
- temporary,
- expand->index, expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- operation);
+ switch (op->type) {
+ case GLITZ_RENDER_TYPE_ARGBF:
+ case GLITZ_RENDER_TYPE_ARGBF_SOLID:
+ _string_array_to_char_array (program, _glitz_vertex_program_convolution);
+ sprintf (program_buffer, program,
+ "0", "0", "1", "1");
break;
- case GLITZ_CONVOLUTION_3X3_SIMPLE:
- sprintf (program_buffer,
- _glitz_fragment_program_convolution_simple,
- temporary,
- expand->index, expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- expand->index, expand->tex,
- operation);
+ case GLITZ_RENDER_TYPE_ARGBF_ARGB:
+ case GLITZ_RENDER_TYPE_ARGBF_ARGBC:
+ _string_array_to_char_array (program, _glitz_vertex_program_convolution);
+ sprintf (program_buffer, program,
+ "1", "1", "0", "0");
break;
+ default:
+ return 0;
}
-
- return glitz_program_compile_fragment_arb (gl, program_buffer);
+
+ return _glitz_compile_arb_vertex_program (op->gl, program_buffer);
}
static glitz_gl_uint_t
-glitz_program_compile_programmatic (glitz_programmatic_surface_type_t type,
- glitz_gl_proc_address_list_t *gl,
- int offset)
+_glitz_create_fragment_program (glitz_render_op_t *op,
+ const glitz_program_expand_t *expand)
{
- char program_buffer[1024];
- const glitz_program_expand_t *expand = &_program_expand_map[offset];
-
- switch (type) {
- case GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE:
- sprintf (program_buffer,
- _glitz_fragment_program_programmatic[type],
- expand->temporary,
- expand->operation);
+ char program[2048], program_buffer[2048];
+
+ switch (op->type) {
+ case GLITZ_RENDER_TYPE_ARGBF:
+ case GLITZ_RENDER_TYPE_ARGBF_SOLID:
+ _string_array_to_char_array (program, _glitz_fragment_program_convolution);
+ sprintf (program_buffer, program,
+ expand->declarations,
+ "0", "0", expand->texture,
+ "0", expand->texture,
+ "0", expand->texture,
+ "0", expand->texture,
+ "0", expand->texture,
+ "0", expand->texture,
+ "0", expand->texture,
+ "0", expand->texture,
+ "0", expand->texture,
+ expand->in);
+ break;
+ case GLITZ_RENDER_TYPE_ARGBF_ARGB:
+ case GLITZ_RENDER_TYPE_ARGBF_ARGBC:
+ _string_array_to_char_array (program, _glitz_fragment_program_convolution);
+ sprintf (program_buffer, program,
+ expand->declarations,
+ "1", "1", expand->texture,
+ "1", expand->texture,
+ "1", expand->texture,
+ "1", expand->texture,
+ "1", expand->texture,
+ "1", expand->texture,
+ "1", expand->texture,
+ "1", expand->texture,
+ "1", expand->texture,
+ expand->in);
+ break;
+ case GLITZ_RENDER_TYPE_LGRAD:
+ case GLITZ_RENDER_TYPE_LGRAD_SOLID:
+ _string_array_to_char_array (program, _glitz_fragment_program_linear);
+ sprintf (program_buffer, program,
+ "0",
+ expand->declarations,
+ expand->in);
+ break;
+ case GLITZ_RENDER_TYPE_LGRAD_ARGB:
+ case GLITZ_RENDER_TYPE_LGRAD_ARGBC:
+ _string_array_to_char_array (program, _glitz_fragment_program_linear);
+ sprintf (program_buffer, program,
+ "1",
+ expand->declarations,
+ expand->in);
+ break;
+ case GLITZ_RENDER_TYPE_RGRAD:
+ case GLITZ_RENDER_TYPE_RGRAD_SOLID:
+ _string_array_to_char_array (program, _glitz_fragment_program_radial);
+ sprintf (program_buffer, program,
+ "0",
+ expand->declarations,
+ expand->in);
break;
- case GLITZ_PROGRAMMATIC_SURFACE_LINEAR_TYPE:
- case GLITZ_PROGRAMMATIC_SURFACE_RADIAL_TYPE:
- sprintf (program_buffer,
- _glitz_fragment_program_programmatic[type],
- expand->index,
- expand->temporary,
- expand->operation);
+ case GLITZ_RENDER_TYPE_RGRAD_ARGB:
+ case GLITZ_RENDER_TYPE_RGRAD_ARGBC:
+ _string_array_to_char_array (program, _glitz_fragment_program_radial);
+ sprintf (program_buffer, program,
+ "1",
+ expand->declarations,
+ expand->in);
break;
+ default:
+ return 0;
}
-
- return glitz_program_compile_fragment_arb (gl, program_buffer);
+
+ return _glitz_compile_arb_fragment_program (op->gl, program_buffer);
}
+static int
+_texture_index (glitz_texture_t *texture)
+{
+ if (texture) {
+ if (texture->target == GLITZ_GL_TEXTURE_2D)
+ return GLITZ_TEXTURE_2D;
+ else
+ return GLITZ_TEXTURE_RECT;
+ } else
+ return GLITZ_TEXTURE_NONE;
+}
+
void
-glitz_program_enable_argb_argb (glitz_gl_proc_address_list_t *gl,
- glitz_programs_t *programs,
- glitz_texture_t *src_texture,
- glitz_texture_t *mask_texture)
+glitz_program_map_init (glitz_program_map_t *map)
{
- int offset;
-
- offset = _glitz_program_offset (src_texture, mask_texture);
-
- if (!programs->fragment_simple[offset])
- programs->fragment_simple[offset] =
- glitz_program_compile_simple (gl, offset);
-
- if (programs->fragment_simple[offset]) {
- gl->enable (GLITZ_GL_FRAGMENT_PROGRAM_ARB);
- gl->bind_program_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB,
- programs->fragment_simple[offset]);
- }
+ memset (map, 0, sizeof (glitz_program_map_t));
}
void
-glitz_program_enable_convolution (glitz_gl_proc_address_list_t *gl,
- glitz_programs_t *programs,
- glitz_surface_t *src,
- glitz_surface_t *mask,
- glitz_texture_t *src_texture,
- glitz_texture_t *mask_texture,
- int offset,
- int solid_offset,
- unsigned short opacity)
+glitz_program_map_fini (glitz_gl_proc_address_list_t *gl,
+ glitz_program_map_t *map)
{
- glitz_texture_t *texture;
- glitz_surface_t *surface;
- int fragment_offset, vertex_offset = (offset)? 1: 0;
- glitz_convolution_type_t type;
-
- if (offset) {
- texture = mask_texture;
- surface = mask;
- } else {
- texture = src_texture;
- surface = src;
- }
-
- offset += _glitz_program_offset (src_texture, mask_texture);
-
- if (surface->convolution->m[0][0] == 0.0 &&
- surface->convolution->m[0][2] == 0.0 &&
- surface->convolution->m[2][2] == 0.0 &&
- surface->convolution->m[2][0] == 0.0)
- type = GLITZ_CONVOLUTION_3X3_SIMPLE;
- else
- type = GLITZ_CONVOLUTION_3X3_GENERAL;
-
- fragment_offset = GLITZ_FRAGMENT_PROGRAM_TYPES * solid_offset * type +
- offset;
-
- if (!programs->vertex_convolution[vertex_offset])
- programs->vertex_convolution[vertex_offset] =
- glitz_program_compile_vertex_convolution (gl, vertex_offset);
-
- if (!programs->fragment_convolution[fragment_offset])
- programs->fragment_convolution[fragment_offset] =
- glitz_program_compile_convolution (gl, offset, solid_offset, type);
-
- if (programs->fragment_convolution[fragment_offset] &&
- programs->vertex_convolution[vertex_offset]) {
-
- gl->enable (GLITZ_GL_VERTEX_PROGRAM_ARB);
- gl->bind_program_arb (GLITZ_GL_VERTEX_PROGRAM_ARB,
- programs->vertex_convolution[vertex_offset]);
- gl->program_local_param_4d_arb (GLITZ_GL_VERTEX_PROGRAM_ARB, 0,
- texture->texcoord_width /
- (double) texture->width,
- 0.000, 0.0, 0.0);
- gl->program_local_param_4d_arb (GLITZ_GL_VERTEX_PROGRAM_ARB, 1,
- 0.000,
- texture->texcoord_height /
- (double) texture->height,
- 0.0, 0.0);
+ int i, x, y;
- gl->enable (GLITZ_GL_FRAGMENT_PROGRAM_ARB);
- gl->bind_program_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB,
- programs->fragment_convolution[fragment_offset]);
- gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 0,
- surface->convolution->m[0][0],
- surface->convolution->m[0][1],
- surface->convolution->m[0][2],
- 0.0);
- gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 1,
- surface->convolution->m[1][0],
- surface->convolution->m[1][1],
- surface->convolution->m[1][2],
- 0.0);
- gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 2,
- surface->convolution->m[2][0],
- surface->convolution->m[2][1],
- surface->convolution->m[2][2],
- 0.0);
-
- if (solid_offset && mask) {
- glitz_color_t *color;
-
- if (solid_offset == 1)
- color = &((glitz_programmatic_surface_t *) mask)->u.solid.color;
- else
- color = &((glitz_programmatic_surface_t *) src)->u.solid.color;
-
- gl->color_4us (color->red, color->green, color->blue, color->alpha);
- } else
- gl->color_4us (opacity, opacity, opacity, opacity);
+ for (i = 0; i < GLITZ_RENDER_TYPES; i++) {
+ for (x = 0; x < GLITZ_TEXTURE_LAST; x++)
+ for (y = 0; y < GLITZ_TEXTURE_LAST; y++) {
+ if (map->info[i].vertex[x][y])
+ gl->delete_programs (1, &map->info[i].vertex[x][y]);
+ if (map->info[i].fragment[x][y])
+ gl->delete_programs (1, &map->info[i].vertex[x][y]);
+ }
}
}
-void
-glitz_program_enable_programmatic (glitz_surface_t *dst,
- glitz_programmatic_surface_t *surface,
- glitz_texture_t *src_texture,
- glitz_texture_t *mask_texture,
- int offset,
- unsigned short opacity)
+glitz_gl_uint_t
+glitz_get_vertex_program (glitz_render_op_t *op)
{
- int type_offset, add_offset;
- glitz_programs_t *programs = dst->programs;
-
- if (offset)
- add_offset = _glitz_program_offset (src_texture, NULL);
- else
- add_offset = _glitz_program_offset (NULL, mask_texture);
-
- offset += add_offset;
-
- type_offset = offset + GLITZ_FRAGMENT_PROGRAM_TYPES * surface->type;
-
- if (dst->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) {
- if (!programs->fragment_programmatic[type_offset])
- programs->fragment_programmatic[type_offset] =
- glitz_program_compile_programmatic (surface->type, dst->gl, offset);
-
- if (programs->fragment_programmatic[type_offset]) {
- dst->gl->enable (GLITZ_GL_FRAGMENT_PROGRAM_ARB);
- dst->gl->bind_program_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB,
- programs->fragment_programmatic[type_offset]);
+ glitz_gl_uint_t *program;
+ int index1 = _texture_index (op->src_texture);
+ int index2 = _texture_index (op->mask_texture);
- glitz_programmatic_surface_bind (dst->gl, surface, dst->feature_mask,
- 0xffff);
+ program = &op->dst->program_map->info[op->type].vertex[index1][index2];
+
+ if (*program == 0)
+ *program =
+ _glitz_create_vertex_program (op, &_program_expand_map[index1][index2]);
- dst->gl->color_4us (opacity, opacity, opacity, opacity);
- }
- }
+ return *program;
}
-void
-glitz_programs_fini (glitz_gl_proc_address_list_t *gl,
- glitz_programs_t *programs)
+glitz_gl_uint_t
+glitz_get_fragment_program (glitz_render_op_t *op)
{
- int i;
+ glitz_gl_uint_t *program;
+ int index1 = _texture_index (op->src_texture);
+ int index2 = _texture_index (op->mask_texture);
+
+ program = &op->dst->program_map->info[op->type].fragment[index1][index2];
- for (i = 0; i < GLITZ_VERTEX_PROGRAM_TYPES; i++) {
- if (programs->vertex_convolution[i])
- gl->delete_programs_arb (1, &programs->vertex_convolution[i]);
- }
-
- for (i = 0; i < GLITZ_FRAGMENT_PROGRAM_TYPES; i++) {
- if (programs->fragment_simple[i])
- gl->delete_programs_arb (1, &programs->fragment_simple[i]);
- }
-
- for (i = 0; i < (GLITZ_FRAGMENT_PROGRAM_TYPES * 3); i++) {
- if (programs->fragment_convolution[i])
- gl->delete_programs_arb (1, &programs->fragment_convolution[i]);
- }
+ if (*program == 0)
+ *program =
+ _glitz_create_fragment_program (op,
+ &_program_expand_map[index1][index2]);
- for (i = 0; i < GLITZ_FRAGMENT_PROGRAMMATIC_PROGRAM_TYPES; i++) {
- if (programs->fragment_programmatic[i])
- gl->delete_programs_arb (1, &programs->fragment_programmatic[i]);
- }
+ return *program;
}
diff --git a/src/glitz_programmatic.c b/src/glitz_programmatic.c
index cafdd26..7a4ead5 100644
--- a/src/glitz_programmatic.c
+++ b/src/glitz_programmatic.c
@@ -31,8 +31,6 @@
#include "glitzint.h"
-#include <math.h>
-
static glitz_surface_t *
_glitz_programmatic_surface_create_similar (void *abstract_templ,
glitz_format_t *format,
@@ -49,10 +47,10 @@ _glitz_programmatic_surface_destroy (void *abstract_surface)
(glitz_programmatic_surface_t *) abstract_surface;
switch (surface->type) {
- case GLITZ_PROGRAMMATIC_SURFACE_LINEAR_TYPE:
+ case GLITZ_PROGRAMMATIC_SURFACE_TYPE_LINEAR:
glitz_color_range_destroy (surface->u.linear.color_range);
break;
- case GLITZ_PROGRAMMATIC_SURFACE_RADIAL_TYPE:
+ case GLITZ_PROGRAMMATIC_SURFACE_TYPE_RADIAL:
glitz_color_range_destroy (surface->u.radial.color_range);
default:
break;
@@ -137,28 +135,16 @@ _glitz_programmatic_surface_create (void)
surface->base.texture.target = GLITZ_GL_TEXTURE_2D;
surface->base.texture.format = GLITZ_GL_RGBA;
surface->base.texture.filter = surface->base.filter;
- surface->base.texture.texcoord_width =
- surface->base.texture.texcoord_height = 1.0;
+ surface->base.texture.texcoord_width = surface->base.width =
+ surface->base.texture.width = MAXSHORT;
+ surface->base.texture.texcoord_height = surface->base.height =
+ surface->base.texture.height = MAXSHORT;
surface->base.texture.repeatable = surface->base.texture.repeat = 1;
surface->matrix = identity;
return surface;
}
-void
-glitz_programmatic_surface_setup (glitz_surface_t *abstract_surface,
- int width,
- int height)
-{
- glitz_programmatic_surface_t *surface =
- (glitz_programmatic_surface_t *) abstract_surface;
-
- surface->base.texture.texcoord_width = surface->base.width =
- surface->base.texture.width = width;
- surface->base.texture.texcoord_height = surface->base.height =
- surface->base.texture.height = height;
-}
-
glitz_surface_t *
glitz_programmatic_surface_create_solid (glitz_color_t *color)
{
@@ -168,7 +154,7 @@ glitz_programmatic_surface_create_solid (glitz_color_t *color)
if (!surface)
return NULL;
- surface->type = GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE;
+ surface->type = GLITZ_PROGRAMMATIC_SURFACE_TYPE_SOLID;
surface->u.solid.color = *color;
return &surface->base;
@@ -185,7 +171,7 @@ glitz_programmatic_surface_create_linear (glitz_point_fixed_t *start,
if (!surface)
return NULL;
- surface->type = GLITZ_PROGRAMMATIC_SURFACE_LINEAR_TYPE;
+ surface->type = GLITZ_PROGRAMMATIC_SURFACE_TYPE_LINEAR;
surface->u.linear.start = *start;
surface->u.linear.stop = *stop;
surface->u.linear.color_range = color_range;
@@ -206,7 +192,7 @@ glitz_programmatic_surface_create_radial (glitz_point_fixed_t *start,
if (!surface)
return NULL;
- surface->type = GLITZ_PROGRAMMATIC_SURFACE_RADIAL_TYPE;
+ surface->type = GLITZ_PROGRAMMATIC_SURFACE_TYPE_RADIAL;
surface->u.radial.center = *start;
surface->u.radial.radius0 = radius0;
surface->u.radial.radius1 = radius1;
@@ -231,84 +217,3 @@ glitz_programmatic_surface_set_transform (glitz_surface_t *abstract_surface,
surface->matrix.m[1][1] = FIXED_TO_DOUBLE (transform->matrix[1][1]);
surface->matrix.m[2][1] = FIXED_TO_DOUBLE (transform->matrix[1][2]);
}
-
-void
-glitz_programmatic_surface_bind (glitz_gl_proc_address_list_t *gl,
- glitz_programmatic_surface_t *surface,
- unsigned long feature_mask,
- unsigned short opacity)
-{
- switch (surface->type) {
- case GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE:
- if (opacity != 0xffff) {
- gl->color_4us (SHORT_MODULATE (surface->u.solid.color.red, opacity),
- SHORT_MODULATE (surface->u.solid.color.green, opacity),
- SHORT_MODULATE (surface->u.solid.color.blue, opacity),
- SHORT_MODULATE (surface->u.solid.color.alpha, opacity));
- } else
- gl->color_4us (surface->u.solid.color.red,
- surface->u.solid.color.green,
- surface->u.solid.color.blue,
- surface->u.solid.color.alpha);
- break;
- case GLITZ_PROGRAMMATIC_SURFACE_LINEAR_TYPE: {
- glitz_point_t p1, p2;
- double length, angle, start;
-
- p1.x = FIXED_TO_DOUBLE (surface->u.linear.start.x);
- p1.y = FIXED_TO_DOUBLE (surface->u.linear.start.y);
- p2.x = FIXED_TO_DOUBLE (surface->u.linear.stop.x);
- p2.y = FIXED_TO_DOUBLE (surface->u.linear.stop.y);
-
- length = sqrt ((p2.x - p1.x) * (p2.x - p1.x) +
- (p2.y - p1.y) * (p2.y - p1.y));
-
- angle = -atan2 (p2.y - p1.y, p2.x - p1.x);
-
- start = cos (angle) * p1.x;
- start += -sin (angle) * p1.y;
-
- gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 0,
- start,
- (length)? 1.0 / length: INT_MAX,
- cos (angle),
- -sin (angle));
- gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 1,
- surface->matrix.m[0][0],
- surface->matrix.m[0][1],
- surface->matrix.m[1][0],
- surface->matrix.m[1][1]);
- gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 2,
- surface->matrix.m[2][0],
- surface->matrix.m[2][1],
- surface->base.height, 0.0);
-
- gl->active_texture_arb (GLITZ_GL_TEXTURE2_ARB);
- glitz_color_range_bind (gl, surface->u.linear.color_range, feature_mask);
- gl->active_texture_arb (GLITZ_GL_TEXTURE0_ARB);
- } break;
- case GLITZ_PROGRAMMATIC_SURFACE_RADIAL_TYPE:
- gl->program_local_param_4d_arb
- (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 0,
- FIXED_TO_DOUBLE (surface->u.radial.center.x),
- FIXED_TO_DOUBLE (surface->u.radial.center.y),
- 1.0 / (FIXED_TO_DOUBLE (surface->u.radial.radius1) -
- FIXED_TO_DOUBLE (surface->u.radial.radius0)),
- FIXED_TO_DOUBLE (surface->u.radial.radius0));
- gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 1,
- surface->matrix.m[0][0],
- surface->matrix.m[0][1],
- surface->matrix.m[1][0],
- surface->matrix.m[1][1]);
- gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 2,
- surface->matrix.m[2][0],
- surface->matrix.m[2][1],
- surface->base.height, 0.0);
-
- gl->active_texture_arb (GLITZ_GL_TEXTURE2_ARB);
- glitz_color_range_bind (gl, surface->u.radial.color_range, feature_mask);
- gl->active_texture_arb (GLITZ_GL_TEXTURE0_ARB);
- default:
- break;
- }
-}
diff --git a/src/glitz_render.c b/src/glitz_render.c
index 479e66d..f459b7f 100644
--- a/src/glitz_render.c
+++ b/src/glitz_render.c
@@ -1,25 +1,24 @@
/*
- * Copyright © 2004 David Reveman, Peter Nilsson
- *
+ * Copyright © 2004 David Reveman
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the names of
- * David Reveman and Peter Nilsson not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. David Reveman and Peter Nilsson
- * makes no representations about the suitability of this software for
- * any purpose. It is provided "as is" without express or implied warranty.
+ * David Reveman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * David Reveman makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
*
- * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
- * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
- * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <c99drn@cs.umu.se>
*/
@@ -30,168 +29,668 @@
#include "glitzint.h"
-glitz_render_type_t
-glitz_render_type (glitz_surface_t *src,
- glitz_surface_t *mask,
- glitz_surface_t *dst)
+#include <math.h>
+
+static void
+_glitz_render_argb_solid (glitz_render_op_t *op)
{
- int src_conv, mask_conv;
+ if (op->alpha_mask.alpha != 0xffff) {
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_MODULATE);
+ op->gl->color_4us (op->alpha_mask.alpha,
+ op->alpha_mask.alpha,
+ op->alpha_mask.alpha,
+ op->alpha_mask.alpha);
+ } else {
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_REPLACE);
+ op->gl->color_4us (0x0, 0x0, 0x0, 0xffff);
+ }
+}
- if (dst->feature_mask & GLITZ_FEATURE_CONVOLUTION_FILTER_MASK) {
- src_conv = (src->convolution)? 1: 0;
- mask_conv = (mask && mask->convolution)? 1: 0;
- } else
- src_conv = mask_conv = 0;
+static void
+_glitz_render_argb_argb (glitz_render_op_t *op)
+{
+ op->gl->active_texture (GLITZ_GL_TEXTURE0);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_REPLACE);
+ op->gl->color_4us (0x0, 0x0, 0x0, 0xffff);
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE1);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_COMBINE);
+
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB,
+ GLITZ_GL_MODULATE);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB,
+ GLITZ_GL_TEXTURE);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB,
+ GLITZ_GL_PREVIOUS);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB,
+ 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,
+ GLITZ_GL_TEXTURE);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_ALPHA,
+ GLITZ_GL_PREVIOUS);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA,
+ GLITZ_GL_SRC_ALPHA);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_ALPHA,
+ GLITZ_GL_SRC_ALPHA);
+}
+
+static void
+_setup_x_argbc (glitz_render_op_t *op)
+{
+ op->gl->active_texture (GLITZ_GL_TEXTURE0);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_COMBINE);
+
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB,
+ GLITZ_GL_INTERPOLATE);
+
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB,
+ GLITZ_GL_TEXTURE);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB,
+ GLITZ_GL_PRIMARY_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE2_RGB,
+ GLITZ_GL_PRIMARY_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB,
+ GLITZ_GL_SRC_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB,
+ GLITZ_GL_SRC_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND2_RGB,
+ GLITZ_GL_SRC_ALPHA);
+
+ /* we don't care about the alpha channel, so lets do something (simple?) */
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA,
+ GLITZ_GL_REPLACE);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA,
+ GLITZ_GL_PRIMARY_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA,
+ GLITZ_GL_SRC_ALPHA);
+
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE1);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_COMBINE);
- if (!mask) {
- if (SURFACE_SOLID (src))
- return GLITZ_RENDER_TYPE_SOLID;
- else if ((!src_conv) && (!SURFACE_PROGRAMMATIC (src)))
- return GLITZ_RENDER_TYPE_ARGB;
- else if (SURFACE_PROGRAMMATIC (src) &&
- (dst->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK))
- return GLITZ_RENDER_TYPE_SRC_PROGRAMMATIC;
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB,
+ GLITZ_GL_DOT3_RGBA);
+
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB,
+ GLITZ_GL_PREVIOUS);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB,
+ GLITZ_GL_PRIMARY_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB,
+ GLITZ_GL_SRC_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB,
+ GLITZ_GL_SRC_COLOR);
+}
+
+static void
+_glitz_render_argb_argbc (glitz_render_op_t *op)
+{
+ if (op->count == 0) {
+ _setup_x_argbc (op);
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE2);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_MODULATE);
+ }
+
+ if (op->alpha_mask.red) {
+ op->gl->color_4d (1.0, 0.5, 0.5, 0.5);
+ } else if (op->alpha_mask.green) {
+ op->gl->color_4d (0.5, 1.0, 0.5, 0.5);
+ } else if (op->alpha_mask.blue) {
+ op->gl->color_4d (0.5, 0.5, 1.0, 0.5);
+ } else {
+ op->gl->active_texture (GLITZ_GL_TEXTURE0);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_REPLACE);
+ op->gl->color_4us (0x0, 0x0, 0x0, 0xffff);
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE1);
+ glitz_texture_unbind (op->gl, op->src_texture);
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE2);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_MODULATE);
}
+}
- if ((!src_conv) &&
- mask && (!SURFACE_PROGRAMMATIC (mask)) && (!mask_conv)) {
- if ((mask->texture.format == GLITZ_GL_INTENSITY4 ||
- mask->texture.format == GLITZ_GL_INTENSITY8 ||
- mask->texture.format == GLITZ_GL_INTENSITY12 ||
- mask->texture.format == GLITZ_GL_INTENSITY16) &&
- (dst->feature_mask & GLITZ_FEATURE_ARB_MULTITEXTURE_MASK)) {
- if (SURFACE_SOLID (src))
- return GLITZ_RENDER_TYPE_SOLID_A;
- else if (!SURFACE_PROGRAMMATIC (src))
- return GLITZ_RENDER_TYPE_ARGB_A;
- else if (dst->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK)
- return GLITZ_RENDER_TYPE_SRC_PROGRAMMATIC;
- } else if (dst->feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) {
- if (!SURFACE_PROGRAMMATIC (src))
- return GLITZ_RENDER_TYPE_ARGB_ARGB;
- else
- return GLITZ_RENDER_TYPE_SRC_PROGRAMMATIC;
- }
+
+static void
+_glitz_render_solid_solid (glitz_render_op_t *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));
+}
+
+static void
+_glitz_render_solid_argb (glitz_render_op_t *op)
+{
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_COMBINE);
+
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB,
+ GLITZ_GL_MODULATE);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB,
+ GLITZ_GL_TEXTURE);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB,
+ GLITZ_GL_PRIMARY_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB,
+ GLITZ_GL_SRC_ALPHA);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB,
+ GLITZ_GL_SRC_COLOR);
+
+ 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,
+ GLITZ_GL_TEXTURE);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_ALPHA,
+ GLITZ_GL_PRIMARY_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA,
+ GLITZ_GL_SRC_ALPHA);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_ALPHA,
+ GLITZ_GL_SRC_ALPHA);
+
+ op->gl->color_4us (op->solid->red,
+ op->solid->green,
+ op->solid->blue,
+ op->solid->alpha);
+}
+
+static void
+_glitz_render_solid_argbc (glitz_render_op_t *op)
+{
+ if (op->count == 0) {
+ glitz_gl_float_t color[4];
+
+ _setup_x_argbc (op);
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE2);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_COMBINE);
+
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_RGB,
+ GLITZ_GL_MODULATE);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_RGB,
+ GLITZ_GL_PREVIOUS);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_RGB,
+ GLITZ_GL_CONSTANT);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_RGB,
+ GLITZ_GL_SRC_COLOR);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB,
+ GLITZ_GL_SRC_COLOR);
+
+ 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,
+ GLITZ_GL_PREVIOUS);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE1_ALPHA,
+ GLITZ_GL_CONSTANT);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND0_ALPHA,
+ GLITZ_GL_SRC_ALPHA);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_ALPHA,
+ GLITZ_GL_SRC_ALPHA);
+
+ color[0] = (double) op->solid->red / 65536.0;
+ color[1] = (double) op->solid->green / 65536.0;
+ color[2] = (double) op->solid->blue / 65536.0;
+ color[3] = (double) op->solid->alpha / 65536.0;
+
+ op->gl->tex_env_fv (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_COLOR,
+ color);
+ }
+
+ if (op->alpha_mask.red) {
+ op->gl->color_4d (1.0, 0.5, 0.5, 0.5);
+ } else if (op->alpha_mask.green) {
+ op->gl->color_4d (0.5, 1.0, 0.5, 0.5);
+ } else if (op->alpha_mask.blue) {
+ op->gl->color_4d (0.5, 0.5, 1.0, 0.5);
+ } else {
+ op->gl->active_texture (GLITZ_GL_TEXTURE0);
+ op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+ GLITZ_GL_MODULATE);
+ op->gl->color_4us (op->solid->red,
+ op->solid->green,
+ op->solid->blue,
+ op->solid->alpha);
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE1);
+ glitz_texture_unbind (op->gl, op->src_texture);
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE2);
+ glitz_texture_unbind (op->gl, op->src_texture);
}
+}
+
+static void
+_glitz_render_argbf (glitz_render_op_t *op)
+{
+ if (op->count == 0) {
+ glitz_gl_uint_t vertex_program, fragment_program;
+
+ vertex_program = glitz_get_vertex_program (op);
+ fragment_program = glitz_get_fragment_program (op);
- if (src_conv) {
- if (mask && SURFACE_SOLID (mask)) {
- return GLITZ_RENDER_TYPE_SRC_CONVOLUTION_AND_SOLID_MASK;
- } else if ((!mask) || (!SURFACE_PROGRAMMATIC (mask)))
- return GLITZ_RENDER_TYPE_SRC_CONVOLUTION;
+ if (vertex_program && fragment_program) {
+ glitz_texture_t *texture = op->src_texture;
+ glitz_surface_t *surface = op->src;
+
+ op->gl->enable (GLITZ_GL_VERTEX_PROGRAM);
+ op->gl->bind_program (GLITZ_GL_VERTEX_PROGRAM, vertex_program);
+ op->gl->program_local_param_4d (GLITZ_GL_VERTEX_PROGRAM, 0,
+ texture->texcoord_width /
+ (double) texture->width,
+ 0.000, 0.0, 0.0);
+ op->gl->program_local_param_4d (GLITZ_GL_VERTEX_PROGRAM, 1,
+ 0.000,
+ texture->texcoord_height /
+ (double) texture->height,
+ 0.0, 0.0);
+
+ op->gl->enable (GLITZ_GL_FRAGMENT_PROGRAM);
+ op->gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, fragment_program);
+ op->gl->program_local_param_4d (GLITZ_GL_FRAGMENT_PROGRAM, 0,
+ surface->convolution->m[0][0],
+ surface->convolution->m[0][1],
+ surface->convolution->m[0][2], 0.0);
+ op->gl->program_local_param_4d (GLITZ_GL_FRAGMENT_PROGRAM, 1,
+ surface->convolution->m[1][0],
+ surface->convolution->m[1][1],
+ surface->convolution->m[1][2], 0.0);
+ op->gl->program_local_param_4d (GLITZ_GL_FRAGMENT_PROGRAM, 2,
+ surface->convolution->m[2][0],
+ surface->convolution->m[2][1],
+ surface->convolution->m[2][2], 0.0);
+ }
+
+ op->gl->color_4us (op->alpha_mask.red,
+ op->alpha_mask.green,
+ op->alpha_mask.blue,
+ op->alpha_mask.alpha);
}
+}
+
+static void
+_glitz_end_f (glitz_render_op_t *op)
+{
+ op->gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, 0);
+ op->gl->disable (GLITZ_GL_FRAGMENT_PROGRAM);
+ op->gl->bind_program (GLITZ_GL_VERTEX_PROGRAM, 0);
+ op->gl->disable (GLITZ_GL_VERTEX_PROGRAM);
+}
+
+static void
+_glitz_render_lgrad (glitz_render_op_t *op)
+{
+ if (op->count == 0) {
+ glitz_gl_uint_t fragment_program;
+
+ fragment_program = glitz_get_fragment_program (op);
+
+ if (fragment_program) {
+ glitz_programmatic_surface_t *surface =
+ (glitz_programmatic_surface_t *) op->src;
+ glitz_point_t p1, p2;
+ double length, angle, start;
- if (mask_conv) {
- if (SURFACE_SOLID (src)) {
- return GLITZ_RENDER_TYPE_MASK_CONVOLUTION_AND_SOLID_SRC;
- } else if (!SURFACE_PROGRAMMATIC (src))
- return GLITZ_RENDER_TYPE_MASK_CONVOLUTION;
+ op->gl->enable (GLITZ_GL_FRAGMENT_PROGRAM);
+ op->gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, fragment_program);
+
+ p1.x = FIXED_TO_DOUBLE (surface->u.linear.start.x);
+ p1.y = FIXED_TO_DOUBLE (surface->u.linear.start.y);
+ p2.x = FIXED_TO_DOUBLE (surface->u.linear.stop.x);
+ p2.y = FIXED_TO_DOUBLE (surface->u.linear.stop.y);
+
+ length = sqrt ((p2.x - p1.x) * (p2.x - p1.x) +
+ (p2.y - p1.y) * (p2.y - p1.y));
+
+ angle = -atan2 (p2.y - p1.y, p2.x - p1.x);
+
+ start = cos (angle) * p1.x;
+ start += -sin (angle) * p1.y;
+
+ op->gl->program_local_param_4d (GLITZ_GL_FRAGMENT_PROGRAM, 0, start,
+ (length)? 1.0 / length: INT_MAX,
+ cos (angle), -sin (angle));
+ op->gl->program_local_param_4d (GLITZ_GL_FRAGMENT_PROGRAM, 1,
+ surface->matrix.m[0][0],
+ surface->matrix.m[0][1],
+ surface->matrix.m[1][0],
+ surface->matrix.m[1][1]);
+ op->gl->program_local_param_4d (GLITZ_GL_FRAGMENT_PROGRAM, 2,
+ surface->matrix.m[2][0],
+ surface->matrix.m[2][1],
+ surface->base.height, 0.0);
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE2);
+ glitz_color_range_bind (op->gl, surface->u.linear.color_range,
+ op->dst->feature_mask);
+ op->gl->active_texture (GLITZ_GL_TEXTURE0);
+ }
}
+
+ op->gl->color_4us (op->alpha_mask.red,
+ op->alpha_mask.green,
+ op->alpha_mask.blue,
+ op->alpha_mask.alpha);
+}
+
+static void
+_glitz_render_rgrad (glitz_render_op_t *op)
+{
+ if (op->count == 0) {
+ glitz_gl_uint_t fragment_program;
+
+ fragment_program = glitz_get_fragment_program (op);
- return GLITZ_RENDER_TYPE_NOT_SUPPORTED;
+ if (fragment_program) {
+ glitz_programmatic_surface_t *surface =
+ (glitz_programmatic_surface_t *) op->src;
+
+ op->gl->enable (GLITZ_GL_FRAGMENT_PROGRAM);
+ op->gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, fragment_program);
+
+ op->gl->program_local_param_4d
+ (GLITZ_GL_FRAGMENT_PROGRAM, 0,
+ FIXED_TO_DOUBLE (surface->u.radial.center.x),
+ FIXED_TO_DOUBLE (surface->u.radial.center.y),
+ 1.0 / (FIXED_TO_DOUBLE (surface->u.radial.radius1) -
+ FIXED_TO_DOUBLE (surface->u.radial.radius0)),
+ FIXED_TO_DOUBLE (surface->u.radial.radius0));
+ op->gl->program_local_param_4d (GLITZ_GL_FRAGMENT_PROGRAM, 1,
+ surface->matrix.m[0][0],
+ surface->matrix.m[0][1],
+ surface->matrix.m[1][0],
+ surface->matrix.m[1][1]);
+ op->gl->program_local_param_4d (GLITZ_GL_FRAGMENT_PROGRAM, 2,
+ surface->matrix.m[2][0],
+ surface->matrix.m[2][1],
+ surface->base.height, 0.0);
+
+ op->gl->active_texture (GLITZ_GL_TEXTURE2);
+ glitz_color_range_bind (op->gl, surface->u.radial.color_range,
+ op->dst->feature_mask);
+ op->gl->active_texture (GLITZ_GL_TEXTURE0);
+ }
+ }
+
+ op->gl->color_4us (op->alpha_mask.red,
+ op->alpha_mask.green,
+ op->alpha_mask.blue,
+ op->alpha_mask.alpha);
}
-void
-glitz_render_enable (glitz_render_type_t type,
- glitz_surface_t *src,
- glitz_surface_t *mask,
- glitz_surface_t *dst,
- glitz_texture_t *src_texture,
- glitz_texture_t *mask_texture,
- unsigned short opacity)
-{
- switch (type) {
- case GLITZ_RENDER_TYPE_ARGB:
- if (opacity != 0xffff) {
- dst->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV,
- GLITZ_GL_TEXTURE_ENV_MODE,
- GLITZ_GL_MODULATE);
- dst->gl->color_4us (opacity, opacity, opacity, opacity);
- } else {
- dst->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV,
- GLITZ_GL_TEXTURE_ENV_MODE,
- GLITZ_GL_REPLACE);
- dst->gl->color_4us (0x0, 0x0, 0x0, 0xffff);
+static void
+_glitz_end_grad (glitz_render_op_t *op)
+{
+ op->gl->active_texture (GLITZ_GL_TEXTURE2);
+ op->gl->bind_texture (GLITZ_GL_TEXTURE_1D, 0);
+ op->gl->disable (GLITZ_GL_TEXTURE_1D);
+ op->gl->active_texture (GLITZ_GL_TEXTURE0);
+ op->gl->bind_program (GLITZ_GL_FRAGMENT_PROGRAM, 0);
+ op->gl->disable (GLITZ_GL_FRAGMENT_PROGRAM);
+}
+
+static glitz_render_t
+_glitz_render_map[GLITZ_SURFACE_TYPES][GLITZ_SURFACE_TYPES] = {
+ {
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 }
+ }, {
+ { GLITZ_RENDER_TYPE_ARGB, _glitz_render_argb_solid, NULL, 1 },
+ { GLITZ_RENDER_TYPE_ARGB_ARGB, _glitz_render_argb_argb, NULL, 2 },
+ { GLITZ_RENDER_TYPE_ARGB_ARGBC, _glitz_render_argb_argbc, NULL, 3 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_ARGB_SOLID, _glitz_render_argb_solid, NULL, 1 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 }
+ }, {
+ { GLITZ_RENDER_TYPE_ARGB, _glitz_render_argb_solid, NULL, 1 },
+ { GLITZ_RENDER_TYPE_ARGB_ARGB, _glitz_render_argb_argb, NULL, 2 },
+ { GLITZ_RENDER_TYPE_ARGB_ARGBC, _glitz_render_argb_argbc, NULL, 3 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_ARGB_SOLID, _glitz_render_argb_solid, NULL, 1 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 }
+ }, {
+ { GLITZ_RENDER_TYPE_ARGBF, _glitz_render_argbf, _glitz_end_f, 1 },
+ { GLITZ_RENDER_TYPE_ARGBF_ARGB, _glitz_render_argbf, _glitz_end_f, 2 },
+ { GLITZ_RENDER_TYPE_ARGBF_ARGBC, _glitz_render_argbf, _glitz_end_f, 2 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_ARGBF_SOLID, _glitz_render_argbf, _glitz_end_f, 1 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 }
+ }, {
+ { GLITZ_RENDER_TYPE_SOLID, _glitz_render_solid_solid, NULL, 0 },
+ { GLITZ_RENDER_TYPE_SOLID_ARGB, _glitz_render_solid_argb, NULL, 1 },
+ { GLITZ_RENDER_TYPE_SOLID_ARGBC, _glitz_render_solid_argbc, NULL, 3 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_SOLID_SOLID, _glitz_render_solid_solid, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 }
+ }, {
+ { GLITZ_RENDER_TYPE_LGRAD, _glitz_render_lgrad, _glitz_end_grad, 0 },
+ { GLITZ_RENDER_TYPE_LGRAD_ARGB, _glitz_render_lgrad, _glitz_end_grad, 2 },
+ { GLITZ_RENDER_TYPE_LGRAD_ARGBC, _glitz_render_lgrad, _glitz_end_grad, 2 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_LGRAD_SOLID, _glitz_render_lgrad, _glitz_end_grad, 1 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 }
+ }, {
+ { GLITZ_RENDER_TYPE_RGRAD, _glitz_render_rgrad, _glitz_end_grad, 0 },
+ { GLITZ_RENDER_TYPE_RGRAD_ARGB, _glitz_render_rgrad, _glitz_end_grad, 2 },
+ { GLITZ_RENDER_TYPE_RGRAD_ARGBC, _glitz_render_rgrad, _glitz_end_grad, 2 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_RGRAD_SOLID, _glitz_render_rgrad, _glitz_end_grad, 1 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 },
+ { GLITZ_RENDER_TYPE_NA, NULL, NULL, 0 }
+ }
+};
+
+#define MANUAL_REPEAT(surface) \
+ (((surface)->hint_mask & GLITZ_INT_HINT_REPEAT_MASK) && \
+ (!(surface)->texture.repeatable))
+
+#define ROTATING_TRANSFORM(surface) \
+ ((surface)->transform && \
+ (((surface)->transform->m[0][1] != 0.0) || \
+ ((surface)->transform->m[1][0] != 0.0)))
+
+#define SIMPLE_SURFACE(surface) \
+ ((!MANUAL_REPEAT (surface)) && (!ROTATING_TRANSFORM (surface)))
+
+#define MULTI_TEXTURE(feature_mask, src, mask) \
+ (((feature_mask) & GLITZ_FEATURE_ARB_MULTITEXTURE_MASK) && \
+ (SIMPLE_SURFACE (src) && SIMPLE_SURFACE (mask)))
+
+static glitz_surface_type_t
+_glitz_get_surface_type (unsigned long feature_mask,
+ glitz_surface_t *surface)
+{
+ if (surface == NULL)
+ return GLITZ_SURFACE_TYPE_NULL;
+
+ if (SURFACE_PROGRAMMATIC (surface)) {
+ if (SURFACE_SOLID (surface))
+ return GLITZ_SURFACE_TYPE_SOLID;
+ else if (feature_mask & GLITZ_FEATURE_ARB_FRAGMENT_PROGRAM_MASK) {
+ if (SURFACE_LINEAR_GRADIENT (surface))
+ return GLITZ_SURFACE_TYPE_LGRAD;
+ else
+ return GLITZ_SURFACE_TYPE_RGRAD;
}
- break;
- case GLITZ_RENDER_TYPE_ARGB_ARGB:
- glitz_program_enable_argb_argb (dst->gl, dst->programs,
- src_texture, mask_texture);
- break;
- case GLITZ_RENDER_TYPE_SOLID_A:
- glitz_programmatic_surface_bind (dst->gl,
- (glitz_programmatic_surface_t *) src,
- dst->feature_mask,
- 0xffff);
- break;
- case GLITZ_RENDER_TYPE_ARGB_A:
- break;
- case GLITZ_RENDER_TYPE_SOLID:
- glitz_programmatic_surface_bind (dst->gl,
- (glitz_programmatic_surface_t *) src,
- dst->feature_mask,
- opacity);
- break;
- case GLITZ_RENDER_TYPE_SRC_CONVOLUTION:
- case GLITZ_RENDER_TYPE_SRC_CONVOLUTION_AND_SOLID_MASK:
- glitz_program_enable_convolution (dst->gl, dst->programs,
- src, mask, src_texture, mask_texture,
- GLITZ_PROGRAM_SRC_OPERATION_OFFSET, 1,
- opacity);
- break;
- case GLITZ_RENDER_TYPE_MASK_CONVOLUTION:
- glitz_program_enable_convolution (dst->gl, dst->programs,
- src, mask, src_texture, mask_texture,
- GLITZ_PROGRAM_MASK_OPERATION_OFFSET, 0,
- 0xffff);
- break;
- case GLITZ_RENDER_TYPE_MASK_CONVOLUTION_AND_SOLID_SRC:
- glitz_program_enable_convolution (dst->gl, dst->programs,
- src, mask, src_texture, mask_texture,
- GLITZ_PROGRAM_MASK_OPERATION_OFFSET, 2,
- 0xffff);
- break;
- case GLITZ_RENDER_TYPE_SRC_PROGRAMMATIC:
- glitz_program_enable_programmatic (dst,
- (glitz_programmatic_surface_t *) src,
- src_texture, mask_texture,
- GLITZ_PROGRAM_SRC_OPERATION_OFFSET,
- opacity);
- break;
- case GLITZ_RENDER_TYPE_MASK_PROGRAMMATIC:
- glitz_program_enable_programmatic (dst,
- (glitz_programmatic_surface_t *) mask,
- src_texture, mask_texture,
- GLITZ_PROGRAM_MASK_OPERATION_OFFSET,
- 0xffff);
- break;
- case GLITZ_RENDER_TYPE_NOT_SUPPORTED:
- break;
+ } else {
+ if (!surface->convolution) {
+ if (SURFACE_COMPONENT_ALPHA (surface)) {
+ if (feature_mask & GLITZ_FEATURE_COMPONENT_ALPHA_MASK)
+ return GLITZ_SURFACE_TYPE_ARGBC;
+ } else
+ return GLITZ_SURFACE_TYPE_ARGB;
+
+ } else if (feature_mask & GLITZ_FEATURE_CONVOLUTION_FILTER_MASK)
+ return GLITZ_SURFACE_TYPE_ARGBF;
}
+
+ return GLITZ_SURFACE_TYPE_NA;
}
+static glitz_color_t _default_alpha_mask = {
+ 0x0000, 0x0000, 0x0000, 0xffff
+};
+
void
-glitz_render_disable (glitz_render_type_t type,
- glitz_surface_t *dst)
-{
- switch (type) {
- case GLITZ_RENDER_TYPE_SRC_PROGRAMMATIC:
- case GLITZ_RENDER_TYPE_MASK_PROGRAMMATIC:
- dst->gl->active_texture_arb (GLITZ_GL_TEXTURE2_ARB);
- dst->gl->bind_texture (GLITZ_GL_TEXTURE_1D, 0);
- dst->gl->disable (GLITZ_GL_TEXTURE_1D);
- dst->gl->active_texture_arb (GLITZ_GL_TEXTURE0_ARB);
- /* fall-through */
- case GLITZ_RENDER_TYPE_SRC_CONVOLUTION:
- case GLITZ_RENDER_TYPE_SRC_CONVOLUTION_AND_SOLID_MASK:
- case GLITZ_RENDER_TYPE_MASK_CONVOLUTION:
- case GLITZ_RENDER_TYPE_MASK_CONVOLUTION_AND_SOLID_SRC:
- dst->gl->bind_program_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 0);
- dst->gl->disable (GLITZ_GL_FRAGMENT_PROGRAM_ARB);
- dst->gl->bind_program_arb (GLITZ_GL_VERTEX_PROGRAM_ARB, 0);
- dst->gl->disable (GLITZ_GL_VERTEX_PROGRAM_ARB);
- break;
- default:
- break;
+glitz_render_op_init (glitz_render_op_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)
+{
+ glitz_surface_type_t src_type;
+ glitz_surface_type_t mask_type;
+ glitz_render_t *render;
+
+ op->type = GLITZ_RENDER_TYPE_NA;
+ op->render = NULL;
+ op->alpha_mask = _default_alpha_mask;
+ op->gl = dst->gl;
+ op->dst = dst;
+ op->src_texture = op->mask_texture = NULL;
+ op->count = 0;
+ op->src = *src;
+ op->mask = *mask;
+ op->solid = NULL;
+ op->component_alpha = GLITZ_COMPONENT_ALPHA_NONE;
+
+ src_type = _glitz_get_surface_type (dst->feature_mask, *src);
+ if (src_type < 1)
+ return;
+
+ mask_type = _glitz_get_surface_type (dst->feature_mask, *mask);
+ if (mask_type < 0)
+ return;
+
+ render = &_glitz_render_map[src_type][mask_type];
+ if (render->type == GLITZ_RENDER_TYPE_NA) {
+ if (dst->feature_mask & GLITZ_FEATURE_OFFSCREEN_DRAWING_MASK)
+ op->type = GLITZ_RENDER_TYPE_INTERMEDIATE;
+
+ return;
+ }
+
+ if (mask_type == GLITZ_SURFACE_TYPE_SOLID) {
+ op->alpha_mask.alpha =
+ ((glitz_programmatic_surface_t *) (op->mask))->u.solid.color.alpha;
+ *mask = NULL;
+ }
+
+ if (src_type == GLITZ_SURFACE_TYPE_SOLID) {
+ op->solid = &((glitz_programmatic_surface_t *) (op->src))->u.solid.color;
+
+ /* mask becomes source */
+ if (*mask) {
+ *src = *mask;
+ *mask = NULL;
+ *x_src = *x_mask;
+ *y_src = *y_mask;
+ }
}
+
+ if (mask_type != GLITZ_SURFACE_TYPE_NULL &&
+ mask_type != GLITZ_SURFACE_TYPE_SOLID) {
+ if (dst->feature_mask & GLITZ_FEATURE_ARB_TEXTURE_ENV_COMBINE_MASK) {
+ if (mask_type == GLITZ_SURFACE_TYPE_ARGBC) {
+ if (op->mask->format->alpha_size)
+ op->component_alpha = GLITZ_COMPONENT_ALPHA_ARGB;
+ else
+ op->component_alpha = GLITZ_COMPONENT_ALPHA_RGB;
+ }
+
+ if (src_type != GLITZ_SURFACE_TYPE_SOLID) {
+ if (MULTI_TEXTURE (dst->feature_mask, *src, *mask))
+ op->render = render;
+ else if ((dst->feature_mask & GLITZ_FEATURE_OFFSCREEN_DRAWING_MASK) &&
+ (!SURFACE_COMPONENT_ALPHA (*mask)))
+ op->type = GLITZ_RENDER_TYPE_INTERMEDIATE;
+
+ } else
+ op->render = render;
+ }
+ } else
+ op->render = render;
+
+ /* update source and mask */
+ op->src = *src;
+ op->mask = *mask;
+
+ if (op->render == render)
+ op->type = render->type;
+}
+
+void
+glitz_render_op_set_textures (glitz_render_op_t *op,
+ glitz_texture_t *src,
+ glitz_texture_t *mask)
+{
+ op->src_texture = src;
+ op->mask_texture = mask;
+}
+
+void
+glitz_render_op_set_alpha_mask (glitz_render_op_t *op,
+ unsigned short red,
+ unsigned short green,
+ unsigned short blue,
+ unsigned short alpha)
+{
+ op->alpha_mask.red = red;
+ op->alpha_mask.green = green;
+ op->alpha_mask.blue = blue;
+ op->alpha_mask.alpha = alpha;
+}
+
+void
+glitz_render_op_get_alpha_mask (glitz_render_op_t *op,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue,
+ unsigned short *alpha)
+{
+ if (red) *red = op->alpha_mask.red;
+ if (green) *green = op->alpha_mask.green;
+ if (blue) *blue = op->alpha_mask.blue;
+ if (alpha) *alpha = op->alpha_mask.alpha;
+}
+
+void
+glitz_render_enable (glitz_render_op_t *op)
+{
+ op->render->enable (op);
+ op->count++;
+}
+
+void
+glitz_render_disable (glitz_render_op_t *op)
+{
+ if (op->render->disable)
+ op->render->disable (op);
}
diff --git a/src/glitz_surface.c b/src/glitz_surface.c
index ed95511..4104d07 100644
--- a/src/glitz_surface.c
+++ b/src/glitz_surface.c
@@ -43,17 +43,19 @@ glitz_surface_init (glitz_surface_t *surface,
int n_formats,
int width,
int height,
- glitz_programs_t *programs,
+ glitz_program_map_t *program_map,
unsigned long texture_mask)
{
surface->backend = backend;
+ surface->ref_count = 1;
+
surface->filter = GLITZ_FILTER_NEAREST;
surface->polyedge = GLITZ_POLYEDGE_SMOOTH;
surface->polyedge_smooth_hint = GLITZ_POLYEDGE_SMOOTH_HINT_GOOD;
surface->polyopacity = 0xffff;
-
- surface->programs = programs;
+
+ surface->program_map = program_map;
surface->format = format;
surface->formats = formats;
surface->n_formats = n_formats;
@@ -221,8 +223,24 @@ glitz_surface_create_radial (glitz_point_fixed_t *center,
slim_hidden_def(glitz_surface_create_radial);
void
+glitz_surface_reference (glitz_surface_t *surface)
+{
+ if (surface == NULL)
+ return;
+
+ surface->ref_count++;
+}
+
+void
glitz_surface_destroy (glitz_surface_t *surface)
{
+ if (!surface)
+ return;
+
+ surface->ref_count--;
+ if (surface->ref_count)
+ return;
+
surface->backend->destroy (surface);
}
@@ -385,6 +403,21 @@ glitz_surface_set_repeat (glitz_surface_t *surface,
slim_hidden_def(glitz_surface_set_repeat);
void
+glitz_surface_set_component_alpha (glitz_surface_t *surface,
+ glitz_bool_t component_alpha)
+{
+ if (SURFACE_PROGRAMMATIC (surface))
+ return;
+
+ if (component_alpha && surface->format->red_size)
+ surface->hint_mask |= GLITZ_INT_HINT_COMPONENT_ALPHA_MASK;
+ else
+ surface->hint_mask &= ~GLITZ_INT_HINT_COMPONENT_ALPHA_MASK;
+
+}
+slim_hidden_def(glitz_surface_set_component_alpha);
+
+void
glitz_surface_set_filter (glitz_surface_t *surface,
glitz_filter_t filter)
{
diff --git a/src/glitz_texture.c b/src/glitz_texture.c
index 8abb308..3136af5 100644
--- a/src/glitz_texture.c
+++ b/src/glitz_texture.c
@@ -43,7 +43,7 @@ _glitz_texture_find_best_target (unsigned int width,
(!glitz_uint_is_power_of_two (width)) ||
(!glitz_uint_is_power_of_two (height))) {
if (target_mask & GLITZ_TEXTURE_TARGET_RECTANGLE_MASK)
- *target = GLITZ_GL_TEXTURE_RECTANGLE_EXT;
+ *target = GLITZ_GL_TEXTURE_RECTANGLE;
}
}
@@ -179,7 +179,7 @@ void
glitz_texture_bind (glitz_gl_proc_address_list_t *gl,
glitz_texture_t *texture)
{
- gl->disable (GLITZ_GL_TEXTURE_RECTANGLE_EXT);
+ gl->disable (GLITZ_GL_TEXTURE_RECTANGLE);
gl->disable (GLITZ_GL_TEXTURE_2D);
if (!texture->target)
diff --git a/src/glitzint.h b/src/glitzint.h
index f8decfa..3b8fea3 100644
--- a/src/glitzint.h
+++ b/src/glitzint.h
@@ -88,8 +88,10 @@ typedef struct _glitz_gl_proc_address_list_t {
glitz_gl_vertex_2i_t vertex_2i;
glitz_gl_vertex_2d_t vertex_2d;
glitz_gl_tex_env_f_t tex_env_f;
+ glitz_gl_tex_env_fv_t tex_env_fv;
glitz_gl_tex_coord_2d_t tex_coord_2d;
glitz_gl_color_4us_t color_4us;
+ glitz_gl_color_4d_t color_4d;
glitz_gl_scissor_t scissor;
glitz_gl_blend_func_t blend_func;
glitz_gl_clear_t clear;
@@ -138,71 +140,74 @@ typedef struct _glitz_gl_proc_address_list_t {
glitz_gl_end_list_t end_list;
glitz_gl_call_list_t call_list;
- glitz_gl_active_texture_arb_t active_texture_arb;
- glitz_gl_multi_tex_coord_2d_arb_t multi_tex_coord_2d_arb;
- glitz_gl_gen_programs_arb_t gen_programs_arb;
- glitz_gl_delete_programs_arb_t delete_programs_arb;
- glitz_gl_program_string_arb_t program_string_arb;
- glitz_gl_bind_program_arb_t bind_program_arb;
- glitz_gl_program_local_param_4d_arb_t program_local_param_4d_arb;
- glitz_gl_get_program_iv_arb_t get_program_iv_arb;
+ glitz_gl_active_texture_t active_texture;
+ glitz_gl_multi_tex_coord_2d_t multi_tex_coord_2d;
+ glitz_gl_gen_programs_t gen_programs;
+ glitz_gl_delete_programs_t delete_programs;
+ glitz_gl_program_string_t program_string;
+ glitz_gl_bind_program_t bind_program;
+ glitz_gl_program_local_param_4d_t program_local_param_4d;
+ glitz_gl_get_program_iv_t get_program_iv;
+ glitz_gl_gen_buffers_t gen_buffers;
+ glitz_gl_delete_buffers_t delete_buffers;
+ glitz_gl_bind_buffer_t bind_buffer;
+ glitz_gl_buffer_data_t buffer_data;
+ glitz_gl_map_buffer_t map_buffer;
+ glitz_gl_unmap_buffer_t unmap_buffer;
glitz_bool_t need_lookup;
} glitz_gl_proc_address_list_t;
-typedef enum {
- GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE = 0,
- GLITZ_PROGRAMMATIC_SURFACE_LINEAR_TYPE,
- GLITZ_PROGRAMMATIC_SURFACE_RADIAL_TYPE
-} glitz_programmatic_surface_type_t;
-
-typedef enum {
- GLITZ_RENDER_TYPE_NOT_SUPPORTED = 0,
- GLITZ_RENDER_TYPE_SOLID,
- GLITZ_RENDER_TYPE_SOLID_A,
- GLITZ_RENDER_TYPE_ARGB,
- GLITZ_RENDER_TYPE_ARGB_A,
- GLITZ_RENDER_TYPE_ARGB_ARGB,
- GLITZ_RENDER_TYPE_SRC_CONVOLUTION,
- GLITZ_RENDER_TYPE_SRC_CONVOLUTION_AND_SOLID_MASK,
- GLITZ_RENDER_TYPE_MASK_CONVOLUTION,
- GLITZ_RENDER_TYPE_MASK_CONVOLUTION_AND_SOLID_SRC,
- GLITZ_RENDER_TYPE_SRC_PROGRAMMATIC,
- GLITZ_RENDER_TYPE_MASK_PROGRAMMATIC
-} glitz_render_type_t;
-
-#define GLITZ_PROGRAMMATIC_SURFACE_NUM \
- (GLITZ_PROGRAMMATIC_SURFACE_RADIAL_TYPE + 1)
-
-#define GLITZ_PROGRAM_2DSRC_2DMASK_OFFSET 0
-#define GLITZ_PROGRAM_RECTSRC_2DMASK_OFFSET 1
-#define GLITZ_PROGRAM_2DSRC_RECTMASK_OFFSET 2
-#define GLITZ_PROGRAM_RECTSRC_RECTMASK_OFFSET 3
-#define GLITZ_PROGRAM_NOSRC_2DMASK_OFFSET 4
-#define GLITZ_PROGRAM_NOSRC_RECTMASK_OFFSET 5
-#define GLITZ_PROGRAM_2DSRC_NOMASK_OFFSET 6
-#define GLITZ_PROGRAM_RECTSRC_NOMASK_OFFSET 7
-#define GLITZ_PROGRAM_NOSRC_NOMASK_OFFSET 8
-
-#define GLITZ_PROGRAM_SRC_OPERATION_OFFSET 0
-#define GLITZ_PROGRAM_MASK_OPERATION_OFFSET 9
-
-#define GLITZ_VERTEX_PROGRAM_TYPES 2
-#define GLITZ_FRAGMENT_PROGRAM_TYPES 18
-
-#define GLITZ_CONVOLUTION_TYPES 2
-#define GLITZ_FRAGMENT_CONVOLUTION_PROGRAM_TYPES \
- (GLITZ_FRAGMENT_PROGRAM_TYPES * GLITZ_CONVOLUTION_TYPES * 3)
-#define GLITZ_FRAGMENT_PROGRAMMATIC_PROGRAM_TYPES \
- (GLITZ_FRAGMENT_PROGRAM_TYPES * GLITZ_PROGRAMMATIC_SURFACE_NUM)
-
-typedef struct _glitz_programs_t {
- glitz_gl_uint_t vertex_convolution[GLITZ_VERTEX_PROGRAM_TYPES];
- glitz_gl_uint_t fragment_simple[GLITZ_FRAGMENT_PROGRAM_TYPES];
- glitz_gl_uint_t
- fragment_convolution[GLITZ_FRAGMENT_CONVOLUTION_PROGRAM_TYPES];
- glitz_gl_uint_t
- fragment_programmatic[GLITZ_FRAGMENT_PROGRAMMATIC_PROGRAM_TYPES];
-} glitz_programs_t;
+typedef int glitz_surface_type_t;
+
+#define GLITZ_SURFACE_TYPE_NA -1
+#define GLITZ_SURFACE_TYPE_NULL 0
+#define GLITZ_SURFACE_TYPE_ARGB 1
+#define GLITZ_SURFACE_TYPE_ARGBC 2
+#define GLITZ_SURFACE_TYPE_ARGBF 3
+#define GLITZ_SURFACE_TYPE_SOLID 4
+#define GLITZ_SURFACE_TYPE_LGRAD 5
+#define GLITZ_SURFACE_TYPE_RGRAD 6
+#define GLITZ_SURFACE_TYPES 7
+
+typedef int glitz_render_type_t;
+
+#define GLITZ_RENDER_TYPE_NA -1
+#define GLITZ_RENDER_TYPE_INTERMEDIATE 0
+#define GLITZ_RENDER_TYPE_ARGB 1
+#define GLITZ_RENDER_TYPE_ARGB_SOLID 2
+#define GLITZ_RENDER_TYPE_ARGB_ARGB 4
+#define GLITZ_RENDER_TYPE_ARGB_ARGBC 5
+#define GLITZ_RENDER_TYPE_ARGBF 6
+#define GLITZ_RENDER_TYPE_ARGBF_SOLID 7
+#define GLITZ_RENDER_TYPE_ARGBF_ARGB 9
+#define GLITZ_RENDER_TYPE_ARGBF_ARGBC 10
+#define GLITZ_RENDER_TYPE_SOLID 11
+#define GLITZ_RENDER_TYPE_SOLID_SOLID 12
+#define GLITZ_RENDER_TYPE_SOLID_ARGB 14
+#define GLITZ_RENDER_TYPE_SOLID_ARGBC 15
+#define GLITZ_RENDER_TYPE_LGRAD 16
+#define GLITZ_RENDER_TYPE_LGRAD_SOLID 17
+#define GLITZ_RENDER_TYPE_LGRAD_ARGB 19
+#define GLITZ_RENDER_TYPE_LGRAD_ARGBC 20
+#define GLITZ_RENDER_TYPE_RGRAD 21
+#define GLITZ_RENDER_TYPE_RGRAD_SOLID 22
+#define GLITZ_RENDER_TYPE_RGRAD_ARGB 24
+#define GLITZ_RENDER_TYPE_RGRAD_ARGBC 25
+#define GLITZ_RENDER_TYPES 26
+
+#define GLITZ_TEXTURE_NONE 0
+#define GLITZ_TEXTURE_2D 1
+#define GLITZ_TEXTURE_RECT 2
+#define GLITZ_TEXTURE_LAST 3
+
+typedef struct _glitz_program_info_t {
+ glitz_gl_uint_t vertex[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST];
+ glitz_gl_uint_t fragment[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST];
+} glitz_program_info_t;
+
+typedef struct _glitz_program_map_t {
+ glitz_program_info_t info[GLITZ_RENDER_TYPES];
+} glitz_program_map_t;
typedef enum {
GLITZ_CN_NONE,
@@ -281,26 +286,37 @@ typedef struct glitz_surface_backend {
(*make_current_read) (void *surface);
} glitz_surface_backend_t;
-#define GLITZ_INT_HINT_REPEAT_MASK (1L << 5)
-#define GLITZ_INT_HINT_DIRTY_MASK (1L << 6)
-#define GLITZ_INT_HINT_CLEAR_EXTERIOR_MASK (1L << 7)
+#define GLITZ_INT_HINT_REPEAT_MASK (1L << 5)
+#define GLITZ_INT_HINT_DIRTY_MASK (1L << 6)
+#define GLITZ_INT_HINT_CLEAR_EXTERIOR_MASK (1L << 7)
+#define GLITZ_INT_HINT_COMPONENT_ALPHA_MASK (1L << 8)
#define SURFACE_PROGRAMMATIC(surface) \
- (surface->hint_mask & GLITZ_HINT_PROGRAMMATIC_MASK)
+ ((surface)->hint_mask & GLITZ_HINT_PROGRAMMATIC_MASK)
#define SURFACE_SOLID(surface) \
- ((surface->hint_mask & GLITZ_HINT_PROGRAMMATIC_MASK) && \
- ((glitz_programmatic_surface_t *) surface)->type == \
- GLITZ_PROGRAMMATIC_SURFACE_SOLID_TYPE)
+ (((glitz_programmatic_surface_t *) (surface))->type == \
+ GLITZ_PROGRAMMATIC_SURFACE_TYPE_SOLID)
+
+#define SURFACE_LINEAR_GRADIENT(surface) \
+ (((glitz_programmatic_surface_t *) (surface))->type == \
+ GLITZ_PROGRAMMATIC_SURFACE_TYPE_LINEAR)
+
+#define SURFACE_RADIAL_GRADIENT(surface) \
+ (((glitz_programmatic_surface_t *) (surface))->type == \
+ GLITZ_PROGRAMMATIC_SURFACE_TYPE_RADIAL)
#define SURFACE_REPEAT(surface) \
- (surface->hint_mask & GLITZ_INT_HINT_REPEAT_MASK)
+ ((surface)->hint_mask & GLITZ_INT_HINT_REPEAT_MASK)
#define SURFACE_DIRTY(surface) \
- (surface->hint_mask & GLITZ_INT_HINT_DIRTY_MASK)
+ ((surface)->hint_mask & GLITZ_INT_HINT_DIRTY_MASK)
#define SURFACE_CLEAR_EXTERIOR(surface) \
- (surface->hint_mask & GLITZ_INT_HINT_CLEAR_EXTERIOR_MASK)
+ ((surface)->hint_mask & GLITZ_INT_HINT_CLEAR_EXTERIOR_MASK)
+
+#define SURFACE_COMPONENT_ALPHA(surface) \
+ ((surface)->hint_mask & GLITZ_INT_HINT_COMPONENT_ALPHA_MASK)
typedef struct _glitz_sample_offset {
double x;
@@ -319,6 +335,7 @@ typedef struct _glitz_multi_sample_info {
struct _glitz_surface {
const glitz_surface_backend_t *backend;
+ int ref_count;
glitz_format_t *format;
glitz_format_t *formats;
int n_formats;
@@ -333,7 +350,7 @@ struct _glitz_surface {
int width, height;
glitz_bounding_box_t dirty_box;
glitz_gl_proc_address_list_t *gl;
- glitz_programs_t *programs;
+ glitz_program_map_t *program_map;
glitz_matrix_t *convolution;
unsigned int stencil_masks[GLITZ_N_STENCIL_MASKS];
unsigned int *stencil_mask;
@@ -344,21 +361,11 @@ struct _glitz_surface {
glitz_multi_sample_info_t *multi_sample;
};
-#define GLITZ_COLOR_RANGE_UPDATE_TEXTURE_MASK (1L << 0)
-#define GLITZ_COLOR_RANGE_UPDATE_FILTER_MASK (1L << 1)
-#define GLITZ_COLOR_RANGE_UPDATE_EXTEND_MASK (1L << 2)
-#define GLITZ_COLOR_RANGE_UPDATE_ALL_MASK ((1L << 3) - 1)
-
-struct _glitz_color_range {
- unsigned char *data;
- unsigned int size;
- glitz_gl_uint_t texture;
- glitz_filter_t filter;
- glitz_extend_t extend;
- unsigned long update_mask;
- unsigned int ref_count;
- glitz_gl_delete_textures_t delete_textures;
-};
+typedef enum {
+ GLITZ_PROGRAMMATIC_SURFACE_TYPE_SOLID = 0,
+ GLITZ_PROGRAMMATIC_SURFACE_TYPE_LINEAR,
+ GLITZ_PROGRAMMATIC_SURFACE_TYPE_RADIAL
+} glitz_programmatic_surface_type_t;
typedef struct _glitz_programmatic_surface_t {
glitz_surface_t base;
@@ -384,6 +391,39 @@ typedef struct _glitz_programmatic_surface_t {
} u;
} glitz_programmatic_surface_t;
+
+typedef struct _glitz_render_op_t glitz_render_op_t;
+
+typedef void (*glitz_render_function_t) (glitz_render_op_t *);
+
+typedef struct _glitz_render_t {
+ glitz_render_type_t type;
+ glitz_render_function_t enable;
+ glitz_render_function_t disable;
+ int texture_units;
+} glitz_render_t;
+
+typedef enum {
+ GLITZ_COMPONENT_ALPHA_NONE = 0,
+ GLITZ_COMPONENT_ALPHA_RGB,
+ GLITZ_COMPONENT_ALPHA_ARGB
+} glitz_component_alpha_type_t;
+
+struct _glitz_render_op_t {
+ glitz_render_type_t type;
+ glitz_render_t *render;
+ glitz_gl_proc_address_list_t *gl;
+ glitz_surface_t *src;
+ glitz_surface_t *mask;
+ glitz_surface_t *dst;
+ glitz_texture_t *src_texture;
+ glitz_texture_t *mask_texture;
+ glitz_color_t *solid;
+ glitz_color_t alpha_mask;
+ glitz_component_alpha_type_t component_alpha;
+ int count;
+};
+
typedef struct _glitz_extension_map {
char *name;
int mask;
@@ -514,7 +554,7 @@ glitz_surface_init (glitz_surface_t *surface,
int n_formats,
int width,
int height,
- glitz_programs_t *programs,
+ glitz_program_map_t *program_map,
unsigned long texture_mask);
void
@@ -527,6 +567,9 @@ extern glitz_texture_t *__internal_linkage
glitz_surface_get_texture (glitz_surface_t *surface);
extern void __internal_linkage
+glitz_surface_reference (glitz_surface_t *surface);
+
+extern void __internal_linkage
glitz_surface_destory (glitz_surface_t *surface);
glitz_bool_t
@@ -600,19 +643,17 @@ glitz_format_get_best_texture_format (glitz_format_t *formats,
glitz_format_t *format);
void
-glitz_programs_fini (glitz_gl_proc_address_list_t *gl,
- glitz_programs_t *programs);
+glitz_program_map_init (glitz_program_map_t *map);
+
+void
+glitz_program_map_fini (glitz_gl_proc_address_list_t *gl,
+ glitz_program_map_t *map);
-extern void __internal_linkage
-glitz_programmatic_surface_setup (glitz_surface_t *abstract_surface,
- int width,
- int height);
+extern glitz_gl_uint_t __internal_linkage
+glitz_get_vertex_program (glitz_render_op_t *op);
-extern void __internal_linkage
-glitz_programmatic_surface_bind (glitz_gl_proc_address_list_t *proc_address,
- glitz_programmatic_surface_t *surface,
- unsigned long feature_mask,
- unsigned short opacity);
+extern glitz_gl_uint_t __internal_linkage
+glitz_get_fragment_program (glitz_render_op_t *op);
extern glitz_surface_t *__internal_linkage
glitz_programmatic_surface_create_solid (glitz_color_t *color);
@@ -667,29 +708,10 @@ glitz_int_fill_triangles (glitz_operator_t op,
int n_points);
extern void __internal_linkage
-glitz_program_enable_argb_argb (glitz_gl_proc_address_list_t *gl,
- glitz_programs_t *programs,
- glitz_texture_t *src_texture,
- glitz_texture_t *mask_texture);
+glitz_program_enable_convolution (glitz_render_op_t *op);
extern void __internal_linkage
-glitz_program_enable_convolution (glitz_gl_proc_address_list_t *gl,
- glitz_programs_t *programs,
- glitz_surface_t *src,
- glitz_surface_t *mask,
- glitz_texture_t *src_texture,
- glitz_texture_t *mask_texture,
- int offset,
- int solid_offset,
- unsigned short opacity);
-
-extern void __internal_linkage
-glitz_program_enable_programmatic (glitz_surface_t *dst,
- glitz_programmatic_surface_t *surface,
- glitz_texture_t *src_texture,
- glitz_texture_t *mask_texture,
- int offset,
- unsigned short opacity);
+glitz_program_enable_programmatic (glitz_render_op_t *op);
extern void __internal_linkage
glitz_stencil_rectangles (glitz_surface_t *dst,
@@ -710,23 +732,48 @@ glitz_stencil_triangles (glitz_surface_t *dst,
const glitz_point_fixed_t *points,
int n_points);
-extern glitz_render_type_t __internal_linkage
-glitz_render_type (glitz_surface_t *dst,
- glitz_surface_t *src,
- glitz_surface_t *mask);
+extern void __internal_linkage
+glitz_render_op_init (glitz_render_op_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);
+
+extern void __internal_linkage
+glitz_render_op_set_textures (glitz_render_op_t *op,
+ glitz_texture_t *src,
+ glitz_texture_t *mask);
+
+extern void __internal_linkage
+glitz_render_op_set_alpha_mask (glitz_render_op_t *op,
+ unsigned short red,
+ unsigned short green,
+ unsigned short blue,
+ unsigned short alpha);
+
+extern void __internal_linkage
+glitz_render_op_get_alpha_mask (glitz_render_op_t *op,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue,
+ unsigned short *alpha);
extern void __internal_linkage
-glitz_render_enable (glitz_render_type_t type,
- glitz_surface_t *src,
- glitz_surface_t *mask,
- glitz_surface_t *dst,
- glitz_texture_t *src_texture,
- glitz_texture_t *mask_texture,
- unsigned short opacity);
+glitz_render_enable (glitz_render_op_t *op);
extern void __internal_linkage
-glitz_render_disable (glitz_render_type_t type,
- glitz_surface_t *dst);
+glitz_render_disable (glitz_render_op_t *op);
+
+extern char *__internal_linkage
+glitz_pixel_buffer_bind (glitz_pixel_buffer_t *buffer,
+ glitz_gl_enum_t target);
+
+extern void __internal_linkage
+glitz_pixel_buffer_unbind (glitz_pixel_buffer_t *buffer);
+
#define MAXSHORT SHRT_MAX
#define MINSHORT SHRT_MIN
@@ -793,8 +840,9 @@ typedef glitz_fixed_16_16 glitz_fixed;
#define FIXED_TO_DOUBLE(f) (((double) (f)) / 65536)
#define DOUBLE_TO_FIXED(f) ((int) ((f) * 65536))
-#define SHORT_MODULATE(s1, s2) \
- ((unsigned short) (((unsigned int) s1 * s2) / 0xffff))
+#define SHORT_MULT(s1, s2) \
+ ((s1 == 0xffff)? s2: ((s2 == 0xffff)? s1: \
+ ((unsigned short) (((unsigned int) s1 * s2) / 0xffff))))
typedef void (*glitz_function_pointer_t) (void);
@@ -808,6 +856,7 @@ slim_hidden_proto(glitz_surface_create_radial)
slim_hidden_proto(glitz_surface_set_transform)
slim_hidden_proto(glitz_surface_set_convolution)
slim_hidden_proto(glitz_surface_set_repeat)
+slim_hidden_proto(glitz_surface_set_component_alpha)
slim_hidden_proto(glitz_surface_set_filter)
slim_hidden_proto(glitz_surface_set_polyedge)
slim_hidden_proto(glitz_surface_set_polyopacity)