Просмотр исходного кода

st/vega: Fix degenerate paints.

Fix the case that the two points of a linear gradient coincide, or the
case that the radius of a radial gradient is equal to or less than 0.
tags/android-x86-2.2
Chia-I Wu 14 лет назад
Родитель
Сommit
d7aa03b4fe

+ 15
- 1
src/gallium/state_trackers/vega/asm_fill.h Просмотреть файл

@@ -179,6 +179,18 @@ pattern( struct ureg_program *ureg,
ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, ureg_src(temp[1]), sampler[0]);
}

static INLINE void
paint_degenerate( struct ureg_program *ureg,
struct ureg_dst *out,
struct ureg_src *in,
struct ureg_src *sampler,
struct ureg_dst *temp,
struct ureg_src *constant)
{
ureg_MOV(ureg, temp[1], ureg_scalar(constant[3], TGSI_SWIZZLE_Y));
ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[1]), sampler[0]);
}

static INLINE void
color_transform( struct ureg_program *ureg,
struct ureg_dst *out,
@@ -436,7 +448,9 @@ static const struct shader_asm_info shaders_paint_asm[] = {
{VEGA_RADIAL_GRADIENT_SHADER, radial_grad,
VG_TRUE, 2, 5, 0, 1, 0, 6},
{VEGA_PATTERN_SHADER, pattern,
VG_TRUE, 3, 4, 0, 1, 0, 5}
VG_TRUE, 3, 4, 0, 1, 0, 5},
{VEGA_PAINT_DEGENERATE_SHADER, paint_degenerate,
VG_FALSE, 3, 1, 0, 1, 0, 2}
};

/* image draw modes */

+ 58
- 8
src/gallium/state_trackers/vega/paint.c Просмотреть файл

@@ -266,10 +266,13 @@ static INLINE void paint_linear_gradient_buffer(struct vg_paint *paint,
void *buffer)
{
VGfloat *map = (VGfloat*)buffer;
VGfloat dd;

map[0] = paint->gradient.linear.coords[2] - paint->gradient.linear.coords[0];
map[1] = paint->gradient.linear.coords[3] - paint->gradient.linear.coords[1];
map[2] = 1.f / (map[0] * map[0] + map[1] * map[1]);
dd = (map[0] * map[0] + map[1] * map[1]);

map[2] = (dd > 0.0f) ? 1.f / dd : 0.f;
map[3] = 1.f;

map[4] = 0.f;
@@ -298,14 +301,33 @@ static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint,
const struct matrix *inv,
void *buffer)
{
VGfloat *radialCoords = paint->gradient.radial.vals;

const VGfloat *center = &paint->gradient.radial.vals[0];
const VGfloat *focal = &paint->gradient.radial.vals[2];
VGfloat rr = paint->gradient.radial.vals[4];
VGfloat *map = (VGfloat*)buffer;
VGfloat dd, new_focal[2];

rr *= rr;

map[0] = center[0] - focal[0];
map[1] = center[1] - focal[1];
dd = map[0] * map[0] + map[1] * map[1];

/* focal point must lie inside the circle */
if (0.998f * rr < dd) {
VGfloat scale;

scale = (dd > 0.0f) ? sqrt(0.998f * rr / dd) : 0.0f;
map[0] *= scale;
map[1] *= scale;

map[0] = radialCoords[0] - radialCoords[2];
map[1] = radialCoords[1] - radialCoords[3];
map[2] = -map[0] * map[0] - map[1] * map[1] +
radialCoords[4] * radialCoords[4];
new_focal[0] = center[0] - map[0];
new_focal[1] = center[1] - map[1];
dd = map[0] * map[0] + map[1] * map[1];
focal = new_focal;
}

map[2] = (rr > dd) ? rr - dd : 1.0f;
map[3] = 1.f;

map[4] = 0.f;
@@ -316,7 +338,7 @@ static INLINE void paint_radial_gradient_buffer(struct vg_paint *paint,
{
struct matrix mat;
matrix_load_identity(&mat);
matrix_translate(&mat, -radialCoords[2], -radialCoords[3]);
matrix_translate(&mat, -focal[0], -focal[1]);
matrix_mult(&mat, inv);

map[8] = mat.m[0]; map[9] = mat.m[3]; map[10] = mat.m[6]; map[11] = 0.f;
@@ -654,6 +676,34 @@ void paint_resolve_type(struct vg_paint *paint)
}
}

VGboolean paint_is_degenerate(struct vg_paint *paint)
{
VGboolean degen;
VGfloat *vals;


switch (paint->type) {
case VG_PAINT_TYPE_LINEAR_GRADIENT:
vals = paint->gradient.linear.coords;
/* two points are coincident */
degen = (floatsEqual(vals[0], vals[2]) &&
floatsEqual(vals[1], vals[3]));
break;
case VG_PAINT_TYPE_RADIAL_GRADIENT:
vals = paint->gradient.radial.vals;
/* radius <= 0 */
degen = (vals[4] <= 0.0f);
break;
case VG_PAINT_TYPE_COLOR:
case VG_PAINT_TYPE_PATTERN:
default:
degen = VG_FALSE;
break;
}

return degen;
}

VGint paint_constant_buffer_size(struct vg_paint *paint)
{
switch(paint->type) {

+ 2
- 0
src/gallium/state_trackers/vega/paint.h Просмотреть файл

@@ -110,6 +110,8 @@ VGboolean paint_color_ramp_premultiplied(struct vg_paint *paint);
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
struct pipe_sampler_view **sampler_views);

VGboolean paint_is_degenerate(struct vg_paint *paint);

VGint paint_constant_buffer_size(struct vg_paint *paint);

void paint_fill_constant_buffer(struct vg_paint *paint,

+ 3
- 0
src/gallium/state_trackers/vega/shader.c Просмотреть файл

@@ -233,6 +233,9 @@ static void setup_shader_program(struct shader *shader)
default:
abort();
}

if (paint_is_degenerate(shader->paint))
shader_id = VEGA_PAINT_DEGENERATE_SHADER;
}

/* second stage image */

+ 1
- 0
src/gallium/state_trackers/vega/shaders_cache.c Просмотреть файл

@@ -261,6 +261,7 @@ create_shader(struct pipe_context *pipe,
case VEGA_LINEAR_GRADIENT_SHADER:
case VEGA_RADIAL_GRADIENT_SHADER:
case VEGA_PATTERN_SHADER:
case VEGA_PAINT_DEGENERATE_SHADER:
shaders[idx] = &shaders_paint_asm[(sh >> SHADERS_PAINT_SHIFT) - 1];
assert(shaders[idx]->id == sh);
idx++;

+ 1
- 0
src/gallium/state_trackers/vega/shaders_cache.h Просмотреть файл

@@ -65,6 +65,7 @@ enum VegaShaderType {
VEGA_LINEAR_GRADIENT_SHADER = 2 << SHADERS_PAINT_SHIFT,
VEGA_RADIAL_GRADIENT_SHADER = 3 << SHADERS_PAINT_SHIFT,
VEGA_PATTERN_SHADER = 4 << SHADERS_PAINT_SHIFT,
VEGA_PAINT_DEGENERATE_SHADER = 5 << SHADERS_PAINT_SHIFT,

VEGA_IMAGE_NORMAL_SHADER = 1 << SHADERS_IMAGE_SHIFT,
VEGA_IMAGE_MULTIPLY_SHADER = 2 << SHADERS_IMAGE_SHIFT,

Загрузка…
Отмена
Сохранить