Browse Source

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.
tags/android-x86-2.2
Chia-I Wu 15 years ago
parent
commit
b06de80843

+ 8
- 0
src/gallium/state_trackers/vega/image.c View File

@@ -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);


+ 1
- 1
src/gallium/state_trackers/vega/matrix.h View File

@@ -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];

+ 18
- 35
src/gallium/state_trackers/vega/paint.c View File

@@ -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:

+ 2
- 0
src/gallium/state_trackers/vega/paint.h View File

@@ -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);



+ 13
- 2
src/gallium/state_trackers/vega/path.c View File

@@ -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);
}

+ 20
- 1
src/gallium/state_trackers/vega/shader.c View File

@@ -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);
}

+ 3
- 0
src/gallium/state_trackers/vega/shader.h View File

@@ -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

+ 25
- 0
src/gallium/state_trackers/vega/vg_context.c View File

@@ -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;
}

+ 4
- 0
src/gallium/state_trackers/vega/vg_context.h View File

@@ -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)
{

Loading…
Cancel
Save