diff options
author | David Reveman <davidr@novell.com> | 2004-04-30 02:26:02 +0000 |
---|---|---|
committer | David Reveman <davidr@novell.com> | 2004-04-30 02:26:02 +0000 |
commit | e9567a2848fa35a870f5bc18e3f5d11308fad5ec (patch) | |
tree | 60157ef31ac65aa46980ff02ff2b4020c2445d23 | |
parent | 14b8f0268696e867ef1c87d174e0ab4c233e691b (diff) |
Updated linear and radial surfaces
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | src/glitz.c | 6 | ||||
-rw-r--r-- | src/glitz.h | 7 | ||||
-rw-r--r-- | src/glitz_matrix.c | 31 | ||||
-rw-r--r-- | src/glitz_program.c | 93 | ||||
-rw-r--r-- | src/glitz_programmatic.c | 87 | ||||
-rw-r--r-- | src/glitz_surface.c | 15 | ||||
-rw-r--r-- | src/glitzint.h | 11 |
8 files changed, 189 insertions, 79 deletions
@@ -1,3 +1,21 @@ +2004-04-30 David Reveman <c99drn@cs.umu.se> + + * src/glitzint.h: Updated linear and radial surfaces. + + * src/glitz_surface.c: Updated linear and radial surfaces. + + * src/glitz_programmatic.c: Updated linear and radial surfaces. + + * src/glitz_program.c: Updated linear and radial surfaces. + + * src/glitz_matrix.c: Fixed indentation. + + * src/glitz.h: Removed glitz_distance_fixed_t. Updated linear + and radial surfaces. + + * src/glitz.c (_glitz_composite_direct): Fixed rare source/mask + offset bug. + 2004-04-28 David Reveman <c99drn@cs.umu.se> * src/glitzint.h: Added internal_format to glitz_texture_t. Added diff --git a/src/glitz.c b/src/glitz.c index 4e29691..7167d80 100644 --- a/src/glitz.c +++ b/src/glitz.c @@ -209,6 +209,9 @@ _glitz_composite_direct (glitz_operator_t op, } else { glitz_intersect_sub_pixel_region (&src_region, &dst_region, &src_region); + if (x_src < 0) x_src = 0; + if (y_src < 0) y_src = 0; + src_region.x2 = x_src + (src_region.x2 - src_region.x1) - translate_src.x; src_region.y2 = y_src + (src_region.y2 - src_region.y1) - translate_src.y; src_region.x1 = x_src - translate_src.x; @@ -225,6 +228,9 @@ _glitz_composite_direct (glitz_operator_t op, mask_region.x2 = (dst_region.x2 - dst_region.x1) + mask_region.x1; } else { glitz_intersect_sub_pixel_region (&mask_region, &dst_region, &mask_region); + + if (x_mask < 0) x_mask = 0; + if (y_mask < 0) y_mask = 0; mask_region.x2 = x_mask + (mask_region.x2 - mask_region.x1) - translate_mask.x; diff --git a/src/glitz.h b/src/glitz.h index 2a65487..2dbbcf1 100644 --- a/src/glitz.h +++ b/src/glitz.h @@ -55,10 +55,6 @@ typedef struct _glitz_point_fixed_t { glitz_fixed16_16_t x, y; } glitz_point_fixed_t; -typedef struct _glitz_distance_fixed_t { - glitz_fixed16_16_t dx, dy; -} glitz_distance_fixed_t; - typedef struct _glitz_line_fixed_t { glitz_point_fixed_t p1, p2; } glitz_line_fixed_t; @@ -277,7 +273,8 @@ glitz_surface_create_linear (glitz_point_fixed_t *start, glitz_surface_t * glitz_surface_create_radial (glitz_point_fixed_t *center, - glitz_distance_fixed_t *radius, + glitz_fixed16_16_t radius0, + glitz_fixed16_16_t radius1, glitz_color_range_t *color_range); void diff --git a/src/glitz_matrix.c b/src/glitz_matrix.c index b4f4d40..8855fcf 100644 --- a/src/glitz_matrix.c +++ b/src/glitz_matrix.c @@ -35,8 +35,8 @@ static void _glitz_matrix_transform_distance (glitz_matrix_t *matrix, - double *dx, - double *dy) + double *dx, + double *dy) { double new_x, new_y; @@ -49,7 +49,7 @@ _glitz_matrix_transform_distance (glitz_matrix_t *matrix, void glitz_matrix_transform_point (glitz_matrix_t *matrix, - glitz_point_t *point) + glitz_point_t *point) { _glitz_matrix_transform_distance (matrix, &point->x, &point->y); @@ -59,7 +59,7 @@ glitz_matrix_transform_point (glitz_matrix_t *matrix, void glitz_matrix_transform_region (glitz_matrix_t *matrix, - glitz_region_box_t *region) + glitz_region_box_t *region) { glitz_point_t point; @@ -83,7 +83,7 @@ glitz_matrix_transform_region (glitz_matrix_t *matrix, void glitz_matrix_transform_sub_pixel_region (glitz_matrix_t *matrix, - glitz_sub_pixel_region_box_t *region) + glitz_sub_pixel_region_box_t *region) { _glitz_matrix_transform_distance (matrix, ®ion->x1, ®ion->y1); _glitz_matrix_transform_distance (matrix, ®ion->x2, ®ion->y2); @@ -96,9 +96,9 @@ glitz_matrix_transform_sub_pixel_region (glitz_matrix_t *matrix, static void _glitz_matrix_set_affine (glitz_matrix_t *matrix, - double a, double b, - double c, double d, - double tx, double ty) + double a, double b, + double c, double d, + double tx, double ty) { matrix->m[0][0] = a; matrix->m[0][1] = b; matrix->m[1][0] = c; matrix->m[1][1] = d; @@ -107,7 +107,7 @@ _glitz_matrix_set_affine (glitz_matrix_t *matrix, static void _glitz_matrix_scalar_multiply (glitz_matrix_t *matrix, - double scalar) + double scalar) { int row, col; @@ -131,14 +131,14 @@ _glitz_matrix_compute_adjoint (glitz_matrix_t *matrix) tx = matrix->m[2][0]; ty = matrix->m[2][1]; _glitz_matrix_set_affine (matrix, - d, -b, - -c, a, - c * ty - d * tx, b * tx - a * ty); + d, -b, + -c, a, + c * ty - d * tx, b * tx - a * ty); } static void _glitz_matrix_compute_determinant (glitz_matrix_t *matrix, - double *det) + double *det) { double a, b, c, d; @@ -167,14 +167,13 @@ glitz_matrix_invert (glitz_matrix_t *matrix) void glitz_matrix_translate (glitz_matrix_t *matrix, - double tx, - double ty) + double tx, + double ty) { matrix->m[2][0] += tx; matrix->m[2][1] += ty; } - /* This function is only used for convolution kernel normalization. I'm not sure that it does the right thing when kernel contains negative values or when the sum equals zero. */ diff --git a/src/glitz_program.c b/src/glitz_program.c index c6a6d71..e88a742 100644 --- a/src/glitz_program.c +++ b/src/glitz_program.c @@ -260,26 +260,55 @@ char *_glitz_fragment_program_programmatic[] = { /* * Linear gradient using 1D texture as color range. - * Texture unit 2 is 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" - - "MUL position.x, gradient.z, pos.x;\n" - "MAD position.x, gradient.w, pos.y, position.x;\n" + + /* flip Y position */ + "SUB position.y, translate.z, pos.y;\n" + + /* 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" + + /* 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" + + /* calculate gradient offset */ + "MUL position.x, gradient.z, position.x;\n" + "MAD position.x, gradient.w, position.y, position.x;\n" "SUB distance.x, position.x, gradient.x;\n" "MUL distance.x, distance.x, gradient.y;\n" @@ -293,29 +322,54 @@ char *_glitz_fragment_program_programmatic[] = { /* * Radial gradient using 1D texture as color range. - * Texture unit 2 is 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 * - * param[0].x = center point X coordinate - * param[0].y = center point Y coordinate - * param[1].x = MIN (radius_x, radius_y) / radius_x - * param[1].y = MIN (radius_x, radius_y) / radius_y - * param[1].z = 0 - * param[1].x = 1 / MIN (radius_x, radius_y) + * 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 length = program.local[1];\n" - "ATTRIB position = fragment.texcoord[%d];\n" - "TEMP color, distance;\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" + + /* 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" + + /* 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" + + /* calculate gradient offset */ "SUB distance, position, gradient;\n" - "MUL distance, distance, length;\n" "DP3 distance.x, distance, distance;\n" "RSQ distance.w, distance.x;\n" @@ -323,8 +377,9 @@ char *_glitz_fragment_program_programmatic[] = { "RCP distance.x, distance.w;\n" "MUL distance.x, distance.x, distance.x;\n" "MUL distance.x, distance.x, distance.w;\n" - - "MUL distance.x, distance.x, length.w;\n" + + "SUB distance.x, distance.x, gradient.w;\n" + "MUL distance.x, distance.x, gradient.z;\n" "TEX color, distance, texture[2], 1D;\n" diff --git a/src/glitz_programmatic.c b/src/glitz_programmatic.c index fe7f1ce..7565241 100644 --- a/src/glitz_programmatic.c +++ b/src/glitz_programmatic.c @@ -108,6 +108,13 @@ glitz_programmatic_surface_backend = { glitz_programmatic_surface_t * _glitz_programmatic_surface_create (void) { + static const glitz_matrix_t identity = { + { + { 1.0, 0.0, 0.0 }, + { 0.0, 1.0, 0.0 }, + { 0.0, 0.0, 1.0 } + } + }; glitz_programmatic_surface_t *surface; surface = (glitz_programmatic_surface_t *) @@ -126,6 +133,7 @@ _glitz_programmatic_surface_create (void) surface->texture.texcoord_width = surface->texture.texcoord_height = 1.0; surface->texture.repeatable = surface->texture.repeat = 1; + surface->transform = identity; return surface; } @@ -181,7 +189,8 @@ glitz_programmatic_surface_create_linear (glitz_point_fixed_t *start, glitz_surface_t * glitz_programmatic_surface_create_radial (glitz_point_fixed_t *start, - glitz_distance_fixed_t *radius, + glitz_fixed16_16_t radius0, + glitz_fixed16_16_t radius1, glitz_color_range_t *color_range) { glitz_programmatic_surface_t *surface; @@ -192,7 +201,8 @@ glitz_programmatic_surface_create_radial (glitz_point_fixed_t *start, surface->type = GLITZ_PROGRAMMATIC_SURFACE_RADIAL_TYPE; surface->u.radial.center = *start; - surface->u.radial.radius = *radius; + surface->u.radial.radius0 = radius0; + surface->u.radial.radius1 = radius1; surface->u.radial.color_range = color_range; glitz_color_range_reference (color_range); @@ -200,6 +210,22 @@ glitz_programmatic_surface_create_radial (glitz_point_fixed_t *start, } void +glitz_programmatic_surface_set_transform (glitz_surface_t *abstract_surface, + glitz_transform_t *transform) +{ + glitz_programmatic_surface_t *surface = + (glitz_programmatic_surface_t *) abstract_surface; + + surface->transform.m[0][0] = FIXED_TO_DOUBLE (transform->matrix[0][0]); + surface->transform.m[1][0] = FIXED_TO_DOUBLE (transform->matrix[0][1]); + surface->transform.m[2][0] = FIXED_TO_DOUBLE (transform->matrix[0][2]); + + surface->transform.m[0][1] = FIXED_TO_DOUBLE (transform->matrix[1][0]); + surface->transform.m[1][1] = FIXED_TO_DOUBLE (transform->matrix[1][1]); + surface->transform.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) @@ -216,12 +242,9 @@ glitz_programmatic_surface_bind (glitz_gl_proc_address_list_t *gl, double length, angle, start; p1.x = FIXED_TO_DOUBLE (surface->u.linear.start.x); - p1.y = surface->base.height - - FIXED_TO_DOUBLE (surface->u.linear.start.y); - + p1.y = FIXED_TO_DOUBLE (surface->u.linear.start.y); p2.x = FIXED_TO_DOUBLE (surface->u.linear.stop.x); - p2.y = surface->base.height - - FIXED_TO_DOUBLE (surface->u.linear.stop.y); + 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)); @@ -236,41 +259,41 @@ glitz_programmatic_surface_bind (glitz_gl_proc_address_list_t *gl, (length)? 1.0 / length: INT_MAX, cos (angle), -sin (angle)); + gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 1, + surface->transform.m[0][0], + surface->transform.m[0][1], + surface->transform.m[1][0], + surface->transform.m[1][1]); + gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 2, + surface->transform.m[2][0], + surface->transform.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: { - double radius_x, radius_y; - double length; - - radius_x = FIXED_TO_DOUBLE (surface->u.radial.radius.dx); - radius_y = FIXED_TO_DOUBLE (surface->u.radial.radius.dy); - - length = fabs (MIN (radius_x, radius_y)); - - /* ugly */ - if (length == 0.0) - length = 0.000001; - - gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 0, - FIXED_TO_DOUBLE - (surface->u.radial.center.x), - surface->base.height - - FIXED_TO_DOUBLE - (surface->u.radial.center.y), - 0.0, 0.0); + 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, - length / radius_x, - length / radius_y, - 0.0, - 1.0 / length); + surface->transform.m[0][0], + surface->transform.m[0][1], + surface->transform.m[1][0], + surface->transform.m[1][1]); + gl->program_local_param_4d_arb (GLITZ_GL_FRAGMENT_PROGRAM_ARB, 2, + surface->transform.m[2][0], + surface->transform.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_surface.c b/src/glitz_surface.c index 2974201..3bc6506 100644 --- a/src/glitz_surface.c +++ b/src/glitz_surface.c @@ -104,11 +104,14 @@ slim_hidden_def(glitz_surface_create_linear); glitz_surface_t * glitz_surface_create_radial (glitz_point_fixed_t *center, - glitz_distance_fixed_t *radius, + glitz_fixed16_16_t radius0, + glitz_fixed16_16_t radius1, glitz_color_range_t *color_range) { return - glitz_programmatic_surface_create_radial (center, radius, color_range); + glitz_programmatic_surface_create_radial (center, + radius0, radius1, + color_range); } slim_hidden_def(glitz_surface_create_radial); @@ -243,8 +246,10 @@ glitz_surface_set_transform (glitz_surface_t *surface, } }; - if (SURFACE_PROGRAMMATIC (surface)) + if (SURFACE_PROGRAMMATIC (surface)) { + glitz_programmatic_surface_set_transform (surface, transform); return; + } if (transform && memcmp (transform, &identity, sizeof (glitz_transform_t)) == 0) @@ -254,8 +259,8 @@ glitz_surface_set_transform (glitz_surface_t *surface, if (!surface->transform) { glitz_surface_push_transform (surface); if (!surface->transform) - return; - } + return; + } surface->transform->m[0][0] = FIXED_TO_DOUBLE (transform->matrix[0][0]); surface->transform->m[1][0] = FIXED_TO_DOUBLE (transform->matrix[0][1]); diff --git a/src/glitzint.h b/src/glitzint.h index 835593f..1000588 100644 --- a/src/glitzint.h +++ b/src/glitzint.h @@ -333,6 +333,7 @@ typedef struct _glitz_programmatic_surface_t { glitz_surface_t base; glitz_texture_t texture; + glitz_matrix_t transform; glitz_programmatic_surface_type_t type; union { @@ -346,7 +347,8 @@ typedef struct _glitz_programmatic_surface_t { } linear; struct { glitz_point_fixed_t center; - glitz_distance_fixed_t radius; + glitz_fixed16_16_t radius0; + glitz_fixed16_16_t radius1; glitz_color_range_t *color_range; } radial; } u; @@ -613,10 +615,15 @@ glitz_programmatic_surface_create_linear (glitz_point_fixed_t *start, extern glitz_surface_t *__internal_linkage glitz_programmatic_surface_create_radial (glitz_point_fixed_t *start, - glitz_distance_fixed_t *radius, + glitz_fixed16_16_t radius0, + glitz_fixed16_16_t radius1, glitz_color_range_t *color_range); extern void __internal_linkage +glitz_programmatic_surface_set_transform (glitz_surface_t *surface, + glitz_transform_t *transform); + +extern void __internal_linkage glitz_color_range_bind (glitz_gl_proc_address_list_t *gl, glitz_color_range_t *color_range, unsigned long feature_mask); |