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