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