massively improve xrender scaling to be almost perfect. a few nigglies remain

though with transformed images (especailly with border scaling)


SVN revision: 26965
This commit is contained in:
Carsten Haitzler 2006-11-05 12:51:23 +00:00
parent bcd4e797d6
commit b24c5e70da
3 changed files with 73 additions and 60 deletions

View File

@ -73,8 +73,8 @@ Xrender_Surface *_xr_render_surface_format_adopt(Ximage_Info *xinf, Drawable dra
void _xr_render_surface_free(Xrender_Surface *rs);
void _xr_render_surface_repeat_set(Xrender_Surface *rs, int repeat);
void _xr_render_surface_solid_rectangle_set(Xrender_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h);
void _xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h);
void _xr_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h);
void _xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy);
void _xr_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy);
void _xr_render_surface_clips_set(Xrender_Surface *rs, RGBA_Draw_Context *dc, int rx, int ry, int rw, int rh);
void _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Draw_Context *dc, int sx, int sy, int sw, int sh, int x, int y, int w, int h, int smooth);
void _xr_render_surface_copy(Xrender_Surface *srs, Xrender_Surface *drs, int sx, int sy, int x, int y, int w, int h);

View File

@ -281,6 +281,7 @@ _xre_image_copy(XR_Image *im)
void
_xre_image_resize(XR_Image *im, int w, int h)
{
/* FIXME: ... */
if ((w == im->w) && (h == im->h)) return;
if (im->surface)
{
@ -290,10 +291,18 @@ _xre_image_resize(XR_Image *im, int w, int h)
ww = w; hh = h;
RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h);
old_surface = im->surface;
im->surface = _xr_render_surface_new(old_surface->xinf, w + 1, h + 1, old_surface->fmt, old_surface->alpha);
im->surface = _xr_render_surface_new(old_surface->xinf, w + 2, h + 2, old_surface->fmt, old_surface->alpha);
if (im->surface)
_xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, ww, hh);
_xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, ww + 1, hh + 1);
_xr_render_surface_free(old_surface);
_xr_render_surface_copy(im->surface, im->surface,
ww, 1,
ww + 1, 1,
1, hh);
_xr_render_surface_copy(im->surface, im->surface,
0, hh,
0, hh + 1,
ww + 2, 1);
}
if (im->data)
{
@ -462,11 +471,11 @@ _xre_image_alpha_set(XR_Image *im, int alpha)
old_surface = im->surface;
im->surface = NULL;
if (im->alpha)
im->surface = _xr_render_surface_new(im->xinf, im->w + 1, im->h + 1, im->xinf->fmt32, 1);
im->surface = _xr_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->fmt32, 1);
else
im->surface = _xr_render_surface_new(im->xinf, im->w + 1, im->h + 1, im->xinf->fmt24, 0);
im->surface = _xr_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->fmt24, 0);
if (im->surface)
_xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, im->w + 1, im->h + 1);
_xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, im->w + 2, im->h + 2);
_xr_render_surface_free(old_surface);
}
if (im->updates)
@ -538,9 +547,9 @@ _xre_image_surface_gen(XR_Image *im)
rx = r->x; ry = r->y; rw = r->w, rh = r->h;
RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, im->w, im->h);
if (im->alpha)
_xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh);
_xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh, 1, 1);
else
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh);
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh, 1, 1);
}
evas_common_tilebuf_free_render_rects(rects);
}
@ -551,27 +560,31 @@ _xre_image_surface_gen(XR_Image *im)
}
if (im->alpha)
{
im->surface = _xr_render_surface_new(im->xinf, im->w + 1, im->h + 1, im->xinf->fmt32, 1);
_xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h);
im->surface = _xr_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->fmt32, 1);
_xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h, 1, 1);
}
else
{
im->surface = _xr_render_surface_new(im->xinf, im->w + 1, im->h + 1, im->xinf->fmt24, 0);
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h);
im->surface = _xr_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->fmt24, 0);
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h, 1, 1);
}
/* fill right and bottom pixel so interpolation works right */
/* fill borders */
_xr_render_surface_copy(im->surface, im->surface,
im->w - 1, 0,
im->w, 0,
1, 1,
0, 1,
1, im->h);
_xr_render_surface_copy(im->surface, im->surface,
0, im->h - 1,
0, im->h,
im->w, 1);
0, 1,
0, 0,
im->w + 2, 1);
_xr_render_surface_copy(im->surface, im->surface,
im->w - 1, im->h - 1,
im->w, im->h,
1, 1);
im->w, 1,
im->w + 1, 1,
1, im->h);
_xr_render_surface_copy(im->surface, im->surface,
0, im->h,
0, im->h + 1,
im->w + 2, 1);
if ((im->im) && (!im->dirty))
{
evas_common_image_unref(im->im);

View File

@ -165,7 +165,7 @@ _xr_render_surface_solid_rectangle_set(Xrender_Surface *rs, int r, int g, int b,
}
void
_xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h)
_xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy)
{
Ximage_Image *xim;
unsigned int *p, *sp, *sple, *spe;
@ -209,11 +209,11 @@ _xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *p
sp += sjump;
}
}
_xr_image_put(xim, rs->draw, x, y, w, h);
_xr_image_put(xim, rs->draw, x + ox, y + oy, w, h);
}
void
_xr_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h)
_xr_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy)
{
Ximage_Image *xim;
unsigned int *p, *sp, *sple, *spe;
@ -257,7 +257,7 @@ _xr_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pi
sp += sjump;
}
}
_xr_image_put(xim, rs->draw, x, y, w, h);
_xr_image_put(xim, rs->draw, x + ox, y + oy, w, h);
}
void
@ -318,14 +318,16 @@ init_xtransform(XTransform *t)
}
static void
set_xtransform_scale(XTransform *t, int sw, int sh, int w, int h)
set_xtransform_scale(XTransform *t, int sw, int sh, int w, int h, int tx, int ty)
{
// if ((sw > 1) && (w > 1))
// { sw--; w--; }
// if ((sh > 1) && (h > 1))
// { sh--; h--; }
t->matrix[0][0] = XDoubleToFixed((double)sw / (double)w);
t->matrix[1][1] = XDoubleToFixed((double)sh / (double)h);
t->matrix[0][0] = XDoubleToFixed((double)(sw) / (double)(w));
t->matrix[1][1] = XDoubleToFixed((double)(sh) / (double)(h));
t->matrix[2][0] = tx;
t->matrix[2][1] = ty;
}
// when color multiplier is used want: instead
@ -397,10 +399,10 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr
else
{
if ((srs->alpha) || (a != 0xff))
trs = _xr_render_surface_new(srs->xinf, sw + e, sh + e,
trs = _xr_render_surface_new(srs->xinf, sw + 2, sh + 2,
srs->xinf->fmt32, 1);
else
trs = _xr_render_surface_new(srs->xinf, sw + e, sh + e,
trs = _xr_render_surface_new(srs->xinf, sw + 2, sh + 2,
srs->fmt, srs->alpha);
if (!trs) return;
@ -408,63 +410,56 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr
XRenderChangePicture(srs->xinf->disp, mask, CPComponentAlpha, &att);
XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf);
XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, mask,
trs->pic, sx, sy, 0, 0, 0, 0, sw, sh);
/* fill right and bottom pixel so interpolation works right */
if (e)
{
XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, mask,
trs->pic, sx + sw - 1, sy, 0, 0, sw, 0, 1, sh);
XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, mask,
trs->pic, sx, sy + sh - 1, 0, 0, 0, sh, sw, 1);
XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, mask,
trs->pic, sx + sw - 1, sy + sh - 1, 0, 0, sw, sh, 1, 1);
}
trs->pic,
sx, sy,
sx, sy,
0, 0, sw + 2, sh + 2);
mask = None;
}
}
}
//#define HFW + (sw / 2)
//#define HFH + (sh / 2)
#define HFW
#define HFH
_xr_render_surface_clips_set(drs, dc, x, y, w, h);
if (trs)
{
XRenderSetPictureFilter(trs->xinf->disp, trs->pic, get_filter(smooth), NULL, 0);
set_xtransform_scale(&xf, sw, sh, w, h);
set_xtransform_scale(&xf, sw, sh, w, h, -1, -1);
XRenderSetPictureTransform(trs->xinf->disp, trs->pic, &xf);
att.component_alpha = 0;
if (dc->render_op == _EVAS_RENDER_MUL)
att.component_alpha = 1;
if (dc->render_op == _EVAS_RENDER_MUL) att.component_alpha = 1;
XRenderChangePicture(trs->xinf->disp, trs->pic, CPComponentAlpha, &att);
XRenderComposite(trs->xinf->disp, op, trs->pic, mask, drs->pic,
0, 0, 0, 0, x, y, w, h);
(w HFW) / sw, (h HFH) / sh,
(w HFW) / sw, (h HFH) / sh,
x, y, w, h);
_xr_render_surface_free(trs);
}
else
{
if (srs->bordered && is_scaling)
{
trs = _xr_render_surface_new(srs->xinf, sw + 1, sh + 1,
trs = _xr_render_surface_new(srs->xinf, sw + 2, sh + 2,
srs->fmt, srs->alpha);
if (!trs) return;
att.component_alpha = 0;
XRenderChangePicture(srs->xinf->disp, srs->pic, CPComponentAlpha, &att);
XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf);
XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None,
trs->pic, sx, sy, 0, 0, 0, 0, sw, sh);
XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None,
trs->pic, sx + sw - 1, sy, 0, 0, sw, 0, 1, sh);
XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None,
trs->pic, sx, sy + sh - 1, 0, 0, 0, sh, sw, 1);
XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None,
trs->pic, sx + sw - 1, sy + sh - 1, 0, 0, sw, sh, 1, 1);
trs->pic, sx, sy, sx, sy, 0, 0, sw + 2, sh + 2);
XRenderSetPictureFilter(trs->xinf->disp, trs->pic, get_filter(smooth), NULL, 0);
set_xtransform_scale(&xf, sw, sh, w, h);
set_xtransform_scale(&xf, sw, sh, w, h, -1, -1);
XRenderSetPictureTransform(trs->xinf->disp, trs->pic, &xf);
if (dc->render_op == _EVAS_RENDER_MUL)
@ -474,14 +469,17 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr
}
XRenderComposite(trs->xinf->disp, op, trs->pic, mask, drs->pic,
0, 0, 0, 0, x, y, w, h);
(w HFW) / sw, (h HFH) / sh,
(w HFW) / sw, (h HFH) / sh,
// 1, 1, 1, 1,
x, y, w, h);
_xr_render_surface_free(trs);
}
else
{
XRenderSetPictureFilter(srs->xinf->disp, srs->pic, get_filter(smooth), NULL, 0);
set_xtransform_scale(&xf, sw, sh, w, h);
set_xtransform_scale(&xf, sw, sh, w, h, 0, 0);
XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf);
att.component_alpha = 0;
@ -490,9 +488,11 @@ _xr_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Dr
XRenderChangePicture(srs->xinf->disp, srs->pic, CPComponentAlpha, &att);
XRenderComposite(srs->xinf->disp, op, srs->pic, mask, drs->pic,
((sx * w) + (sw / 2)) / sw,
((sy * h) + (sh / 2)) / sh,
0, 0, x, y, w, h);
((((sx + 1) * w) HFW) / sw),
((((sy + 1) * h) HFH) / sh),
((((sx + 1) * w) HFW) / sw),
((((sy + 1) * h) HFH) / sh),
x, y, w, h);
}
}
}