135c4bbdfSmrg/*
235c4bbdfSmrg * Copyright © 2009 Intel Corporation
335c4bbdfSmrg *
435c4bbdfSmrg * Permission is hereby granted, free of charge, to any person obtaining a
535c4bbdfSmrg * copy of this software and associated documentation files (the "Software"),
635c4bbdfSmrg * to deal in the Software without restriction, including without limitation
735c4bbdfSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
835c4bbdfSmrg * and/or sell copies of the Software, and to permit persons to whom the
935c4bbdfSmrg * Software is furnished to do so, subject to the following conditions:
1035c4bbdfSmrg *
1135c4bbdfSmrg * The above copyright notice and this permission notice (including the next
1235c4bbdfSmrg * paragraph) shall be included in all copies or substantial portions of the
1335c4bbdfSmrg * Software.
1435c4bbdfSmrg *
1535c4bbdfSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1635c4bbdfSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1735c4bbdfSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1835c4bbdfSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1935c4bbdfSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2035c4bbdfSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2135c4bbdfSmrg * IN THE SOFTWARE.
2235c4bbdfSmrg *
2335c4bbdfSmrg * Authors:
2435c4bbdfSmrg *    Zhigang Gong <zhigang.gong@linux.intel.com>
2535c4bbdfSmrg *
2635c4bbdfSmrg */
2735c4bbdfSmrg
2835c4bbdfSmrg#ifndef GLAMOR_PRIV_H
2935c4bbdfSmrg#error This file can only be included by glamor_priv.h
3035c4bbdfSmrg#endif
3135c4bbdfSmrg
3235c4bbdfSmrg#ifndef __GLAMOR_UTILS_H__
3335c4bbdfSmrg#define __GLAMOR_UTILS_H__
3435c4bbdfSmrg
3535c4bbdfSmrg#include "glamor_prepare.h"
3635c4bbdfSmrg#include "mipict.h"
3735c4bbdfSmrg
3835c4bbdfSmrg#define v_from_x_coord_x(_xscale_, _x_)          ( 2 * (_x_) * (_xscale_) - 1.0)
3935c4bbdfSmrg#define v_from_x_coord_y(_yscale_, _y_)          (2 * (_y_) * (_yscale_) - 1.0)
4035c4bbdfSmrg#define t_from_x_coord_x(_xscale_, _x_)          ((_x_) * (_xscale_))
4135c4bbdfSmrg#define t_from_x_coord_y(_yscale_, _y_)          ((_y_) * (_yscale_))
4235c4bbdfSmrg
4335c4bbdfSmrg#define pixmap_priv_get_dest_scale(pixmap, _pixmap_priv_, _pxscale_, _pyscale_) \
4435c4bbdfSmrg  do {                                                                   \
4535c4bbdfSmrg    int _w_,_h_;                                                         \
4635c4bbdfSmrg    PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, _pixmap_priv_, _w_, _h_);        \
4735c4bbdfSmrg    *(_pxscale_) = 1.0 / _w_;                                            \
4835c4bbdfSmrg    *(_pyscale_) = 1.0 / _h_;                                            \
4935c4bbdfSmrg   } while(0)
5035c4bbdfSmrg
5135c4bbdfSmrg#define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_)	\
5235c4bbdfSmrg   do {									\
5335c4bbdfSmrg    *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width;			\
5435c4bbdfSmrg    *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height;			\
5535c4bbdfSmrg  } while(0)
5635c4bbdfSmrg
5735c4bbdfSmrg#define PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, w, h)          \
5835c4bbdfSmrg  do {								\
5935c4bbdfSmrg	if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) {	\
6035c4bbdfSmrg		w = priv->box.x2 - priv->box.x1;	\
6135c4bbdfSmrg		h = priv->box.y2 - priv->box.y1;	\
6235c4bbdfSmrg	} else {						\
6335c4bbdfSmrg		w = (pixmap)->drawable.width;		\
6435c4bbdfSmrg		h = (pixmap)->drawable.height;		\
6535c4bbdfSmrg	}							\
6635c4bbdfSmrg  } while(0)
6735c4bbdfSmrg
6835c4bbdfSmrg#define glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, priv)         \
6935c4bbdfSmrg  do {								\
7035c4bbdfSmrg	int actual_w, actual_h;					\
7135c4bbdfSmrg	PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, actual_w, actual_h);	\
7235c4bbdfSmrg	wh[0] = (float)priv->fbo->width / actual_w;	\
7335c4bbdfSmrg	wh[1] = (float)priv->fbo->height / actual_h;	\
7435c4bbdfSmrg	wh[2] = 1.0 / priv->fbo->width;			\
7535c4bbdfSmrg	wh[3] = 1.0 / priv->fbo->height;			\
7635c4bbdfSmrg  } while(0)
7735c4bbdfSmrg
7835c4bbdfSmrg#define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_)		\
7935c4bbdfSmrg   do {								\
8035c4bbdfSmrg        if (_X_UNLIKELY(_priv_ && glamor_pixmap_priv_is_large(_priv_))) { \
8135c4bbdfSmrg		*(_xoff_) = - (_priv_)->box.x1;	\
8235c4bbdfSmrg		*(_yoff_) = - (_priv_)->box.y1;	\
8335c4bbdfSmrg	} else {						\
8435c4bbdfSmrg		*(_xoff_) = 0;					\
8535c4bbdfSmrg		*(_yoff_) = 0;					\
8635c4bbdfSmrg	}							\
8735c4bbdfSmrg   } while(0)
8835c4bbdfSmrg
8935c4bbdfSmrg#define xFixedToFloat(_val_) ((float)xFixedToInt(_val_)			\
9035c4bbdfSmrg			      + ((float)xFixedFrac(_val_) / 65536.0))
9135c4bbdfSmrg
9235c4bbdfSmrg#define glamor_picture_get_matrixf(_picture_, _matrix_)			\
9335c4bbdfSmrg  do {									\
9435c4bbdfSmrg    int _i_;								\
9535c4bbdfSmrg    if ((_picture_)->transform)						\
9635c4bbdfSmrg      {									\
9735c4bbdfSmrg	for(_i_ = 0; _i_ < 3; _i_++)					\
9835c4bbdfSmrg	  {								\
9935c4bbdfSmrg	    (_matrix_)[_i_ * 3 + 0] =					\
10035c4bbdfSmrg	      xFixedToFloat((_picture_)->transform->matrix[_i_][0]);	\
10135c4bbdfSmrg	    (_matrix_)[_i_ * 3 + 1] =					\
10235c4bbdfSmrg	      xFixedToFloat((_picture_)->transform->matrix[_i_][1]);	\
10335c4bbdfSmrg	    (_matrix_)[_i_ * 3 + 2] = \
10435c4bbdfSmrg	      xFixedToFloat((_picture_)->transform->matrix[_i_][2]);	\
10535c4bbdfSmrg	  }								\
10635c4bbdfSmrg      }									\
10735c4bbdfSmrg  }  while(0)
10835c4bbdfSmrg
10935c4bbdfSmrg#define fmod(x, w)		(x - w * floor((float)x/w))
11035c4bbdfSmrg
11135c4bbdfSmrg#define fmodulus(x, w, c)	do {c = fmod(x, w);		\
11235c4bbdfSmrg				    c = c >= 0 ? c : c + w;}	\
11335c4bbdfSmrg				while(0)
11435c4bbdfSmrg/* @x: is current coord
11535c4bbdfSmrg * @x2: is the right/bottom edge
11635c4bbdfSmrg * @w: is current width or height
11735c4bbdfSmrg * @odd: is output value, 0 means we are in an even region, 1 means we are in a
11835c4bbdfSmrg * odd region.
11935c4bbdfSmrg * @c: is output value, equal to x mod w. */
12035c4bbdfSmrg#define fodd_repeat_mod(x, x2, w, odd, c)	\
12135c4bbdfSmrg  do {						\
12235c4bbdfSmrg	float shift;				\
12335c4bbdfSmrg	fmodulus((x), w, c); 			\
12435c4bbdfSmrg	shift = fabs((x) - (c));		\
12535c4bbdfSmrg	shift = floor(fabs(round(shift)) / w);	\
12635c4bbdfSmrg	odd = (int)shift & 1;			\
12735c4bbdfSmrg	if (odd && (((x2 % w) == 0) &&		\
12835c4bbdfSmrg	    round(fabs(x)) == x2))		\
12935c4bbdfSmrg		odd = 0;			\
13035c4bbdfSmrg  } while(0)
13135c4bbdfSmrg
13235c4bbdfSmrg/* @txy: output value, is the corrected coords.
13335c4bbdfSmrg * @xy: input coords to be fixed up.
13435c4bbdfSmrg * @cd: xy mod wh, is a input value.
13535c4bbdfSmrg * @wh: current width or height.
13635c4bbdfSmrg * @bxy1,bxy2: current box edge's x1/x2 or y1/y2
13735c4bbdfSmrg *
13835c4bbdfSmrg * case 1:
13935c4bbdfSmrg *  ----------
14035c4bbdfSmrg *  |  *     |
14135c4bbdfSmrg *  |        |
14235c4bbdfSmrg *  ----------
14335c4bbdfSmrg *  tx = (c - x1) mod w
14435c4bbdfSmrg *
14535c4bbdfSmrg *  case 2:
14635c4bbdfSmrg *     ---------
14735c4bbdfSmrg *  *  |       |
14835c4bbdfSmrg *     |       |
14935c4bbdfSmrg *     ---------
15035c4bbdfSmrg *   tx = - (c - (x1 mod w))
15135c4bbdfSmrg *
15235c4bbdfSmrg *   case 3:
15335c4bbdfSmrg *
15435c4bbdfSmrg *   ----------
15535c4bbdfSmrg *   |        |  *
15635c4bbdfSmrg *   |        |
15735c4bbdfSmrg *   ----------
15835c4bbdfSmrg *   tx = ((x2 mod x) - c) + (x2 - x1)
15935c4bbdfSmrg **/
16035c4bbdfSmrg#define __glamor_repeat_reflect_fixup(txy, xy,		\
16135c4bbdfSmrg				cd, wh, bxy1, bxy2)	\
16235c4bbdfSmrg  do {							\
16335c4bbdfSmrg	cd = wh - cd;					\
16435c4bbdfSmrg	if ( xy >= bxy1 && xy < bxy2) {			\
16535c4bbdfSmrg		cd = cd - bxy1;				\
16635c4bbdfSmrg		fmodulus(cd, wh, txy);			\
16735c4bbdfSmrg	} else	if (xy < bxy1) {			\
16835c4bbdfSmrg		float bxy1_mod;				\
16935c4bbdfSmrg		fmodulus(bxy1, wh, bxy1_mod);		\
17035c4bbdfSmrg		txy = -(cd - bxy1_mod);			\
17135c4bbdfSmrg	}						\
17235c4bbdfSmrg	else if (xy >= bxy2)	{			\
17335c4bbdfSmrg		float bxy2_mod;				\
17435c4bbdfSmrg		fmodulus(bxy2, wh, bxy2_mod);		\
17535c4bbdfSmrg		if (bxy2_mod == 0)			\
17635c4bbdfSmrg			bxy2_mod = wh;			\
17735c4bbdfSmrg		txy = (bxy2_mod - cd) + bxy2 - bxy1;	\
17835c4bbdfSmrg	} else {assert(0); txy = 0;}			\
17935c4bbdfSmrg  } while(0)
18035c4bbdfSmrg
18135c4bbdfSmrg#define _glamor_repeat_reflect_fixup(txy, xy, cd, odd,	\
18235c4bbdfSmrg				     wh, bxy1, bxy2)	\
18335c4bbdfSmrg  do {							\
18435c4bbdfSmrg	if (odd) {					\
18535c4bbdfSmrg		__glamor_repeat_reflect_fixup(txy, xy, 	\
18635c4bbdfSmrg			cd, wh, bxy1, bxy2);		\
18735c4bbdfSmrg	} else						\
18835c4bbdfSmrg		txy = xy - bxy1;			\
18935c4bbdfSmrg  } while(0)
19035c4bbdfSmrg
19135c4bbdfSmrg#define _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type,	\
19235c4bbdfSmrg					    tx1, ty1, 		\
19335c4bbdfSmrg				            _x1_, _y1_)		\
19435c4bbdfSmrg  do {								\
19535c4bbdfSmrg	int odd_x, odd_y;					\
19635c4bbdfSmrg	float c, d;						\
19735c4bbdfSmrg	fodd_repeat_mod(_x1_,priv->box.x2,			\
19835c4bbdfSmrg		    (pixmap)->drawable.width,		\
19935c4bbdfSmrg		    odd_x, c);					\
20035c4bbdfSmrg	fodd_repeat_mod(_y1_,	priv->box.y2,			\
20135c4bbdfSmrg		    (pixmap)->drawable.height,		\
20235c4bbdfSmrg		    odd_y, d);					\
20335c4bbdfSmrg	DEBUGF("c %f d %f oddx %d oddy %d \n",			\
20435c4bbdfSmrg		c, d, odd_x, odd_y);				\
20535c4bbdfSmrg	DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2,	\
20635c4bbdfSmrg		priv->box.x1, priv->fbo->width);		\
20735c4bbdfSmrg	DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, 	\
20835c4bbdfSmrg		priv->box.y1, priv->fbo->height);		\
20935c4bbdfSmrg	_glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x,	\
21035c4bbdfSmrg		(pixmap)->drawable.width,		\
21135c4bbdfSmrg		priv->box.x1, priv->box.x2);			\
21235c4bbdfSmrg	_glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y,	\
21335c4bbdfSmrg		(pixmap)->drawable.height,		\
21435c4bbdfSmrg		priv->box.y1, priv->box.y2);			\
21535c4bbdfSmrg   } while(0)
21635c4bbdfSmrg
21735c4bbdfSmrg#define _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1,	\
21835c4bbdfSmrg				  ty1, tx2, ty2,		\
21935c4bbdfSmrg				  _x1_, _y1_, _x2_,		\
22035c4bbdfSmrg				  _y2_, c, d, odd_x, odd_y)	\
22135c4bbdfSmrg  do {								\
22235c4bbdfSmrg	if (repeat_type == RepeatReflect) {			\
22335c4bbdfSmrg		DEBUGF("x1 y1 %d %d\n",				\
22435c4bbdfSmrg			_x1_, _y1_ );				\
22535c4bbdfSmrg		DEBUGF("width %d box.x1 %d \n",			\
22635c4bbdfSmrg		       (pixmap)->drawable.width,	\
22735c4bbdfSmrg		       priv->box.x1);				\
22835c4bbdfSmrg		if (odd_x) {					\
22935c4bbdfSmrg			c = (pixmap)->drawable.width	\
23035c4bbdfSmrg				- c;				\
23135c4bbdfSmrg			tx1 = c - priv->box.x1;			\
23235c4bbdfSmrg			tx2 = tx1 - ((_x2_) - (_x1_));		\
23335c4bbdfSmrg		} else {					\
23435c4bbdfSmrg			tx1 = c - priv->box.x1;			\
23535c4bbdfSmrg			tx2 = tx1 + ((_x2_) - (_x1_));		\
23635c4bbdfSmrg		}						\
23735c4bbdfSmrg		if (odd_y){					\
23835c4bbdfSmrg			d = (pixmap)->drawable.height\
23935c4bbdfSmrg			    - d;				\
24035c4bbdfSmrg			ty1 = d - priv->box.y1;			\
24135c4bbdfSmrg			ty2 = ty1 - ((_y2_) - (_y1_));		\
24235c4bbdfSmrg		} else {					\
24335c4bbdfSmrg			ty1 = d - priv->box.y1;			\
24435c4bbdfSmrg			ty2 = ty1 + ((_y2_) - (_y1_));		\
24535c4bbdfSmrg		}						\
24635c4bbdfSmrg	} else { /* RepeatNormal*/				\
24735c4bbdfSmrg		tx1 = (c - priv->box.x1);  			\
24835c4bbdfSmrg		ty1 = (d - priv->box.y1);			\
24935c4bbdfSmrg		tx2 = tx1 + ((_x2_) - (_x1_));			\
25035c4bbdfSmrg		ty2 = ty1 + ((_y2_) - (_y1_));			\
25135c4bbdfSmrg	}							\
25235c4bbdfSmrg   } while(0)
25335c4bbdfSmrg
25435c4bbdfSmrg/* _x1_ ... _y2_ may has fractional. */
25535c4bbdfSmrg#define glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, tx1, \
25635c4bbdfSmrg					   ty1, _x1_, _y1_)		\
25735c4bbdfSmrg  do {									\
25835c4bbdfSmrg	DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n",		\
25935c4bbdfSmrg		(pixmap)->drawable.width,			\
26035c4bbdfSmrg		priv->box.x1, priv->box.x2, priv->box.y1,		\
26135c4bbdfSmrg		priv->box.y2);						\
26235c4bbdfSmrg	DEBUGF("x1 %f y1 %f \n", _x1_, _y1_);				\
26335c4bbdfSmrg	if (repeat_type != RepeatReflect) {				\
26435c4bbdfSmrg		tx1 = _x1_ - priv->box.x1;				\
26535c4bbdfSmrg		ty1 = _y1_ - priv->box.y1;				\
26635c4bbdfSmrg	} else			\
26735c4bbdfSmrg                _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \
26835c4bbdfSmrg				  tx1, ty1, 				\
26935c4bbdfSmrg				  _x1_, _y1_);				\
27035c4bbdfSmrg	DEBUGF("tx1 %f ty1 %f \n", tx1, ty1);				\
27135c4bbdfSmrg   } while(0)
27235c4bbdfSmrg
27335c4bbdfSmrg/* _x1_ ... _y2_ must be integer. */
27435c4bbdfSmrg#define glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1,		\
27535c4bbdfSmrg				 ty1, tx2, ty2, _x1_, _y1_, _x2_,	\
27635c4bbdfSmrg				 _y2_) 					\
27735c4bbdfSmrg  do {									\
27835c4bbdfSmrg	int c, d;							\
27935c4bbdfSmrg	int odd_x = 0, odd_y = 0;					\
28035c4bbdfSmrg	DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n",		\
28135c4bbdfSmrg		(pixmap)->drawable.width,			\
28235c4bbdfSmrg		priv->box.x1, priv->box.x2,				\
28335c4bbdfSmrg		priv->box.y1, priv->box.y2);				\
28435c4bbdfSmrg	modulus((_x1_), (pixmap)->drawable.width, c); 	\
28535c4bbdfSmrg	modulus((_y1_), (pixmap)->drawable.height, d);	\
28635c4bbdfSmrg	DEBUGF("c %d d %d \n", c, d);					\
28735c4bbdfSmrg	if (repeat_type == RepeatReflect) {				\
28835c4bbdfSmrg		odd_x = abs((_x1_ - c)					\
28935c4bbdfSmrg                            / ((pixmap)->drawable.width)) & 1;            \
29035c4bbdfSmrg		odd_y = abs((_y1_ - d)					\
29135c4bbdfSmrg                            / ((pixmap)->drawable.height)) & 1;           \
29235c4bbdfSmrg	}								\
29335c4bbdfSmrg	_glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, ty1, tx2, ty2, \
29435c4bbdfSmrg				  _x1_, _y1_, _x2_, _y2_, c, d,		\
29535c4bbdfSmrg				  odd_x, odd_y);			\
29635c4bbdfSmrg   } while(0)
29735c4bbdfSmrg
29835c4bbdfSmrg#define glamor_transform_point(matrix, tx, ty, x, y)			\
29935c4bbdfSmrg  do {									\
30035c4bbdfSmrg    int _i_;								\
30135c4bbdfSmrg    float _result_[4];							\
30235c4bbdfSmrg    for (_i_ = 0; _i_ < 3; _i_++) {					\
30335c4bbdfSmrg      _result_[_i_] = (matrix)[_i_ * 3] * (x) + (matrix)[_i_ * 3 + 1] * (y)	\
30435c4bbdfSmrg	+ (matrix)[_i_ * 3 + 2];					\
30535c4bbdfSmrg    }									\
30635c4bbdfSmrg    tx = _result_[0] / _result_[2];					\
30735c4bbdfSmrg    ty = _result_[1] / _result_[2];					\
30835c4bbdfSmrg  } while(0)
30935c4bbdfSmrg
31035c4bbdfSmrg#define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_,	\
31135c4bbdfSmrg				     texcoord)                          \
31235c4bbdfSmrg  do {									\
31335c4bbdfSmrg	(texcoord)[0] = t_from_x_coord_x(xscale, _tx_);			\
31435c4bbdfSmrg        (texcoord)[1] = t_from_x_coord_y(yscale, _ty_);                 \
31535c4bbdfSmrg        DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0],	\
31635c4bbdfSmrg		(texcoord)[1]);						\
31735c4bbdfSmrg  } while(0)
31835c4bbdfSmrg
31935c4bbdfSmrg#define glamor_set_transformed_point(priv, matrix, xscale,              \
32035c4bbdfSmrg				     yscale, texcoord,			\
32135c4bbdfSmrg                                     x, y)				\
32235c4bbdfSmrg  do {									\
32335c4bbdfSmrg    float tx, ty;							\
32435c4bbdfSmrg    int fbo_x_off, fbo_y_off;						\
32535c4bbdfSmrg    pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
32635c4bbdfSmrg    glamor_transform_point(matrix, tx, ty, x, y);			\
32735c4bbdfSmrg    DEBUGF("tx %f ty %f fbooff %d %d \n",				\
32835c4bbdfSmrg	    tx, ty, fbo_x_off, fbo_y_off);				\
32935c4bbdfSmrg									\
33035c4bbdfSmrg    tx += fbo_x_off;							\
33135c4bbdfSmrg    ty += fbo_y_off;							\
33235c4bbdfSmrg    (texcoord)[0] = t_from_x_coord_x(xscale, tx);			\
33335c4bbdfSmrg    (texcoord)[1] = t_from_x_coord_y(yscale, ty);                       \
33435c4bbdfSmrg    DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]);	\
33535c4bbdfSmrg  } while(0)
33635c4bbdfSmrg
33735c4bbdfSmrg#define glamor_set_transformed_normalize_tcoords_ext( priv,		\
33835c4bbdfSmrg						  matrix,		\
33935c4bbdfSmrg						  xscale,		\
34035c4bbdfSmrg						  yscale,		\
34135c4bbdfSmrg                                                  tx1, ty1, tx2, ty2,   \
34235c4bbdfSmrg                                                  texcoords,		\
34335c4bbdfSmrg						  stride)		\
34435c4bbdfSmrg  do {									\
34535c4bbdfSmrg    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
34635c4bbdfSmrg				 texcoords, tx1, ty1);                  \
34735c4bbdfSmrg    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
34835c4bbdfSmrg				 texcoords + 1 * stride, tx2, ty1);     \
34935c4bbdfSmrg    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
35035c4bbdfSmrg				 texcoords + 2 * stride, tx2, ty2);     \
35135c4bbdfSmrg    glamor_set_transformed_point(priv, matrix, xscale, yscale,		\
35235c4bbdfSmrg				 texcoords + 3 * stride, tx1, ty2);     \
35335c4bbdfSmrg  } while (0)
35435c4bbdfSmrg
35535c4bbdfSmrg#define glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, \
35635c4bbdfSmrg							 repeat_type,	\
35735c4bbdfSmrg							 matrix,	\
35835c4bbdfSmrg							 xscale,	\
35935c4bbdfSmrg							 yscale,	\
36035c4bbdfSmrg							 _x1_, _y1_,	\
36135c4bbdfSmrg							 _x2_, _y2_,   	\
36235c4bbdfSmrg							 texcoords,	\
36335c4bbdfSmrg							 stride)	\
36435c4bbdfSmrg  do {									\
36535c4bbdfSmrg    if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) {		\
36635c4bbdfSmrg	glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale,	\
36735c4bbdfSmrg						 yscale, _x1_, _y1_,	\
36835c4bbdfSmrg						 _x2_, _y2_,	\
36935c4bbdfSmrg						 texcoords, stride);	\
37035c4bbdfSmrg    } else {								\
37135c4bbdfSmrg    float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;			\
37235c4bbdfSmrg    float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4;		\
37335c4bbdfSmrg    DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_);	\
37435c4bbdfSmrg    glamor_transform_point(matrix, tx1, ty1, _x1_, _y1_);		\
37535c4bbdfSmrg    glamor_transform_point(matrix, tx2, ty2, _x2_, _y1_);		\
37635c4bbdfSmrg    glamor_transform_point(matrix, tx3, ty3, _x2_, _y2_);		\
37735c4bbdfSmrg    glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_);		\
37835c4bbdfSmrg    DEBUGF("transformed %f %f %f %f %f %f %f %f\n",			\
37935c4bbdfSmrg	   tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);			\
38035c4bbdfSmrg    glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
38135c4bbdfSmrg				       ttx1, tty1, 			\
38235c4bbdfSmrg				       tx1, ty1);			\
38335c4bbdfSmrg    glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, 	\
38435c4bbdfSmrg				       ttx2, tty2, 			\
38535c4bbdfSmrg				       tx2, ty2);			\
38635c4bbdfSmrg    glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, 	\
38735c4bbdfSmrg				       ttx3, tty3, 			\
38835c4bbdfSmrg				       tx3, ty3);			\
38935c4bbdfSmrg    glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, 	\
39035c4bbdfSmrg				       ttx4, tty4, 			\
39135c4bbdfSmrg				       tx4, ty4);			\
39235c4bbdfSmrg    DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, 	\
39335c4bbdfSmrg	    ttx2, tty2,	ttx3, tty3, ttx4, tty4);			\
39435c4bbdfSmrg    _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1,		\
39535c4bbdfSmrg				 texcoords);			\
39635c4bbdfSmrg    _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2,		\
39735c4bbdfSmrg				 texcoords + 1 * stride);	\
39835c4bbdfSmrg    _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3,		\
39935c4bbdfSmrg				 texcoords + 2 * stride);	\
40035c4bbdfSmrg    _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4,		\
40135c4bbdfSmrg				 texcoords + 3 * stride);	\
40235c4bbdfSmrg   }									\
40335c4bbdfSmrg  } while (0)
40435c4bbdfSmrg
40535c4bbdfSmrg#define glamor_set_repeat_transformed_normalize_tcoords( pixmap,        \
40635c4bbdfSmrg                                                         priv,          \
40735c4bbdfSmrg							 repeat_type,	\
40835c4bbdfSmrg							 matrix,	\
40935c4bbdfSmrg							 xscale,	\
41035c4bbdfSmrg							 yscale,	\
41135c4bbdfSmrg							 _x1_, _y1_,	\
41235c4bbdfSmrg							 _x2_, _y2_,   	\
41335c4bbdfSmrg							 texcoords)	\
41435c4bbdfSmrg  do {									\
41535c4bbdfSmrg      glamor_set_repeat_transformed_normalize_tcoords_ext( pixmap,      \
41635c4bbdfSmrg                                                           priv,	\
41735c4bbdfSmrg							 repeat_type,	\
41835c4bbdfSmrg							 matrix,	\
41935c4bbdfSmrg							 xscale,	\
42035c4bbdfSmrg							 yscale,	\
42135c4bbdfSmrg							 _x1_, _y1_,	\
42235c4bbdfSmrg							 _x2_, _y2_,   	\
42335c4bbdfSmrg							 texcoords,	\
42435c4bbdfSmrg							 2);	\
42535c4bbdfSmrg  } while (0)
42635c4bbdfSmrg
42735c4bbdfSmrg#define _glamor_set_normalize_tcoords(xscale, yscale, tx1,		\
42835c4bbdfSmrg				      ty1, tx2, ty2,			\
42935c4bbdfSmrg				      vertices, stride)                 \
43035c4bbdfSmrg  do {									\
43135c4bbdfSmrg    /* vertices may be write-only, so we use following			\
43235c4bbdfSmrg     * temporary variable. */ 						\
43335c4bbdfSmrg    float _t0_, _t1_, _t2_, _t5_;					\
43435c4bbdfSmrg    (vertices)[0] = _t0_ = t_from_x_coord_x(xscale, tx1);		\
43535c4bbdfSmrg    (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2);	\
43635c4bbdfSmrg    (vertices)[2 * stride] = _t2_;					\
43735c4bbdfSmrg    (vertices)[3 * stride] = _t0_;					\
43835c4bbdfSmrg    (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1);               \
43935c4bbdfSmrg    (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2);  \
44035c4bbdfSmrg    (vertices)[1 * stride + 1] = _t1_;					\
44135c4bbdfSmrg    (vertices)[3 * stride + 1] = _t5_;					\
44235c4bbdfSmrg  } while(0)
44335c4bbdfSmrg
44435c4bbdfSmrg#define glamor_set_normalize_tcoords_ext(priv, xscale, yscale,		\
44535c4bbdfSmrg				     x1, y1, x2, y2,			\
44635c4bbdfSmrg                                     vertices, stride)	\
44735c4bbdfSmrg  do {									\
44835c4bbdfSmrg     if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) {		\
44935c4bbdfSmrg	float tx1, tx2, ty1, ty2;					\
45035c4bbdfSmrg	int fbo_x_off, fbo_y_off;					\
45135c4bbdfSmrg	pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
45235c4bbdfSmrg	tx1 = x1 + fbo_x_off; 						\
45335c4bbdfSmrg	tx2 = x2 + fbo_x_off;						\
45435c4bbdfSmrg	ty1 = y1 + fbo_y_off;						\
45535c4bbdfSmrg	ty2 = y2 + fbo_y_off;						\
45635c4bbdfSmrg	_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
45735c4bbdfSmrg                                      tx2, ty2, vertices,               \
45835c4bbdfSmrg				   stride);				\
45935c4bbdfSmrg     } else								\
46035c4bbdfSmrg	_glamor_set_normalize_tcoords(xscale, yscale, x1, y1,		\
46135c4bbdfSmrg                                      x2, y2, vertices, stride);        \
46235c4bbdfSmrg } while(0)
46335c4bbdfSmrg
46435c4bbdfSmrg#define glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type, \
46535c4bbdfSmrg					    xscale, yscale,		\
46635c4bbdfSmrg					    _x1_, _y1_, _x2_, _y2_,	\
46735c4bbdfSmrg	                                    vertices, stride)		\
46835c4bbdfSmrg  do {									\
46935c4bbdfSmrg     if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) {		\
47035c4bbdfSmrg	float tx1, tx2, ty1, ty2;					\
47135c4bbdfSmrg	if (repeat_type == RepeatPad) {					\
47235c4bbdfSmrg		tx1 = _x1_ - priv->box.x1;			        \
47335c4bbdfSmrg		ty1 = _y1_ - priv->box.y1;			        \
47435c4bbdfSmrg		tx2 = tx1 + ((_x2_) - (_x1_));				\
47535c4bbdfSmrg		ty2 = ty1 + ((_y2_) - (_y1_));				\
47635c4bbdfSmrg	} else {							\
47735c4bbdfSmrg            glamor_get_repeat_coords(pixmap, priv, repeat_type,         \
47835c4bbdfSmrg				 tx1, ty1, tx2, ty2,			\
47935c4bbdfSmrg				 _x1_, _y1_, _x2_, _y2_);		\
48035c4bbdfSmrg	}								\
48135c4bbdfSmrg	_glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1,		\
48235c4bbdfSmrg                                      tx2, ty2, vertices,               \
48335c4bbdfSmrg				   stride);				\
48435c4bbdfSmrg     } else								\
48535c4bbdfSmrg	_glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_,	\
48635c4bbdfSmrg                                      _x2_, _y2_, vertices,             \
48735c4bbdfSmrg				   stride);				\
48835c4bbdfSmrg } while(0)
48935c4bbdfSmrg
49035c4bbdfSmrg#define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale,		\
49135c4bbdfSmrg						x1, y1, x2, y2,		\
49235c4bbdfSmrg						vertices)               \
49335c4bbdfSmrg    do {								\
49435c4bbdfSmrg	(vertices)[0] = t_from_x_coord_x(xscale, x1);			\
49535c4bbdfSmrg	(vertices)[2] = t_from_x_coord_x(xscale, x2);			\
49635c4bbdfSmrg	(vertices)[6] = (vertices)[2];					\
49735c4bbdfSmrg	(vertices)[4] = (vertices)[0];					\
49835c4bbdfSmrg        (vertices)[1] = t_from_x_coord_y(yscale, y1);                   \
49935c4bbdfSmrg        (vertices)[7] = t_from_x_coord_y(yscale, y2);                   \
50035c4bbdfSmrg	(vertices)[3] = (vertices)[1];					\
50135c4bbdfSmrg	(vertices)[5] = (vertices)[7];					\
50235c4bbdfSmrg    } while(0)
50335c4bbdfSmrg
50435c4bbdfSmrg#define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices)          \
50535c4bbdfSmrg    do {								\
50635c4bbdfSmrg	(vertices)[0] = (x1);						\
50735c4bbdfSmrg	(vertices)[2] = (x2);						\
50835c4bbdfSmrg	(vertices)[6] = (vertices)[2];					\
50935c4bbdfSmrg	(vertices)[4] = (vertices)[0];					\
51035c4bbdfSmrg        (vertices)[1] = (y1);                                           \
51135c4bbdfSmrg        (vertices)[7] = (y2);                                           \
51235c4bbdfSmrg	(vertices)[3] = (vertices)[1];					\
51335c4bbdfSmrg	(vertices)[5] = (vertices)[7];					\
51435c4bbdfSmrg    } while(0)
51535c4bbdfSmrg
51635c4bbdfSmrg#define glamor_set_normalize_vcoords_ext(priv, xscale, yscale,		\
51735c4bbdfSmrg				     x1, y1, x2, y2,			\
51835c4bbdfSmrg                                         vertices, stride)              \
51935c4bbdfSmrg  do {									\
52035c4bbdfSmrg    int fbo_x_off, fbo_y_off;						\
52135c4bbdfSmrg    /* vertices may be write-only, so we use following			\
52235c4bbdfSmrg     * temporary variable. */						\
52335c4bbdfSmrg    float _t0_, _t1_, _t2_, _t5_;					\
52435c4bbdfSmrg    pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off);		\
52535c4bbdfSmrg    (vertices)[0] = _t0_ = v_from_x_coord_x(xscale, x1 + fbo_x_off);	\
52635c4bbdfSmrg    (vertices)[1 * stride] = _t2_ = v_from_x_coord_x(xscale,		\
52735c4bbdfSmrg					x2 + fbo_x_off);		\
52835c4bbdfSmrg    (vertices)[2 * stride] = _t2_;					\
52935c4bbdfSmrg    (vertices)[3 * stride] = _t0_;					\
53035c4bbdfSmrg    (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off);    \
53135c4bbdfSmrg    (vertices)[2 * stride + 1] = _t5_ =                                 \
53235c4bbdfSmrg        v_from_x_coord_y(yscale, y2 + fbo_y_off);                       \
53335c4bbdfSmrg    (vertices)[1 * stride + 1] = _t1_;					\
53435c4bbdfSmrg    (vertices)[3 * stride + 1] = _t5_;					\
53535c4bbdfSmrg  } while(0)
53635c4bbdfSmrg
53735c4bbdfSmrg#define glamor_set_normalize_vcoords_tri_strip(xscale, yscale,		\
53835c4bbdfSmrg					       x1, y1, x2, y2,		\
53935c4bbdfSmrg					       vertices)		\
54035c4bbdfSmrg    do {								\
54135c4bbdfSmrg	(vertices)[0] = v_from_x_coord_x(xscale, x1);			\
54235c4bbdfSmrg	(vertices)[2] = v_from_x_coord_x(xscale, x2);			\
54335c4bbdfSmrg	(vertices)[6] = (vertices)[2];					\
54435c4bbdfSmrg	(vertices)[4] = (vertices)[0];					\
54535c4bbdfSmrg        (vertices)[1] = v_from_x_coord_y(yscale, y1);                   \
54635c4bbdfSmrg        (vertices)[7] = v_from_x_coord_y(yscale, y2);                   \
54735c4bbdfSmrg	(vertices)[3] = (vertices)[1];					\
54835c4bbdfSmrg	(vertices)[5] = (vertices)[7];					\
54935c4bbdfSmrg    } while(0)
55035c4bbdfSmrg
55135c4bbdfSmrg#define glamor_set_normalize_pt(xscale, yscale, x, y,		\
55235c4bbdfSmrg                                pt)				\
55335c4bbdfSmrg    do {							\
55435c4bbdfSmrg        (pt)[0] = t_from_x_coord_x(xscale, x);			\
55535c4bbdfSmrg        (pt)[1] = t_from_x_coord_y(yscale, y);                  \
55635c4bbdfSmrg    } while(0)
55735c4bbdfSmrg
55835c4bbdfSmrg#define glamor_set_circle_centre(width, height, x, y,	\
55935c4bbdfSmrg				 c)		\
56035c4bbdfSmrg    do {						\
56135c4bbdfSmrg        (c)[0] = (float)x;				\
56235c4bbdfSmrg        (c)[1] = (float)y;				\
56335c4bbdfSmrg    } while(0)
56435c4bbdfSmrg
56535c4bbdfSmrg#define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
56635c4bbdfSmrg#define MIN(a,b)	((a) < (b) ? (a) : (b))
56735c4bbdfSmrg#define MAX(a,b)	((a) > (b) ? (a) : (b))
56835c4bbdfSmrg
56935c4bbdfSmrg#define glamor_check_fbo_size(_glamor_,_w_, _h_)    ((_w_) > 0 && (_h_) > 0 \
57035c4bbdfSmrg                                                    && (_w_) <= _glamor_->max_fbo_size  \
57135c4bbdfSmrg                                                    && (_h_) <= _glamor_->max_fbo_size)
57235c4bbdfSmrg
57335c4bbdfSmrg#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)    (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
57435c4bbdfSmrg
57535c4bbdfSmrg#define REVERT_NONE       		0
57635c4bbdfSmrg#define REVERT_NORMAL     		1
57735c4bbdfSmrg#define REVERT_UPLOADING_A1		3
5781b5d61b8Smrg
57935c4bbdfSmrg#define SWAP_UPLOADING	  	2
58035c4bbdfSmrg#define SWAP_NONE_UPLOADING	3
58135c4bbdfSmrg
58235c4bbdfSmrg/* borrowed from uxa */
58335c4bbdfSmrgstatic inline Bool
58435c4bbdfSmrgglamor_get_rgba_from_pixel(CARD32 pixel,
58535c4bbdfSmrg                           float *red,
58635c4bbdfSmrg                           float *green,
58735c4bbdfSmrg                           float *blue, float *alpha, CARD32 format)
58835c4bbdfSmrg{
58935c4bbdfSmrg    int rbits, bbits, gbits, abits;
59035c4bbdfSmrg    int rshift, bshift, gshift, ashift;
59135c4bbdfSmrg
59235c4bbdfSmrg    rbits = PICT_FORMAT_R(format);
59335c4bbdfSmrg    gbits = PICT_FORMAT_G(format);
59435c4bbdfSmrg    bbits = PICT_FORMAT_B(format);
59535c4bbdfSmrg    abits = PICT_FORMAT_A(format);
59635c4bbdfSmrg
59735c4bbdfSmrg    if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
59835c4bbdfSmrg        rshift = gshift = bshift = ashift = 0;
59935c4bbdfSmrg    }
60035c4bbdfSmrg    else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
60135c4bbdfSmrg        bshift = 0;
60235c4bbdfSmrg        gshift = bbits;
60335c4bbdfSmrg        rshift = gshift + gbits;
60435c4bbdfSmrg        ashift = rshift + rbits;
60535c4bbdfSmrg    }
60635c4bbdfSmrg    else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
60735c4bbdfSmrg        rshift = 0;
60835c4bbdfSmrg        gshift = rbits;
60935c4bbdfSmrg        bshift = gshift + gbits;
61035c4bbdfSmrg        ashift = bshift + bbits;
61135c4bbdfSmrg    }
61235c4bbdfSmrg    else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
61335c4bbdfSmrg        ashift = 0;
61435c4bbdfSmrg        rshift = abits;
61535c4bbdfSmrg        if (abits == 0)
61635c4bbdfSmrg            rshift = PICT_FORMAT_BPP(format) - (rbits + gbits + bbits);
61735c4bbdfSmrg        gshift = rshift + rbits;
61835c4bbdfSmrg        bshift = gshift + gbits;
61935c4bbdfSmrg    }
62035c4bbdfSmrg    else {
62135c4bbdfSmrg        return FALSE;
62235c4bbdfSmrg    }
62335c4bbdfSmrg#define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_)	\
62435c4bbdfSmrg  *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1))	\
62535c4bbdfSmrg    / (float)((1<<(_bits_)) - 1)
62635c4bbdfSmrg
62735c4bbdfSmrg    if (rbits)
62835c4bbdfSmrg        COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
62935c4bbdfSmrg    else
63035c4bbdfSmrg        *red = 0;
63135c4bbdfSmrg
63235c4bbdfSmrg    if (gbits)
63335c4bbdfSmrg        COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
63435c4bbdfSmrg    else
63535c4bbdfSmrg        *green = 0;
63635c4bbdfSmrg
63735c4bbdfSmrg    if (bbits)
63835c4bbdfSmrg        COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
63935c4bbdfSmrg    else
64035c4bbdfSmrg        *blue = 0;
64135c4bbdfSmrg
64235c4bbdfSmrg    if (abits)
64335c4bbdfSmrg        COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
64435c4bbdfSmrg    else
64535c4bbdfSmrg        *alpha = 1;
64635c4bbdfSmrg
64735c4bbdfSmrg    return TRUE;
64835c4bbdfSmrg}
64935c4bbdfSmrg
6501b5d61b8Smrgstatic inline void
6511b5d61b8Smrgglamor_get_rgba_from_color(const xRenderColor *color, float rgba[4])
6521b5d61b8Smrg{
6531b5d61b8Smrg    rgba[0] = color->red   / (float)UINT16_MAX;
6541b5d61b8Smrg    rgba[1] = color->green / (float)UINT16_MAX;
6551b5d61b8Smrg    rgba[2] = color->blue  / (float)UINT16_MAX;
6561b5d61b8Smrg    rgba[3] = color->alpha / (float)UINT16_MAX;
6571b5d61b8Smrg}
6581b5d61b8Smrg
65935c4bbdfSmrginline static Bool
66035c4bbdfSmrgglamor_is_large_pixmap(PixmapPtr pixmap)
66135c4bbdfSmrg{
66235c4bbdfSmrg    glamor_pixmap_private *priv;
66335c4bbdfSmrg
66435c4bbdfSmrg    priv = glamor_get_pixmap_private(pixmap);
66535c4bbdfSmrg    return (glamor_pixmap_priv_is_large(priv));
66635c4bbdfSmrg}
66735c4bbdfSmrg
66835c4bbdfSmrgstatic inline void
6691b5d61b8Smrgglamor_make_current(glamor_screen_private *glamor_priv)
67035c4bbdfSmrg{
6711b5d61b8Smrg    if (lastGLContext != glamor_priv->ctx.ctx) {
6721b5d61b8Smrg        lastGLContext = glamor_priv->ctx.ctx;
6731b5d61b8Smrg        glamor_priv->ctx.make_current(&glamor_priv->ctx);
67435c4bbdfSmrg    }
67535c4bbdfSmrg}
67635c4bbdfSmrg
6771b5d61b8Smrgstatic inline BoxRec
6781b5d61b8Smrgglamor_no_rendering_bounds(void)
67935c4bbdfSmrg{
6801b5d61b8Smrg    BoxRec bounds = {
6811b5d61b8Smrg        .x1 = 0,
6821b5d61b8Smrg        .y1 = 0,
6831b5d61b8Smrg        .x2 = MAXSHORT,
6841b5d61b8Smrg        .y2 = MAXSHORT,
6851b5d61b8Smrg    };
6861b5d61b8Smrg
6871b5d61b8Smrg    return bounds;
68835c4bbdfSmrg}
68935c4bbdfSmrg
6901b5d61b8Smrgstatic inline BoxRec
6911b5d61b8Smrgglamor_start_rendering_bounds(void)
69235c4bbdfSmrg{
6931b5d61b8Smrg    BoxRec bounds = {
6941b5d61b8Smrg        .x1 = MAXSHORT,
6951b5d61b8Smrg        .y1 = MAXSHORT,
6961b5d61b8Smrg        .x2 = 0,
6971b5d61b8Smrg        .y2 = 0,
6981b5d61b8Smrg    };
6991b5d61b8Smrg
7001b5d61b8Smrg    return bounds;
70135c4bbdfSmrg}
70235c4bbdfSmrg
70335c4bbdfSmrgstatic inline void
7041b5d61b8Smrgglamor_bounds_union_rect(BoxPtr bounds, xRectangle *rect)
70535c4bbdfSmrg{
7061b5d61b8Smrg    bounds->x1 = min(bounds->x1, rect->x);
7071b5d61b8Smrg    bounds->y1 = min(bounds->y1, rect->y);
7081b5d61b8Smrg    bounds->x2 = min(SHRT_MAX, max(bounds->x2, rect->x + rect->width));
7091b5d61b8Smrg    bounds->y2 = min(SHRT_MAX, max(bounds->y2, rect->y + rect->height));
71035c4bbdfSmrg}
71135c4bbdfSmrg
71235c4bbdfSmrgstatic inline void
7131b5d61b8Smrgglamor_bounds_union_box(BoxPtr bounds, BoxPtr box)
71435c4bbdfSmrg{
7151b5d61b8Smrg    bounds->x1 = min(bounds->x1, box->x1);
7161b5d61b8Smrg    bounds->y1 = min(bounds->y1, box->y1);
7171b5d61b8Smrg    bounds->x2 = max(bounds->x2, box->x2);
7181b5d61b8Smrg    bounds->y2 = max(bounds->y2, box->y2);
71935c4bbdfSmrg}
72035c4bbdfSmrg
72135c4bbdfSmrg/**
72235c4bbdfSmrg * Helper function for implementing draws with GL_QUADS on GLES2,
72335c4bbdfSmrg * where we don't have them.
72435c4bbdfSmrg */
72535c4bbdfSmrgstatic inline void
72635c4bbdfSmrgglamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
72735c4bbdfSmrg{
72835c4bbdfSmrg    if (glamor_priv->use_quads) {
72935c4bbdfSmrg        glDrawArrays(GL_QUADS, 0, count * 4);
73035c4bbdfSmrg    } else {
73135c4bbdfSmrg        glamor_gldrawarrays_quads_using_indices(glamor_priv, count);
73235c4bbdfSmrg    }
73335c4bbdfSmrg}
73435c4bbdfSmrg
735ed6184dfSmrgstatic inline Bool
736ed6184dfSmrgglamor_glsl_has_ints(glamor_screen_private *glamor_priv) {
737ed6184dfSmrg    return glamor_priv->glsl_version >= 130 || glamor_priv->use_gpu_shader4;
738ed6184dfSmrg}
73935c4bbdfSmrg
74035c4bbdfSmrg#endif
741