os: if inet_ntop() is available, use it for IPv4 addresses as well
[xserver.git] / glamor / glamor_utils.h
blobbee48d9892c04ba4fa6834de191cb6b6cf294d71
1 /*
2 * Copyright © 2009 Intel Corporation
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:
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.
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.
23 * Authors:
24 * Zhigang Gong <zhigang.gong@linux.intel.com>
28 #ifndef GLAMOR_PRIV_H
29 #error This file can only be included by glamor_priv.h
30 #endif
32 #ifndef __GLAMOR_UTILS_H__
33 #define __GLAMOR_UTILS_H__
35 #include "glamor_prepare.h"
36 #include "mipict.h"
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_))
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)
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)
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)
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)
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)
89 #define xFixedToFloat(_val_) ((float)xFixedToInt(_val_) \
90 + ((float)xFixedFrac(_val_) / 65536.0))
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]); \
107 } while(0)
109 #define fmod(x, w) (x - w * floor((float)x/w))
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)
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
138 * case 1:
139 * ----------
140 * | * |
141 * | |
142 * ----------
143 * tx = (c - x1) mod w
145 * case 2:
146 * ---------
147 * * | |
148 * | |
149 * ---------
150 * tx = - (c - (x1 mod w))
152 * case 3:
154 * ----------
155 * | | *
156 * | |
157 * ----------
158 * tx = ((x2 mod x) - c) + (x2 - x1)
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); \
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)
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)
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)
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_)); \
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_)); \
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_)); \
252 } while(0)
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)
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; \
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)
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]; \
306 tx = _result_[0] / _result_[2]; \
307 ty = _result_[1] / _result_[2]; \
308 } while(0)
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)
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); \
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)
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)
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); \
403 } while (0)
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)
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)
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)
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_); \
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)
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)
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)
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)
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)
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)
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)
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))
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)
573 #define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
575 #define REVERT_NONE 0
576 #define REVERT_NORMAL 1
577 #define REVERT_UPLOADING_A1 3
579 #define SWAP_UPLOADING 2
580 #define SWAP_NONE_UPLOADING 3
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)
589 int rbits, bbits, gbits, abits;
590 int rshift, bshift, gshift, ashift;
592 rbits = PICT_FORMAT_R(format);
593 gbits = PICT_FORMAT_G(format);
594 bbits = PICT_FORMAT_B(format);
595 abits = PICT_FORMAT_A(format);
597 if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
598 rshift = gshift = bshift = ashift = 0;
600 else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
601 bshift = 0;
602 gshift = bbits;
603 rshift = gshift + gbits;
604 ashift = rshift + rbits;
606 else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
607 rshift = 0;
608 gshift = rbits;
609 bshift = gshift + gbits;
610 ashift = bshift + bbits;
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;
620 else {
621 return FALSE;
623 #define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_) \
624 *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1)) \
625 / (float)((1<<(_bits_)) - 1)
627 if (rbits)
628 COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
629 else
630 *red = 0;
632 if (gbits)
633 COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
634 else
635 *green = 0;
637 if (bbits)
638 COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
639 else
640 *blue = 0;
642 if (abits)
643 COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
644 else
645 *alpha = 1;
647 return TRUE;
650 static inline void
651 glamor_get_rgba_from_color(const xRenderColor *color, float rgba[4])
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;
659 inline static Bool
660 glamor_is_large_pixmap(PixmapPtr pixmap)
662 glamor_pixmap_private *priv;
664 priv = glamor_get_pixmap_private(pixmap);
665 return (glamor_pixmap_priv_is_large(priv));
668 static inline void
669 glamor_make_current(glamor_screen_private *glamor_priv)
671 if (lastGLContext != glamor_priv->ctx.ctx) {
672 lastGLContext = glamor_priv->ctx.ctx;
673 glamor_priv->ctx.make_current(&glamor_priv->ctx);
675 glamor_priv->dirty = TRUE;
678 static inline void
679 glamor_flush(glamor_screen_private *glamor_priv)
681 if (glamor_priv->dirty) {
682 glamor_make_current(glamor_priv);
683 glFlush();
684 glamor_priv->dirty = FALSE;
688 static inline BoxRec
689 glamor_no_rendering_bounds(void)
691 BoxRec bounds = {
692 .x1 = 0,
693 .y1 = 0,
694 .x2 = MAXSHORT,
695 .y2 = MAXSHORT,
698 return bounds;
701 static inline BoxRec
702 glamor_start_rendering_bounds(void)
704 BoxRec bounds = {
705 .x1 = MAXSHORT,
706 .y1 = MAXSHORT,
707 .x2 = 0,
708 .y2 = 0,
711 return bounds;
714 static inline void
715 glamor_bounds_union_rect(BoxPtr bounds, xRectangle *rect)
717 bounds->x1 = min(bounds->x1, rect->x);
718 bounds->y1 = min(bounds->y1, rect->y);
719 bounds->x2 = min(SHRT_MAX, max(bounds->x2, rect->x + rect->width));
720 bounds->y2 = min(SHRT_MAX, max(bounds->y2, rect->y + rect->height));
723 static inline void
724 glamor_bounds_union_box(BoxPtr bounds, BoxPtr box)
726 bounds->x1 = min(bounds->x1, box->x1);
727 bounds->y1 = min(bounds->y1, box->y1);
728 bounds->x2 = max(bounds->x2, box->x2);
729 bounds->y2 = max(bounds->y2, box->y2);
733 * Helper function for implementing draws with GL_QUADS on GLES2,
734 * where we don't have them.
736 static inline void
737 glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
739 if (glamor_priv->use_quads) {
740 glDrawArrays(GL_QUADS, 0, count * 4);
741 } else {
742 glamor_gldrawarrays_quads_using_indices(glamor_priv, count);
746 static inline Bool
747 glamor_glsl_has_ints(glamor_screen_private *glamor_priv) {
748 return glamor_priv->glsl_version >= 130 || glamor_priv->use_gpu_shader4;
751 #endif