From b24c5e70da7fac70ab52bc3c4a81cb731d29c666 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sun, 5 Nov 2006 12:51:23 +0000 Subject: [PATCH] massively improve xrender scaling to be almost perfect. a few nigglies remain though with transformed images (especailly with border scaling) SVN revision: 26965 --- .../src/modules/engines/xrender_x11/evas_engine.h | 4 +- .../engines/xrender_x11/evas_engine_image.c | 53 +++++++++------ .../engines/xrender_x11/evas_engine_xrender.c | 76 +++++++++++----------- 3 files changed, 73 insertions(+), 60 deletions(-) diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.h b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.h index 28d1e8d..4d3b0b8 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine.h +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine.h @@ -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); diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c index 18cf4e9..c18eb82 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_image.c @@ -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->w + 1, 1, + 1, im->h); _xr_render_surface_copy(im->surface, im->surface, - im->w - 1, im->h - 1, - im->w, im->h, - 1, 1); + 0, im->h, + 0, im->h + 1, + im->w + 2, 1); if ((im->im) && (!im->dirty)) { evas_common_image_unref(im->im); diff --git a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_xrender.c b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_xrender.c index 271967a..d6bba68 100644 --- a/legacy/evas/src/modules/engines/xrender_x11/evas_engine_xrender.c +++ b/legacy/evas/src/modules/engines/xrender_x11/evas_engine_xrender.c @@ -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); } } } -- 2.7.4