xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

glamor_utils.h (24707B)


      1 /*
      2  * Copyright © 2009 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  *
     23  * Authors:
     24  *    Zhigang Gong <zhigang.gong@linux.intel.com>
     25  *
     26  */
     27 
     28 #ifndef GLAMOR_PRIV_H
     29 #error This file can only be included by glamor_priv.h
     30 #endif
     31 
     32 #ifndef __GLAMOR_UTILS_H__
     33 #define __GLAMOR_UTILS_H__
     34 
     35 #include "glamor_prepare.h"
     36 #include "mipict.h"
     37 
     38 #define v_from_x_coord_x(_xscale_, _x_)          ( 2 * (_x_) * (_xscale_) - 1.0)
     39 #define v_from_x_coord_y(_yscale_, _y_)          (2 * (_y_) * (_yscale_) - 1.0)
     40 #define t_from_x_coord_x(_xscale_, _x_)          ((_x_) * (_xscale_))
     41 #define t_from_x_coord_y(_yscale_, _y_)          ((_y_) * (_yscale_))
     42 
     43 #define pixmap_priv_get_dest_scale(pixmap, _pixmap_priv_, _pxscale_, _pyscale_) \
     44   do {                                                                   \
     45     int _w_,_h_;                                                         \
     46     PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, _pixmap_priv_, _w_, _h_);        \
     47     *(_pxscale_) = 1.0 / _w_;                                            \
     48     *(_pyscale_) = 1.0 / _h_;                                            \
     49    } while(0)
     50 
     51 #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
     52    do {									\
     53     *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width;			\
     54     *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height;			\
     55   } while(0)
     56 
     57 #define PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, w, h)          \
     58   do {								\
     59 	if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) {	\
     60 		w = priv->box.x2 - priv->box.x1;	\
     61 		h = priv->box.y2 - priv->box.y1;	\
     62 	} else {						\
     63 		w = (pixmap)->drawable.width;		\
     64 		h = (pixmap)->drawable.height;		\
     65 	}							\
     66   } while(0)
     67 
     68 #define glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, priv)         \
     69   do {								\
     70 	int actual_w, actual_h;					\
     71 	PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, actual_w, actual_h);	\
     72 	wh[0] = (float)priv->fbo->width / actual_w;	\
     73 	wh[1] = (float)priv->fbo->height / actual_h;	\
     74 	wh[2] = 1.0 / priv->fbo->width;			\
     75 	wh[3] = 1.0 / priv->fbo->height;			\
     76   } while(0)
     77 
     78 #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_)		\
     79    do {								\
     80         if (_X_UNLIKELY(_priv_ && glamor_pixmap_priv_is_large(_priv_))) { \
     81 		*(_xoff_) = - (_priv_)->box.x1;	\
     82 		*(_yoff_) = - (_priv_)->box.y1;	\
     83 	} else {						\
     84 		*(_xoff_) = 0;					\
     85 		*(_yoff_) = 0;					\
     86 	}							\
     87    } while(0)
     88 
     89 #define xFixedToFloat(_val_) ((float)xFixedToInt(_val_)			\
     90 			      + ((float)xFixedFrac(_val_) / 65536.0))
     91 
     92 #define glamor_picture_get_matrixf(_picture_, _matrix_)			\
     93   do {									\
     94     int _i_;								\
     95     if ((_picture_)->transform)						\
     96       {									\
     97 	for(_i_ = 0; _i_ < 3; _i_++)					\
     98 	  {								\
     99 	    (_matrix_)[_i_ * 3 + 0] =					\
    100 	      xFixedToFloat((_picture_)->transform->matrix[_i_][0]);	\
    101 	    (_matrix_)[_i_ * 3 + 1] =					\
    102 	      xFixedToFloat((_picture_)->transform->matrix[_i_][1]);	\
    103 	    (_matrix_)[_i_ * 3 + 2] = \
    104 	      xFixedToFloat((_picture_)->transform->matrix[_i_][2]);	\
    105 	  }								\
    106       }									\
    107   }  while(0)
    108 
    109 #define fmod(x, w)		(x - w * floor((float)x/w))
    110 
    111 #define fmodulus(x, w, c)	do {c = fmod(x, w);		\
    112 				    c = c >= 0 ? c : c + w;}	\
    113 				while(0)
    114 /* @x: is current coord
    115  * @x2: is the right/bottom edge
    116  * @w: is current width or height
    117  * @odd: is output value, 0 means we are in an even region, 1 means we are in a
    118  * odd region.
    119  * @c: is output value, equal to x mod w. */
    120 #define fodd_repeat_mod(x, x2, w, odd, c)	\
    121   do {						\
    122 	float shift;				\
    123 	fmodulus((x), w, c); 			\
    124 	shift = fabs((x) - (c));		\
    125 	shift = floor(fabs(round(shift)) / w);	\
    126 	odd = (int)shift & 1;			\
    127 	if (odd && (((x2 % w) == 0) &&		\
    128 	    round(fabs(x)) == x2))		\
    129 		odd = 0;			\
    130   } while(0)
    131 
    132 /* @txy: output value, is the corrected coords.
    133  * @xy: input coords to be fixed up.
    134  * @cd: xy mod wh, is a input value.
    135  * @wh: current width or height.
    136  * @bxy1,bxy2: current box edge's x1/x2 or y1/y2
    137  *
    138  * case 1:
    139  *  ----------
    140  *  |  *     |
    141  *  |        |
    142  *  ----------
    143  *  tx = (c - x1) mod w
    144  *
    145  *  case 2:
    146  *     ---------
    147  *  *  |       |
    148  *     |       |
    149  *     ---------
    150  *   tx = - (c - (x1 mod w))
    151  *
    152  *   case 3:
    153  *
    154  *   ----------
    155  *   |        |  *
    156  *   |        |
    157  *   ----------
    158  *   tx = ((x2 mod x) - c) + (x2 - x1)
    159  **/
    160 #define __glamor_repeat_reflect_fixup(txy, xy,		\
    161 				cd, wh, bxy1, bxy2)	\
    162   do {							\
    163 	cd = wh - cd;					\
    164 	if ( xy >= bxy1 && xy < bxy2) {			\
    165 		cd = cd - bxy1;				\
    166 		fmodulus(cd, wh, txy);			\
    167 	} else	if (xy < bxy1) {			\
    168 		float bxy1_mod;				\
    169 		fmodulus(bxy1, wh, bxy1_mod);		\
    170 		txy = -(cd - bxy1_mod);			\
    171 	}						\
    172 	else if (xy >= bxy2)	{			\
    173 		float bxy2_mod;				\
    174 		fmodulus(bxy2, wh, bxy2_mod);		\
    175 		if (bxy2_mod == 0)			\
    176 			bxy2_mod = wh;			\
    177 		txy = (bxy2_mod - cd) + bxy2 - bxy1;	\
    178 	} else {assert(0); txy = 0;}			\
    179   } while(0)
    180 
    181 #define _glamor_repeat_reflect_fixup(txy, xy, cd, odd,	\
    182 				     wh, bxy1, bxy2)	\
    183   do {							\
    184 	if (odd) {					\
    185 		__glamor_repeat_reflect_fixup(txy, xy, 	\
    186 			cd, wh, bxy1, bxy2);		\
    187 	} else						\
    188 		txy = xy - bxy1;			\
    189   } while(0)
    190 
    191 #define _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type,	\
    192 					    tx1, ty1, 		\
    193 				            _x1_, _y1_)		\
    194   do {								\
    195 	int odd_x, odd_y;					\
    196 	float c, d;						\
    197 	fodd_repeat_mod(_x1_,priv->box.x2,			\
    198 		    (pixmap)->drawable.width,		\
    199 		    odd_x, c);					\
    200 	fodd_repeat_mod(_y1_,	priv->box.y2,			\
    201 		    (pixmap)->drawable.height,		\
    202 		    odd_y, d);					\
    203 	DEBUGF("c %f d %f oddx %d oddy %d \n",			\
    204 		c, d, odd_x, odd_y);				\
    205 	DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2,	\
    206 		priv->box.x1, priv->fbo->width);		\
    207 	DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, 	\
    208 		priv->box.y1, priv->fbo->height);		\
    209 	_glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x,	\
    210 		(pixmap)->drawable.width,		\
    211 		priv->box.x1, priv->box.x2);			\
    212 	_glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y,	\
    213 		(pixmap)->drawable.height,		\
    214 		priv->box.y1, priv->box.y2);			\
    215    } while(0)
    216 
    217 #define _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1,	\
    218 				  ty1, tx2, ty2,		\
    219 				  _x1_, _y1_, _x2_,		\
    220 				  _y2_, c, d, odd_x, odd_y)	\
    221   do {								\
    222 	if (repeat_type == RepeatReflect) {			\
    223 		DEBUGF("x1 y1 %d %d\n",				\
    224 			_x1_, _y1_ );				\
    225 		DEBUGF("width %d box.x1 %d \n",			\
    226 		       (pixmap)->drawable.width,	\
    227 		       priv->box.x1);				\
    228 		if (odd_x) {					\
    229 			c = (pixmap)->drawable.width	\
    230 				- c;				\
    231 			tx1 = c - priv->box.x1;			\
    232 			tx2 = tx1 - ((_x2_) - (_x1_));		\
    233 		} else {					\
    234 			tx1 = c - priv->box.x1;			\
    235 			tx2 = tx1 + ((_x2_) - (_x1_));		\
    236 		}						\
    237 		if (odd_y){					\
    238 			d = (pixmap)->drawable.height\
    239 			    - d;				\
    240 			ty1 = d - priv->box.y1;			\
    241 			ty2 = ty1 - ((_y2_) - (_y1_));		\
    242 		} else {					\
    243 			ty1 = d - priv->box.y1;			\
    244 			ty2 = ty1 + ((_y2_) - (_y1_));		\
    245 		}						\
    246 	} else { /* RepeatNormal*/				\
    247 		tx1 = (c - priv->box.x1);  			\
    248 		ty1 = (d - priv->box.y1);			\
    249 		tx2 = tx1 + ((_x2_) - (_x1_));			\
    250 		ty2 = ty1 + ((_y2_) - (_y1_));			\
    251 	}							\
    252    } while(0)
    253 
    254 /* _x1_ ... _y2_ may has fractional. */
    255 #define glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, tx1, \
    256 					   ty1, _x1_, _y1_)		\
    257   do {									\
    258 	DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n",		\
    259 		(pixmap)->drawable.width,			\
    260 		priv->box.x1, priv->box.x2, priv->box.y1,		\
    261 		priv->box.y2);						\
    262 	DEBUGF("x1 %f y1 %f \n", _x1_, _y1_);				\
    263 	if (repeat_type != RepeatReflect) {				\
    264 		tx1 = _x1_ - priv->box.x1;				\
    265 		ty1 = _y1_ - priv->box.y1;				\
    266 	} else			\
    267                 _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \
    268 				  tx1, ty1, 				\
    269 				  _x1_, _y1_);				\
    270 	DEBUGF("tx1 %f ty1 %f \n", tx1, ty1);				\
    271    } while(0)
    272 
    273 /* _x1_ ... _y2_ must be integer. */
    274 #define glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1,		\
    275 				 ty1, tx2, ty2, _x1_, _y1_, _x2_,	\
    276 				 _y2_) 					\
    277   do {									\
    278 	int c, d;							\
    279 	int odd_x = 0, odd_y = 0;					\
    280 	DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n",		\
    281 		(pixmap)->drawable.width,			\
    282 		priv->box.x1, priv->box.x2,				\
    283 		priv->box.y1, priv->box.y2);				\
    284 	modulus((_x1_), (pixmap)->drawable.width, c); 	\
    285 	modulus((_y1_), (pixmap)->drawable.height, d);	\
    286 	DEBUGF("c %d d %d \n", c, d);					\
    287 	if (repeat_type == RepeatReflect) {				\
    288 		odd_x = abs((_x1_ - c)					\
    289                             / ((pixmap)->drawable.width)) & 1;            \
    290 		odd_y = abs((_y1_ - d)					\
    291                             / ((pixmap)->drawable.height)) & 1;           \
    292 	}								\
    293 	_glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, ty1, tx2, ty2, \
    294 				  _x1_, _y1_, _x2_, _y2_, c, d,		\
    295 				  odd_x, odd_y);			\
    296    } while(0)
    297 
    298 #define glamor_transform_point(matrix, tx, ty, x, y)			\
    299   do {									\
    300     int _i_;								\
    301     float _result_[4];							\
    302     for (_i_ = 0; _i_ < 3; _i_++) {					\
    303       _result_[_i_] = (matrix)[_i_ * 3] * (x) + (matrix)[_i_ * 3 + 1] * (y)	\
    304 	+ (matrix)[_i_ * 3 + 2];					\
    305     }									\
    306     tx = _result_[0] / _result_[2];					\
    307     ty = _result_[1] / _result_[2];					\
    308   } while(0)
    309 
    310 #define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_,	\
    311 				     texcoord)                          \
    312   do {									\
    313 	(texcoord)[0] = t_from_x_coord_x(xscale, _tx_);			\
    314         (texcoord)[1] = t_from_x_coord_y(yscale, _ty_);                 \
    315         DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0],	\
    316 		(texcoord)[1]);						\
    317   } while(0)
    318 
    319 #define glamor_set_transformed_point(priv, matrix, xscale,              \
    320 				     yscale, texcoord,			\
    321                                      x, y)				\
    322   do {									\
    323     float tx, ty;							\
    324     int fbo_x_off, fbo_y_off;						\
    325     pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
    326     glamor_transform_point(matrix, tx, ty, x, y);			\
    327     DEBUGF("tx %f ty %f fbooff %d %d \n",				\
    328 	    tx, ty, fbo_x_off, fbo_y_off);				\
    329 									\
    330     tx += fbo_x_off;							\
    331     ty += fbo_y_off;							\
    332     (texcoord)[0] = t_from_x_coord_x(xscale, tx);			\
    333     (texcoord)[1] = t_from_x_coord_y(yscale, ty);                       \
    334     DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]);	\
    335   } while(0)
    336 
    337 #define glamor_set_transformed_normalize_tcoords_ext( priv,		\
    338 						  matrix,		\
    339 						  xscale,		\
    340 						  yscale,		\
    341                                                   tx1, ty1, tx2, ty2,   \
    342                                                   texcoords,		\
    343 						  stride)		\
    344   do {									\
    345     glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
    346 				 texcoords, tx1, ty1);                  \
    347     glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
    348 				 texcoords + 1 * stride, tx2, ty1);     \
    349     glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
    350 				 texcoords + 2 * stride, tx2, ty2);     \
    351     glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
    352 				 texcoords + 3 * stride, tx1, ty2);     \
    353   } while (0)
    354 
    355 #define glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, \
    356 							 repeat_type,	\
    357 							 matrix,	\
    358 							 xscale,	\
    359 							 yscale,	\
    360 							 _x1_, _y1_,	\
    361 							 _x2_, _y2_,   	\
    362 							 texcoords,	\
    363 							 stride)	\
    364   do {									\
    365     if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) {		\
    366 	glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,	\
    367 						 yscale, _x1_, _y1_,	\
    368 						 _x2_, _y2_,	\
    369 						 texcoords, stride);	\
    370     } else {								\
    371     float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;			\
    372     float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4;		\
    373     DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_);	\
    374     glamor_transform_point(matrix, tx1, ty1, _x1_, _y1_);		\
    375     glamor_transform_point(matrix, tx2, ty2, _x2_, _y1_);		\
    376     glamor_transform_point(matrix, tx3, ty3, _x2_, _y2_);		\
    377     glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_);		\
    378     DEBUGF("transformed %f %f %f %f %f %f %f %f\n",			\
    379 	   tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);			\
    380     glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
    381 				       ttx1, tty1, 			\
    382 				       tx1, ty1);			\
    383     glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, 	\
    384 				       ttx2, tty2, 			\
    385 				       tx2, ty2);			\
    386     glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, 	\
    387 				       ttx3, tty3, 			\
    388 				       tx3, ty3);			\
    389     glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, 	\
    390 				       ttx4, tty4, 			\
    391 				       tx4, ty4);			\
    392     DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, 	\
    393 	    ttx2, tty2,	ttx3, tty3, ttx4, tty4);			\
    394     _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1,		\
    395 				 texcoords);			\
    396     _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2,		\
    397 				 texcoords + 1 * stride);	\
    398     _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3,		\
    399 				 texcoords + 2 * stride);	\
    400     _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4,		\
    401 				 texcoords + 3 * stride);	\
    402    }									\
    403   } while (0)
    404 
    405 #define glamor_set_repeat_transformed_normalize_tcoords( pixmap,        \
    406                                                          priv,          \
    407 							 repeat_type,	\
    408 							 matrix,	\
    409 							 xscale,	\
    410 							 yscale,	\
    411 							 _x1_, _y1_,	\
    412 							 _x2_, _y2_,   	\
    413 							 texcoords)	\
    414   do {									\
    415       glamor_set_repeat_transformed_normalize_tcoords_ext( pixmap,      \
    416                                                            priv,	\
    417 							 repeat_type,	\
    418 							 matrix,	\
    419 							 xscale,	\
    420 							 yscale,	\
    421 							 _x1_, _y1_,	\
    422 							 _x2_, _y2_,   	\
    423 							 texcoords,	\
    424 							 2);	\
    425   } while (0)
    426 
    427 #define _glamor_set_normalize_tcoords(xscale, yscale, tx1,		\
    428 				      ty1, tx2, ty2,			\
    429 				      vertices, stride)                 \
    430   do {									\
    431     /* vertices may be write-only, so we use following			\
    432      * temporary variable. */ 						\
    433     float _t0_, _t1_, _t2_, _t5_;					\
    434     (vertices)[0] = _t0_ = t_from_x_coord_x(xscale, tx1);		\
    435     (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2);	\
    436     (vertices)[2 * stride] = _t2_;					\
    437     (vertices)[3 * stride] = _t0_;					\
    438     (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1);               \
    439     (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);  \
    440     (vertices)[1 * stride + 1] = _t1_;					\
    441     (vertices)[3 * stride + 1] = _t5_;					\
    442   } while(0)
    443 
    444 #define glamor_set_normalize_tcoords_ext(priv, xscale, yscale,		\
    445 				     x1, y1, x2, y2,			\
    446                                      vertices, stride)	\
    447   do {									\
    448      if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) {		\
    449 	float tx1, tx2, ty1, ty2;					\
    450 	int fbo_x_off, fbo_y_off;					\
    451 	pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
    452 	tx1 = x1 + fbo_x_off; 						\
    453 	tx2 = x2 + fbo_x_off;						\
    454 	ty1 = y1 + fbo_y_off;						\
    455 	ty2 = y2 + fbo_y_off;						\
    456 	_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
    457                                       tx2, ty2, vertices,               \
    458 				   stride);				\
    459      } else								\
    460 	_glamor_set_normalize_tcoords(xscale, yscale, x1, y1,		\
    461                                       x2, y2, vertices, stride);        \
    462  } while(0)
    463 
    464 #define glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type, \
    465 					    xscale, yscale,		\
    466 					    _x1_, _y1_, _x2_, _y2_,	\
    467 	                                    vertices, stride)		\
    468   do {									\
    469      if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) {		\
    470 	float tx1, tx2, ty1, ty2;					\
    471 	if (repeat_type == RepeatPad) {					\
    472 		tx1 = _x1_ - priv->box.x1;			        \
    473 		ty1 = _y1_ - priv->box.y1;			        \
    474 		tx2 = tx1 + ((_x2_) - (_x1_));				\
    475 		ty2 = ty1 + ((_y2_) - (_y1_));				\
    476 	} else {							\
    477             glamor_get_repeat_coords(pixmap, priv, repeat_type,         \
    478 				 tx1, ty1, tx2, ty2,			\
    479 				 _x1_, _y1_, _x2_, _y2_);		\
    480 	}								\
    481 	_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
    482                                       tx2, ty2, vertices,               \
    483 				   stride);				\
    484      } else								\
    485 	_glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_,	\
    486                                       _x2_, _y2_, vertices,             \
    487 				   stride);				\
    488  } while(0)
    489 
    490 #define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale,		\
    491 						x1, y1, x2, y2,		\
    492 						vertices)               \
    493     do {								\
    494 	(vertices)[0] = t_from_x_coord_x(xscale, x1);			\
    495 	(vertices)[2] = t_from_x_coord_x(xscale, x2);			\
    496 	(vertices)[6] = (vertices)[2];					\
    497 	(vertices)[4] = (vertices)[0];					\
    498         (vertices)[1] = t_from_x_coord_y(yscale, y1);                   \
    499         (vertices)[7] = t_from_x_coord_y(yscale, y2);                   \
    500 	(vertices)[3] = (vertices)[1];					\
    501 	(vertices)[5] = (vertices)[7];					\
    502     } while(0)
    503 
    504 #define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices)          \
    505     do {								\
    506 	(vertices)[0] = (x1);						\
    507 	(vertices)[2] = (x2);						\
    508 	(vertices)[6] = (vertices)[2];					\
    509 	(vertices)[4] = (vertices)[0];					\
    510         (vertices)[1] = (y1);                                           \
    511         (vertices)[7] = (y2);                                           \
    512 	(vertices)[3] = (vertices)[1];					\
    513 	(vertices)[5] = (vertices)[7];					\
    514     } while(0)
    515 
    516 #define glamor_set_normalize_vcoords_ext(priv, xscale, yscale,		\
    517 				     x1, y1, x2, y2,			\
    518                                          vertices, stride)              \
    519   do {									\
    520     int fbo_x_off, fbo_y_off;						\
    521     /* vertices may be write-only, so we use following			\
    522      * temporary variable. */						\
    523     float _t0_, _t1_, _t2_, _t5_;					\
    524     pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
    525     (vertices)[0] = _t0_ = v_from_x_coord_x(xscale, x1 + fbo_x_off);	\
    526     (vertices)[1 * stride] = _t2_ = v_from_x_coord_x(xscale,		\
    527 					x2 + fbo_x_off);		\
    528     (vertices)[2 * stride] = _t2_;					\
    529     (vertices)[3 * stride] = _t0_;					\
    530     (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off);    \
    531     (vertices)[2 * stride + 1] = _t5_ =                                 \
    532         v_from_x_coord_y(yscale, y2 + fbo_y_off);                       \
    533     (vertices)[1 * stride + 1] = _t1_;					\
    534     (vertices)[3 * stride + 1] = _t5_;					\
    535   } while(0)
    536 
    537 #define glamor_set_normalize_vcoords_tri_strip(xscale, yscale,		\
    538 					       x1, y1, x2, y2,		\
    539 					       vertices)		\
    540     do {								\
    541 	(vertices)[0] = v_from_x_coord_x(xscale, x1);			\
    542 	(vertices)[2] = v_from_x_coord_x(xscale, x2);			\
    543 	(vertices)[6] = (vertices)[2];					\
    544 	(vertices)[4] = (vertices)[0];					\
    545         (vertices)[1] = v_from_x_coord_y(yscale, y1);                   \
    546         (vertices)[7] = v_from_x_coord_y(yscale, y2);                   \
    547 	(vertices)[3] = (vertices)[1];					\
    548 	(vertices)[5] = (vertices)[7];					\
    549     } while(0)
    550 
    551 #define glamor_set_normalize_pt(xscale, yscale, x, y,		\
    552                                 pt)				\
    553     do {							\
    554         (pt)[0] = t_from_x_coord_x(xscale, x);			\
    555         (pt)[1] = t_from_x_coord_y(yscale, y);                  \
    556     } while(0)
    557 
    558 #define glamor_set_circle_centre(width, height, x, y,	\
    559 				 c)		\
    560     do {						\
    561         (c)[0] = (float)x;				\
    562         (c)[1] = (float)y;				\
    563     } while(0)
    564 
    565 #define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
    566 #define MIN(a,b)	((a) < (b) ? (a) : (b))
    567 #define MAX(a,b)	((a) > (b) ? (a) : (b))
    568 
    569 #define glamor_check_fbo_size(_glamor_,_w_, _h_)    ((_w_) > 0 && (_h_) > 0 \
    570                                                     && (_w_) <= _glamor_->max_fbo_size  \
    571                                                     && (_h_) <= _glamor_->max_fbo_size)
    572 
    573 #define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
    574 
    575 #define REVERT_NONE       		0
    576 #define REVERT_NORMAL     		1
    577 #define REVERT_UPLOADING_A1		3
    578 
    579 #define SWAP_UPLOADING	  	2
    580 #define SWAP_NONE_UPLOADING	3
    581 
    582 /* borrowed from uxa */
    583 static inline Bool
    584 glamor_get_rgba_from_pixel(CARD32 pixel,
    585                            float *red,
    586                            float *green,
    587                            float *blue, float *alpha, CARD32 format)
    588 {
    589     int rbits, bbits, gbits, abits;
    590     int rshift, bshift, gshift, ashift;
    591 
    592     rbits = PICT_FORMAT_R(format);
    593     gbits = PICT_FORMAT_G(format);
    594     bbits = PICT_FORMAT_B(format);
    595     abits = PICT_FORMAT_A(format);
    596 
    597     if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
    598         rshift = gshift = bshift = ashift = 0;
    599     }
    600     else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
    601         bshift = 0;
    602         gshift = bbits;
    603         rshift = gshift + gbits;
    604         ashift = rshift + rbits;
    605     }
    606     else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
    607         rshift = 0;
    608         gshift = rbits;
    609         bshift = gshift + gbits;
    610         ashift = bshift + bbits;
    611     }
    612     else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
    613         ashift = 0;
    614         rshift = abits;
    615         if (abits == 0)
    616             rshift = PICT_FORMAT_BPP(format) - (rbits + gbits + bbits);
    617         gshift = rshift + rbits;
    618         bshift = gshift + gbits;
    619     }
    620     else {
    621         return FALSE;
    622     }
    623 #define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_)	\
    624   *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1))	\
    625     / (float)((1<<(_bits_)) - 1)
    626 
    627     if (rbits)
    628         COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
    629     else
    630         *red = 0;
    631 
    632     if (gbits)
    633         COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
    634     else
    635         *green = 0;
    636 
    637     if (bbits)
    638         COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
    639     else
    640         *blue = 0;
    641 
    642     if (abits)
    643         COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
    644     else
    645         *alpha = 1;
    646 
    647     return TRUE;
    648 }
    649 
    650 static inline void
    651 glamor_get_rgba_from_color(const xRenderColor *color, float rgba[4])
    652 {
    653     rgba[0] = color->red   / (float)UINT16_MAX;
    654     rgba[1] = color->green / (float)UINT16_MAX;
    655     rgba[2] = color->blue  / (float)UINT16_MAX;
    656     rgba[3] = color->alpha / (float)UINT16_MAX;
    657 }
    658 
    659 inline static Bool
    660 glamor_is_large_pixmap(PixmapPtr pixmap)
    661 {
    662     glamor_pixmap_private *priv;
    663 
    664     priv = glamor_get_pixmap_private(pixmap);
    665     return (glamor_pixmap_priv_is_large(priv));
    666 }
    667 
    668 static inline void
    669 glamor_make_current(glamor_screen_private *glamor_priv)
    670 {
    671     if (lastGLContext != glamor_priv->ctx.ctx) {
    672         lastGLContext = glamor_priv->ctx.ctx;
    673         glamor_priv->ctx.make_current(&glamor_priv->ctx);
    674     }
    675 }
    676 
    677 static inline BoxRec
    678 glamor_no_rendering_bounds(void)
    679 {
    680     BoxRec bounds = {
    681         .x1 = 0,
    682         .y1 = 0,
    683         .x2 = MAXSHORT,
    684         .y2 = MAXSHORT,
    685     };
    686 
    687     return bounds;
    688 }
    689 
    690 static inline BoxRec
    691 glamor_start_rendering_bounds(void)
    692 {
    693     BoxRec bounds = {
    694         .x1 = MAXSHORT,
    695         .y1 = MAXSHORT,
    696         .x2 = 0,
    697         .y2 = 0,
    698     };
    699 
    700     return bounds;
    701 }
    702 
    703 static inline void
    704 glamor_bounds_union_rect(BoxPtr bounds, xRectangle *rect)
    705 {
    706     bounds->x1 = min(bounds->x1, rect->x);
    707     bounds->y1 = min(bounds->y1, rect->y);
    708     bounds->x2 = min(SHRT_MAX, max(bounds->x2, rect->x + rect->width));
    709     bounds->y2 = min(SHRT_MAX, max(bounds->y2, rect->y + rect->height));
    710 }
    711 
    712 static inline void
    713 glamor_bounds_union_box(BoxPtr bounds, BoxPtr box)
    714 {
    715     bounds->x1 = min(bounds->x1, box->x1);
    716     bounds->y1 = min(bounds->y1, box->y1);
    717     bounds->x2 = max(bounds->x2, box->x2);
    718     bounds->y2 = max(bounds->y2, box->y2);
    719 }
    720 
    721 /**
    722  * Helper function for implementing draws with GL_QUADS on GLES2,
    723  * where we don't have them.
    724  */
    725 static inline void
    726 glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
    727 {
    728     if (glamor_priv->use_quads) {
    729         glDrawArrays(GL_QUADS, 0, count * 4);
    730     } else {
    731         glamor_gldrawarrays_quads_using_indices(glamor_priv, count);
    732     }
    733 }
    734 
    735 static inline Bool
    736 glamor_glsl_has_ints(glamor_screen_private *glamor_priv) {
    737     return glamor_priv->glsl_version >= 130 || glamor_priv->use_gpu_shader4;
    738 }
    739 
    740 #endif