summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-12-01 02:30:59 +0800
committerChia-I Wu <[email protected]>2010-12-01 11:31:00 +0800
commitb06de80843e7d096bed4ae03ddc5e2842f1876af (patch)
tree37fd7f50f92ed6822282a64a9b47c32648120667 /src
parentca8bc9c05b2126e949425dc967923c27f62ef378 (diff)
st/vega: Fix paint coordinates transformations.
Depending on whether vgDrawPath(mode), vgDrawImage, or vgDrawGlyph[s] is called, different paint-to-user and user-to-surface matrices should be used to derive the sample points for the paint. This fixes "paint" demo.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/vega/image.c8
-rw-r--r--src/gallium/state_trackers/vega/matrix.h2
-rw-r--r--src/gallium/state_trackers/vega/paint.c53
-rw-r--r--src/gallium/state_trackers/vega/paint.h2
-rw-r--r--src/gallium/state_trackers/vega/path.c15
-rw-r--r--src/gallium/state_trackers/vega/shader.c21
-rw-r--r--src/gallium/state_trackers/vega/shader.h3
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c25
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h4
9 files changed, 94 insertions, 39 deletions
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index b1bda3ff54b..fc87536883a 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -523,11 +523,18 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy,
void image_draw(struct vg_image *img, struct matrix *matrix)
{
struct vg_context *ctx = vg_current_context();
+ struct matrix paint_matrix;
VGfloat x1, y1;
VGfloat x2, y2;
VGfloat x3, y3;
VGfloat x4, y4;
+ if (vg_get_paint_matrix(ctx,
+ &ctx->state.vg.fill_paint_to_user_matrix,
+ matrix,
+ &paint_matrix))
+ return;
+
x1 = 0;
y1 = 0;
x2 = img->width;
@@ -544,6 +551,7 @@ void image_draw(struct vg_image *img, struct matrix *matrix)
shader_set_drawing_image(ctx->shader, VG_TRUE);
shader_set_paint(ctx->shader, ctx->state.vg.fill_paint);
+ shader_set_paint_matrix(ctx->shader, &paint_matrix);
shader_set_image(ctx->shader, img);
shader_bind(ctx->shader);
diff --git a/src/gallium/state_trackers/vega/matrix.h b/src/gallium/state_trackers/vega/matrix.h
index 4c207f912a8..bed2b3193d0 100644
--- a/src/gallium/state_trackers/vega/matrix.h
+++ b/src/gallium/state_trackers/vega/matrix.h
@@ -129,7 +129,7 @@ static INLINE void matrix_make_affine(struct matrix *matrix)
}
static INLINE void matrix_mult(struct matrix *dst,
- struct matrix *src)
+ const struct matrix *src)
{
VGfloat m11 = dst->m[0]*src->m[0] + dst->m[3]*src->m[1] + dst->m[6]*src->m[2];
VGfloat m12 = dst->m[0]*src->m[3] + dst->m[3]*src->m[4] + dst->m[6]*src->m[5];
diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c
index c0c8cddabe9..467d3929754 100644
--- a/src/gallium/state_trackers/vega/paint.c
+++ b/src/gallium/state_trackers/vega/paint.c
@@ -261,9 +261,10 @@ static INLINE void paint_color_buffer(struct vg_paint *paint, void *buffer)
map[7] = 4.f;
}
-static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *buffer)
+static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint,
+ const struct matrix *inv,
+ void *buffer)
{
- struct vg_context *ctx = paint->base.ctx;
VGfloat *map = (VGfloat*)buffer;
map[0] = paint->gradient.linear.coords[2] - paint->gradient.linear.coords[0];
@@ -277,15 +278,10 @@ static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *bu
map[7] = 4.f;
{
struct matrix mat;
- struct matrix inv;
matrix_load_identity(&mat);
+ /* VEGA_LINEAR_GRADIENT_SHADER expects the first point to be at (0, 0) */
matrix_translate(&mat, -paint->gradient.linear.coords[0], -paint->gradient.linear.coords[1]);
- memcpy(&inv, &ctx->state.vg.fill_paint_to_user_matrix,
- sizeof(struct matrix));
- matrix_invert(&inv);
- matrix_mult(&inv, &mat);
- memcpy(&mat, &inv,
- sizeof(struct matrix));
+ matrix_mult(&mat, inv);
map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
@@ -298,10 +294,11 @@ static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint, void *bu
}
-static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *buffer)
+static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint,
+ const struct matrix *inv,
+ void *buffer)
{
VGfloat *radialCoords = paint->gradient.radial.vals;
- struct vg_context *ctx = paint->base.ctx;
VGfloat *map = (VGfloat*)buffer;
@@ -318,15 +315,9 @@ static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *bu
{
struct matrix mat;
- struct matrix inv;
matrix_load_identity(&mat);
matrix_translate(&mat, -radialCoords[2], -radialCoords[3]);
- memcpy(&inv, &ctx->state.vg.fill_paint_to_user_matrix,
- sizeof(struct matrix));
- matrix_invert(&inv);
- matrix_mult(&inv, &mat);
- memcpy(&mat, &inv,
- sizeof(struct matrix));
+ matrix_mult(&mat, inv);
map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
@@ -340,10 +331,10 @@ static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint, void *bu
}
-static INLINE void paint_pattern_buffer(struct vg_paint *paint, void *buffer)
+static INLINE void paint_pattern_buffer(struct vg_paint *paint,
+ const struct matrix *inv,
+ void *buffer)
{
- struct vg_context *ctx = paint->base.ctx;
-
VGfloat *map = (VGfloat *)buffer;
memcpy(map, paint->solid.color, 4 * sizeof(VGfloat));
@@ -353,17 +344,8 @@ static INLINE void paint_pattern_buffer(struct vg_paint *paint, void *buffer)
map[7] = paint->pattern.sampler_view->texture->height0;
{
struct matrix mat;
- memcpy(&mat, &ctx->state.vg.fill_paint_to_user_matrix,
- sizeof(struct matrix));
- matrix_invert(&mat);
- {
- struct matrix pm;
- memcpy(&pm, &ctx->state.vg.path_user_to_surface_matrix,
- sizeof(struct matrix));
- matrix_invert(&pm);
- matrix_mult(&pm, &mat);
- memcpy(&mat, &pm, sizeof(struct matrix));
- }
+
+ memcpy(&mat, inv, sizeof(*inv));
map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
map[12] = mat.m[1]; map[13] = mat.m[4]; map[14] = mat.m[7]; map[15] = 0.f;
@@ -695,6 +677,7 @@ VGint paint_constant_buffer_size(struct vg_paint *paint)
}
void paint_fill_constant_buffer(struct vg_paint *paint,
+ const struct matrix *mat,
void *buffer)
{
switch(paint->type) {
@@ -702,13 +685,13 @@ void paint_fill_constant_buffer(struct vg_paint *paint,
paint_color_buffer(paint, buffer);
break;
case VG_PAINT_TYPE_LINEAR_GRADIENT:
- paint_linear_gradient_buffer(paint, buffer);
+ paint_linear_gradient_buffer(paint, mat, buffer);
break;
case VG_PAINT_TYPE_RADIAL_GRADIENT:
- paint_radial_gradient_buffer(paint, buffer);
+ paint_radial_gradient_buffer(paint, mat, buffer);
break;
case VG_PAINT_TYPE_PATTERN:
- paint_pattern_buffer(paint, buffer);
+ paint_pattern_buffer(paint, mat, buffer);
break;
default:
diff --git a/src/gallium/state_trackers/vega/paint.h b/src/gallium/state_trackers/vega/paint.h
index 012cd3e5618..2e09b839a4a 100644
--- a/src/gallium/state_trackers/vega/paint.h
+++ b/src/gallium/state_trackers/vega/paint.h
@@ -111,7 +111,9 @@ VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **sa
struct pipe_sampler_view **sampler_views);
VGint paint_constant_buffer_size(struct vg_paint *paint);
+
void paint_fill_constant_buffer(struct vg_paint *paint,
+ const struct matrix *mat,
void *buffer);
diff --git a/src/gallium/state_trackers/vega/path.c b/src/gallium/state_trackers/vega/path.c
index 62eb62418d3..06c96a35502 100644
--- a/src/gallium/state_trackers/vega/path.c
+++ b/src/gallium/state_trackers/vega/path.c
@@ -1532,6 +1532,7 @@ void path_render(struct path *p, VGbitfield paintModes,
struct matrix *mat)
{
struct vg_context *ctx = vg_current_context();
+ struct matrix paint_matrix;
vg_validate_state(ctx);
@@ -1543,19 +1544,29 @@ void path_render(struct path *p, VGbitfield paintModes,
mat->m[3], mat->m[4], mat->m[5],
mat->m[6], mat->m[7], mat->m[8]);
#endif
- if (paintModes & VG_FILL_PATH) {
+ if ((paintModes & VG_FILL_PATH) &&
+ vg_get_paint_matrix(ctx,
+ &ctx->state.vg.fill_paint_to_user_matrix,
+ mat,
+ &paint_matrix)) {
/* First the fill */
shader_set_paint(ctx->shader, ctx->state.vg.fill_paint);
+ shader_set_paint_matrix(ctx->shader, &paint_matrix);
shader_bind(ctx->shader);
path_fill(p, mat);
}
- if (paintModes & VG_STROKE_PATH){
+ if ((paintModes & VG_STROKE_PATH) &&
+ vg_get_paint_matrix(ctx,
+ &ctx->state.vg.stroke_paint_to_user_matrix,
+ mat,
+ &paint_matrix)) {
/* 8.7.5: "line width less than or equal to 0 prevents stroking from
* taking place."*/
if (ctx->state.vg.stroke.line_width.f <= 0)
return;
shader_set_paint(ctx->shader, ctx->state.vg.stroke_paint);
+ shader_set_paint_matrix(ctx->shader, &paint_matrix);
shader_bind(ctx->shader);
path_stroke(p, mat);
}
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index 39c4bb0dfd6..a77587c6bff 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -50,6 +50,8 @@ struct shader {
struct vg_paint *paint;
struct vg_image *image;
+ struct matrix paint_matrix;
+
VGboolean drawing_image;
VGImageMode image_mode;
@@ -119,7 +121,8 @@ static VGint setup_constant_buffer(struct shader *shader)
memset(shader->constants, 0, sizeof(VGfloat) * 8);
}
- paint_fill_constant_buffer(shader->paint, shader->constants + 8);
+ paint_fill_constant_buffer(shader->paint,
+ &shader->paint_matrix, shader->constants + 8);
return param_bytes;
}
@@ -324,3 +327,19 @@ void shader_set_image(struct shader *shader, struct vg_image *img)
{
shader->image = img;
}
+
+/**
+ * Set the transformation to map a pixel to the paint coordinates.
+ */
+void shader_set_paint_matrix(struct shader *shader, const struct matrix *mat)
+{
+ const struct st_framebuffer *stfb = shader->context->draw_buffer;
+ const VGfloat px_center_offset = 0.5f;
+
+ memcpy(&shader->paint_matrix, mat, sizeof(*mat));
+
+ /* make it window-to-paint for the shaders */
+ matrix_translate(&shader->paint_matrix, px_center_offset,
+ stfb->height - 1.0f + px_center_offset);
+ matrix_scale(&shader->paint_matrix, 1.0f, -1.0f);
+}
diff --git a/src/gallium/state_trackers/vega/shader.h b/src/gallium/state_trackers/vega/shader.h
index f906631b50e..ff4466cd87c 100644
--- a/src/gallium/state_trackers/vega/shader.h
+++ b/src/gallium/state_trackers/vega/shader.h
@@ -33,6 +33,7 @@ struct shader;
struct vg_paint;
struct vg_context;
struct vg_image;
+struct matrix;
struct shader *shader_create(struct vg_context *context);
void shader_destroy(struct shader *shader);
@@ -53,6 +54,8 @@ VGboolean shader_drawing_image(struct shader *shader);
void shader_set_image(struct shader *shader, struct vg_image *img);
+void shader_set_paint_matrix(struct shader *shader, const struct matrix *mat);
+
void shader_bind(struct shader *shader);
#endif
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 4d088b965df..65adadd1fe9 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -509,3 +509,28 @@ void vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
if (dest_surface)
pipe_surface_reference(&dest_surface, NULL);
}
+
+/**
+ * A transformation from window coordinates to paint coordinates.
+ */
+VGboolean vg_get_paint_matrix(struct vg_context *ctx,
+ const struct matrix *paint_to_user,
+ const struct matrix *user_to_surface,
+ struct matrix *mat)
+{
+ struct matrix tmp;
+
+ /* get user-to-paint matrix */
+ memcpy(mat, paint_to_user, sizeof(*paint_to_user));
+ if (!matrix_invert(mat))
+ return VG_FALSE;
+
+ /* get surface-to-user matrix */
+ memcpy(&tmp, user_to_surface, sizeof(*user_to_surface));
+ if (!matrix_invert(&tmp))
+ return VG_FALSE;
+
+ matrix_mult(mat, &tmp);
+
+ return VG_TRUE;
+}
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index 07f3ca76beb..5d0bca33c52 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -162,6 +162,10 @@ void vg_set_error(struct vg_context *ctx,
void vg_prepare_blend_surface(struct vg_context *ctx);
void vg_prepare_blend_surface_from_mask(struct vg_context *ctx);
+VGboolean vg_get_paint_matrix(struct vg_context *ctx,
+ const struct matrix *paint_to_user,
+ const struct matrix *user_to_surface,
+ struct matrix *mat);
static INLINE VGboolean is_aligned_to(const void *ptr, VGbyte alignment)
{