diff options
author | Zhigang Gong <zhigang.gong@linux.intel.com> | 2012-06-11 09:36:56 +0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2013-12-18 11:23:51 -0800 |
commit | 1d2d858b8daacdd349084433a8af60d559fb6a9d (patch) | |
tree | 04d73eebd93ea5d26cf60e1190b5911fb245abab /glamor/glamor_utils.h | |
parent | 48916a23a92366128f5a1eeb08949d8d32383c32 (diff) |
largepixmap: Add transform/repeat/reflect/pad support.
This commit implement almost all the needed functions for
the large pixmap support. It's almost complete.
Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>
Diffstat (limited to 'glamor/glamor_utils.h')
-rw-r--r-- | glamor/glamor_utils.h | 229 |
1 files changed, 216 insertions, 13 deletions
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h index 44c8175ae..18f7f3b10 100644 --- a/glamor/glamor_utils.h +++ b/glamor/glamor_utils.h @@ -39,13 +39,13 @@ #define t_from_x_coord_y(_yscale_, _y_) (1.0 - (_y_) * (_yscale_)) #define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_)) -#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_) \ - do { \ - int w,h; \ - PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, w, h); \ - *(_pxscale_) = 1.0 / w; \ - *(_pyscale_) = 1.0 / h; \ - } while(0) +#define pixmap_priv_get_dest_scale(_pixmap_priv_, _pxscale_, _pyscale_)\ + do { \ + int w,h; \ + PIXMAP_PRIV_GET_ACTUAL_SIZE(_pixmap_priv_, w, h); \ + *(_pxscale_) = 1.0 / w; \ + *(_pyscale_) = 1.0 / h; \ + } while(0) #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \ do { \ @@ -108,24 +108,175 @@ } \ } while(0) +#define fmod(x, w) (x - w * floor((float)x/w)) + +#define fmodulus(x, w, c) do {c = fmod(x, w); \ + c = c >= 0 ? c : c + w;} \ + while(0) +/* @x: is current coord + * @x2: is the right/bottom edge + * @w: is current width or height + * @odd: is output value, 0 means we are in an even region, 1 means we are in a + * odd region. + * @c: is output value, equal to x mod w. */ +#define fodd_repeat_mod(x, x2, w, odd, c) \ + do { \ + float shift; \ + fmodulus((x), w, c); \ + shift = fabs((x) - (c)); \ + shift = floor(fabs(round(shift)) / w); \ + odd = (int)shift & 1; \ + if (odd && (((x2 % w) == 0) && \ + round(fabs(x)) == x2)) \ + odd = 0; \ + } while(0) + +/* @txy: output value, is the corrected coords. + * @xy: input coords to be fixed up. + * @cd: xy mod wh, is a input value. + * @wh: current width or height. + * @bxy1,bxy2: current box edge's x1/x2 or y1/y2 + * + * case 1: + * ---------- + * | * | + * | | + * ---------- + * tx = (c - x1) mod w + * + * case 2: + * --------- + * * | | + * | | + * --------- + * tx = - (c - (x1 mod w)) + * + * case 3: + * + * ---------- + * | | * + * | | + * ---------- + * tx = ((x2 mod x) - c) + (x2 - x1) + **/ +#define __glamor_repeat_reflect_fixup(txy, xy, \ + cd, wh, bxy1, bxy2) \ + do { \ + cd = wh - cd; \ + if ( xy >= bxy1 && xy < bxy2) { \ + cd = cd - bxy1; \ + fmodulus(cd, wh, txy); \ + } else if (xy < bxy1) { \ + float bxy1_mod; \ + fmodulus(bxy1, wh, bxy1_mod); \ + txy = -(cd - bxy1_mod); \ + } \ + else if (xy >= bxy2) { \ + float bxy2_mod; \ + fmodulus(bxy2, wh, bxy2_mod); \ + if (bxy2_mod == 0) \ + bxy2_mod = wh; \ + txy = (bxy2_mod - cd) + bxy2 - bxy1; \ + } else {assert(0); txy = 0;} \ + } while(0) + +#define _glamor_repeat_reflect_fixup(txy, xy, cd, odd, \ + wh, bxy1, bxy2) \ + do { \ + if (odd) { \ + __glamor_repeat_reflect_fixup(txy, xy, \ + cd, wh, bxy1, bxy2); \ + } else \ + txy = xy - bxy1; \ + } while(0) + +#define _glamor_get_reflect_transform_coords(priv, repeat_type, \ + tx1, ty1, \ + _x1_, _y1_) \ + do { \ + int odd_x, odd_y; \ + float c, d; \ + fodd_repeat_mod(_x1_,priv->box.x2, \ + priv->base.pixmap->drawable.width, \ + odd_x, c); \ + fodd_repeat_mod(_y1_, priv->box.y2, \ + priv->base.pixmap->drawable.height, \ + odd_y, d); \ + DEBUGF("c %f d %f oddx %d oddy %d \n", \ + c, d, odd_x, odd_y); \ + DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2, \ + priv->box.x1, priv->base.fbo->width); \ + DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, \ + priv->box.y1, priv->base.fbo->height); \ + _glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x, \ + priv->base.pixmap->drawable.width, \ + priv->box.x1, priv->box.x2); \ + _glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y, \ + priv->base.pixmap->drawable.height, \ + priv->box.y1, priv->box.y2); \ + } while(0) + #define _glamor_get_repeat_coords(priv, repeat_type, tx1, \ ty1, tx2, ty2, \ _x1_, _y1_, _x2_, \ _y2_, c, d, odd_x, odd_y) \ do { \ if (repeat_type == RepeatReflect) { \ - assert(0); \ + DEBUGF("x1 y1 %d %d\n", \ + _x1_, _y1_ ); \ + DEBUGF("width %d box.x1 %d \n", \ + (priv)->base.pixmap->drawable.width, \ + priv->box.x1); \ + if (odd_x) { \ + c = (priv)->base.pixmap->drawable.width \ + - c; \ + tx1 = c - priv->box.x1; \ + tx2 = tx1 - ((_x2_) - (_x1_)); \ + } else { \ + tx1 = c - priv->box.x1; \ + tx2 = tx1 + ((_x2_) - (_x1_)); \ + } \ + if (odd_y){ \ + d = (priv)->base.pixmap->drawable.height\ + - d; \ + ty1 = d - priv->box.y1; \ + ty2 = ty1 - ((_y2_) - (_y1_)); \ + } else { \ + ty1 = d - priv->box.y1; \ + ty2 = ty1 + ((_y2_) - (_y1_)); \ + } \ } else if (repeat_type == RepeatNormal) { \ tx1 = (c - priv->box.x1); \ ty1 = (d - priv->box.y1); \ tx2 = tx1 + ((_x2_) - (_x1_)); \ ty2 = ty1 + ((_y2_) - (_y1_)); \ } else { \ - assert(0); \ + tx1 = _x1_ - priv->box.x1; \ + ty1 = _y1_ - priv->box.y1; \ + tx2 = tx1 + ((_x2_) - (_x1_)); \ + ty2 = ty1 + ((_y2_) - (_y1_)); \ } \ } while(0) +/* _x1_ ... _y2_ may has fractional. */ +#define glamor_get_repeat_transform_coords(priv, repeat_type, tx1, \ + ty1, _x1_, _y1_) \ + do { \ + DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \ + (priv)->base.pixmap->drawable.width, \ + priv->box.x1, priv->box.x2, priv->box.y1, \ + priv->box.y2); \ + DEBUGF("x1 %f y1 %f \n", _x1_, _y1_); \ + if (repeat_type != RepeatReflect) { \ + tx1 = _x1_ - priv->box.x1; \ + ty1 = _y1_ - priv->box.y1; \ + } else \ + _glamor_get_reflect_transform_coords(priv, repeat_type, \ + tx1, ty1, \ + _x1_, _y1_); \ + DEBUGF("tx1 %f ty1 %f \n", tx1, ty1); \ + } while(0) /* _x1_ ... _y2_ must be integer. */ #define glamor_get_repeat_coords(priv, repeat_type, tx1, \ @@ -152,8 +303,6 @@ odd_x, odd_y); \ } while(0) - - #define glamor_transform_point(matrix, tx, ty, x, y) \ do { \ int i; \ @@ -221,6 +370,58 @@ yInverted); \ } while (0) +#define glamor_set_repeat_transformed_normalize_tcoords( priv, \ + repeat_type, \ + matrix, \ + xscale, \ + yscale, \ + _x1_, _y1_, \ + _x2_, _y2_, \ + yInverted, \ + texcoords) \ + do { \ + if (priv->type != GLAMOR_TEXTURE_LARGE) { \ + glamor_set_transformed_normalize_tcoords(priv, matrix, xscale, \ + yscale, _x1_, _y1_, \ + _x2_, _y2_, yInverted, \ + texcoords); \ + } else { \ + /* For a large pixmap, if both transform and repeat are set, + * the transform must only has x and y scale factor.*/ \ + float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \ + float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4; \ + DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_); \ + glamor_transform_point(matrix, tx1, ty1, _x1_, _y1_); \ + glamor_transform_point(matrix, tx2, ty2, _x2_, _y1_); \ + glamor_transform_point(matrix, tx3, ty3, _x2_, _y2_); \ + glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_); \ + DEBUGF("transformed %f %f %f %f %f %f %f %f\n", \ + tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4); \ + glamor_get_repeat_transform_coords((&priv->large), repeat_type, \ + ttx1, tty1, \ + tx1, ty1); \ + glamor_get_repeat_transform_coords((&priv->large), repeat_type, \ + ttx2, tty2, \ + tx2, ty2); \ + glamor_get_repeat_transform_coords((&priv->large), repeat_type, \ + ttx3, tty3, \ + tx3, ty3); \ + glamor_get_repeat_transform_coords((&priv->large), repeat_type, \ + ttx4, tty4, \ + tx4, ty4); \ + DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \ + ttx2, tty2, ttx3, tty3, ttx4, tty4); \ + _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \ + texcoords, yInverted); \ + _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \ + texcoords + 2, yInverted); \ + _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \ + texcoords + 4, yInverted); \ + _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \ + texcoords + 6, yInverted); \ + } \ + } while (0) + #define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \ ty1, tx2, ty2, \ yInverted, vertices) \ @@ -261,6 +462,8 @@ tx2, ty2, yInverted, vertices); \ } while(0) + + #define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \ xscale, yscale, \ _x1_, _y1_, _x2_, _y2_, \ @@ -480,7 +683,7 @@ format_for_pixmap(PixmapPtr pixmap) /* * Map picture's format to the correct gl texture format and type. - * no_alpha is used to indicate whehter we need to wire alpha to 1. + * no_alpha is used to indicate whehter we need to wire alpha to 1. * * Although opengl support A1/GL_BITMAP, we still don't use it * here, it seems that mesa has bugs when uploading a A1 bitmap. @@ -899,7 +1102,7 @@ inline static Bool glamor_ddx_fallback_check_pixmap(DrawablePtr drawable) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); - return (!pixmap_priv + return (!pixmap_priv || (pixmap_priv->type == GLAMOR_TEXTURE_DRM || pixmap_priv->type == GLAMOR_MEMORY || pixmap_priv->type == GLAMOR_DRM_ONLY)); |