summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2004-04-30 02:26:02 +0000
committerDavid Reveman <davidr@novell.com>2004-04-30 02:26:02 +0000
commite9567a2848fa35a870f5bc18e3f5d11308fad5ec (patch)
tree60157ef31ac65aa46980ff02ff2b4020c2445d23
parent14b8f0268696e867ef1c87d174e0ab4c233e691b (diff)
Updated linear and radial surfaces
-rw-r--r--ChangeLog18
-rw-r--r--src/glitz.c6
-rw-r--r--src/glitz.h7
-rw-r--r--src/glitz_matrix.c31
-rw-r--r--src/glitz_program.c93
-rw-r--r--src/glitz_programmatic.c87
-rw-r--r--src/glitz_surface.c15
-rw-r--r--src/glitzint.h11
8 files changed, 189 insertions, 79 deletions
diff --git a/ChangeLog b/ChangeLog
index 1b4b65a..23aac59 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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, &region->x1, &region->y1);
_glitz_matrix_transform_distance (matrix, &region->x2, &region->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);