glamor_utils.h revision 35c4bbdf
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_tri_tcoords(priv, \ 338 matrix, \ 339 xscale, \ 340 yscale, \ 341 vtx, \ 342 texcoords) \ 343 do { \ 344 glamor_set_transformed_point(priv, matrix, xscale, yscale, \ 345 texcoords, (vtx)[0], (vtx)[1]); \ 346 glamor_set_transformed_point(priv, matrix, xscale, yscale, \ 347 texcoords+2, (vtx)[2], (vtx)[3]); \ 348 glamor_set_transformed_point(priv, matrix, xscale, yscale, \ 349 texcoords+4, (vtx)[4], (vtx)[5]); \ 350 } while (0) 351 352#define glamor_set_transformed_normalize_tcoords_ext( priv, \ 353 matrix, \ 354 xscale, \ 355 yscale, \ 356 tx1, ty1, tx2, ty2, \ 357 texcoords, \ 358 stride) \ 359 do { \ 360 glamor_set_transformed_point(priv, matrix, xscale, yscale, \ 361 texcoords, tx1, ty1); \ 362 glamor_set_transformed_point(priv, matrix, xscale, yscale, \ 363 texcoords + 1 * stride, tx2, ty1); \ 364 glamor_set_transformed_point(priv, matrix, xscale, yscale, \ 365 texcoords + 2 * stride, tx2, ty2); \ 366 glamor_set_transformed_point(priv, matrix, xscale, yscale, \ 367 texcoords + 3 * stride, tx1, ty2); \ 368 } while (0) 369 370#define glamor_set_transformed_normalize_tcoords( priv, \ 371 matrix, \ 372 xscale, \ 373 yscale, \ 374 tx1, ty1, tx2, ty2, \ 375 texcoords) \ 376 do { \ 377 glamor_set_transformed_normalize_tcoords_ext( priv, \ 378 matrix, \ 379 xscale, \ 380 yscale, \ 381 tx1, ty1, tx2, ty2, \ 382 texcoords, \ 383 2); \ 384 } while (0) 385 386#define glamor_set_normalize_tri_tcoords(xscale, \ 387 yscale, \ 388 vtx, \ 389 texcoords) \ 390 do { \ 391 _glamor_set_normalize_tpoint(xscale, yscale, \ 392 (vtx)[0], (vtx)[1], \ 393 texcoords); \ 394 _glamor_set_normalize_tpoint(xscale, yscale, \ 395 (vtx)[2], (vtx)[3], \ 396 texcoords+2); \ 397 _glamor_set_normalize_tpoint(xscale, yscale, \ 398 (vtx)[4], (vtx)[5], \ 399 texcoords+4); \ 400 } while (0) 401 402#define glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, \ 403 repeat_type, \ 404 matrix, \ 405 xscale, \ 406 yscale, \ 407 _x1_, _y1_, \ 408 _x2_, _y2_, \ 409 texcoords, \ 410 stride) \ 411 do { \ 412 if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) { \ 413 glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \ 414 yscale, _x1_, _y1_, \ 415 _x2_, _y2_, \ 416 texcoords, stride); \ 417 } else { \ 418 float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \ 419 float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4; \ 420 DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_); \ 421 glamor_transform_point(matrix, tx1, ty1, _x1_, _y1_); \ 422 glamor_transform_point(matrix, tx2, ty2, _x2_, _y1_); \ 423 glamor_transform_point(matrix, tx3, ty3, _x2_, _y2_); \ 424 glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_); \ 425 DEBUGF("transformed %f %f %f %f %f %f %f %f\n", \ 426 tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4); \ 427 glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \ 428 ttx1, tty1, \ 429 tx1, ty1); \ 430 glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \ 431 ttx2, tty2, \ 432 tx2, ty2); \ 433 glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \ 434 ttx3, tty3, \ 435 tx3, ty3); \ 436 glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \ 437 ttx4, tty4, \ 438 tx4, ty4); \ 439 DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \ 440 ttx2, tty2, ttx3, tty3, ttx4, tty4); \ 441 _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \ 442 texcoords); \ 443 _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \ 444 texcoords + 1 * stride); \ 445 _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \ 446 texcoords + 2 * stride); \ 447 _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \ 448 texcoords + 3 * stride); \ 449 } \ 450 } while (0) 451 452#define glamor_set_repeat_transformed_normalize_tcoords( pixmap, \ 453 priv, \ 454 repeat_type, \ 455 matrix, \ 456 xscale, \ 457 yscale, \ 458 _x1_, _y1_, \ 459 _x2_, _y2_, \ 460 texcoords) \ 461 do { \ 462 glamor_set_repeat_transformed_normalize_tcoords_ext( pixmap, \ 463 priv, \ 464 repeat_type, \ 465 matrix, \ 466 xscale, \ 467 yscale, \ 468 _x1_, _y1_, \ 469 _x2_, _y2_, \ 470 texcoords, \ 471 2); \ 472 } while (0) 473 474#define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \ 475 ty1, tx2, ty2, \ 476 vertices, stride) \ 477 do { \ 478 /* vertices may be write-only, so we use following \ 479 * temporary variable. */ \ 480 float _t0_, _t1_, _t2_, _t5_; \ 481 (vertices)[0] = _t0_ = t_from_x_coord_x(xscale, tx1); \ 482 (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \ 483 (vertices)[2 * stride] = _t2_; \ 484 (vertices)[3 * stride] = _t0_; \ 485 (vertices)[1] = _t1_ = t_from_x_coord_y(yscale, ty1); \ 486 (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y(yscale, ty2); \ 487 (vertices)[1 * stride + 1] = _t1_; \ 488 (vertices)[3 * stride + 1] = _t5_; \ 489 } while(0) 490 491#define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \ 492 x1, y1, x2, y2, \ 493 vertices, stride) \ 494 do { \ 495 if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \ 496 float tx1, tx2, ty1, ty2; \ 497 int fbo_x_off, fbo_y_off; \ 498 pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \ 499 tx1 = x1 + fbo_x_off; \ 500 tx2 = x2 + fbo_x_off; \ 501 ty1 = y1 + fbo_y_off; \ 502 ty2 = y2 + fbo_y_off; \ 503 _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ 504 tx2, ty2, vertices, \ 505 stride); \ 506 } else \ 507 _glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \ 508 x2, y2, vertices, stride); \ 509 } while(0) 510 511#define glamor_set_normalize_tcoords(priv, xscale, yscale, \ 512 x1, y1, x2, y2, \ 513 vertices) \ 514 do { \ 515 glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \ 516 x1, y1, x2, y2, \ 517 vertices, 2); \ 518 } while(0) 519 520#define glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type, \ 521 xscale, yscale, \ 522 _x1_, _y1_, _x2_, _y2_, \ 523 vertices, stride) \ 524 do { \ 525 if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \ 526 float tx1, tx2, ty1, ty2; \ 527 if (repeat_type == RepeatPad) { \ 528 tx1 = _x1_ - priv->box.x1; \ 529 ty1 = _y1_ - priv->box.y1; \ 530 tx2 = tx1 + ((_x2_) - (_x1_)); \ 531 ty2 = ty1 + ((_y2_) - (_y1_)); \ 532 } else { \ 533 glamor_get_repeat_coords(pixmap, priv, repeat_type, \ 534 tx1, ty1, tx2, ty2, \ 535 _x1_, _y1_, _x2_, _y2_); \ 536 } \ 537 _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \ 538 tx2, ty2, vertices, \ 539 stride); \ 540 } else \ 541 _glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \ 542 _x2_, _y2_, vertices, \ 543 stride); \ 544 } while(0) 545 546#define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \ 547 xscale, yscale, \ 548 _x1_, _y1_, _x2_, _y2_, \ 549 vertices) \ 550 do { \ 551 glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \ 552 xscale, yscale, \ 553 _x1_, _y1_, _x2_, _y2_, \ 554 vertices, 2); \ 555 } while(0) 556 557#define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \ 558 x1, y1, x2, y2, \ 559 vertices) \ 560 do { \ 561 (vertices)[0] = t_from_x_coord_x(xscale, x1); \ 562 (vertices)[2] = t_from_x_coord_x(xscale, x2); \ 563 (vertices)[6] = (vertices)[2]; \ 564 (vertices)[4] = (vertices)[0]; \ 565 (vertices)[1] = t_from_x_coord_y(yscale, y1); \ 566 (vertices)[7] = t_from_x_coord_y(yscale, y2); \ 567 (vertices)[3] = (vertices)[1]; \ 568 (vertices)[5] = (vertices)[7]; \ 569 } while(0) 570 571#define glamor_set_tcoords(x1, y1, x2, y2, vertices) \ 572 do { \ 573 (vertices)[0] = (x1); \ 574 (vertices)[2] = (x2); \ 575 (vertices)[4] = (vertices)[2]; \ 576 (vertices)[6] = (vertices)[0]; \ 577 (vertices)[1] = (y1); \ 578 (vertices)[5] = (y2); \ 579 (vertices)[3] = (vertices)[1]; \ 580 (vertices)[7] = (vertices)[5]; \ 581 } while(0) 582 583#define glamor_set_tcoords_ext(x1, y1, x2, y2, vertices, stride) \ 584 do { \ 585 (vertices)[0] = (x1); \ 586 (vertices)[1*stride] = (x2); \ 587 (vertices)[2*stride] = (vertices)[1*stride]; \ 588 (vertices)[3*stride] = (vertices)[0]; \ 589 (vertices)[1] = (y1); \ 590 (vertices)[2*stride + 1] = (y2); \ 591 (vertices)[1*stride + 1] = (vertices)[1]; \ 592 (vertices)[3*stride + 1] = (vertices)[2*stride + 1]; \ 593 } while(0) 594 595#define glamor_set_normalize_one_vcoord(xscale, yscale, x, y, \ 596 vertices) \ 597 do { \ 598 (vertices)[0] = v_from_x_coord_x(xscale, x); \ 599 (vertices)[1] = v_from_x_coord_y(yscale, y); \ 600 } while(0) 601 602#define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \ 603 vertices) \ 604 do { \ 605 glamor_set_normalize_one_vcoord(xscale, yscale, \ 606 (vtx)[0], (vtx)[1], \ 607 vertices); \ 608 glamor_set_normalize_one_vcoord(xscale, yscale, \ 609 (vtx)[2], (vtx)[3], \ 610 vertices+2); \ 611 glamor_set_normalize_one_vcoord(xscale, yscale, \ 612 (vtx)[4], (vtx)[5], \ 613 vertices+4); \ 614 } while(0) 615 616#define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices) \ 617 do { \ 618 (vertices)[0] = (x1); \ 619 (vertices)[2] = (x2); \ 620 (vertices)[6] = (vertices)[2]; \ 621 (vertices)[4] = (vertices)[0]; \ 622 (vertices)[1] = (y1); \ 623 (vertices)[7] = (y2); \ 624 (vertices)[3] = (vertices)[1]; \ 625 (vertices)[5] = (vertices)[7]; \ 626 } while(0) 627 628#define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \ 629 x1, y1, x2, y2, \ 630 vertices, stride) \ 631 do { \ 632 int fbo_x_off, fbo_y_off; \ 633 /* vertices may be write-only, so we use following \ 634 * temporary variable. */ \ 635 float _t0_, _t1_, _t2_, _t5_; \ 636 pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \ 637 (vertices)[0] = _t0_ = v_from_x_coord_x(xscale, x1 + fbo_x_off); \ 638 (vertices)[1 * stride] = _t2_ = v_from_x_coord_x(xscale, \ 639 x2 + fbo_x_off); \ 640 (vertices)[2 * stride] = _t2_; \ 641 (vertices)[3 * stride] = _t0_; \ 642 (vertices)[1] = _t1_ = v_from_x_coord_y(yscale, y1 + fbo_y_off); \ 643 (vertices)[2 * stride + 1] = _t5_ = \ 644 v_from_x_coord_y(yscale, y2 + fbo_y_off); \ 645 (vertices)[1 * stride + 1] = _t1_; \ 646 (vertices)[3 * stride + 1] = _t5_; \ 647 } while(0) 648 649#define glamor_set_normalize_vcoords(priv, xscale, yscale, \ 650 x1, y1, x2, y2, \ 651 vertices) \ 652 do { \ 653 glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \ 654 x1, y1, x2, y2, \ 655 vertices, 2); \ 656 } while(0) 657 658#define glamor_set_const_ext(params, nparam, vertices, nverts, stride) \ 659 do { \ 660 int _i_ = 0, _j_ = 0; \ 661 for(; _i_ < nverts; _i_++) { \ 662 for(_j_ = 0; _j_ < nparam; _j_++) { \ 663 vertices[stride*_i_ + _j_] = params[_j_]; \ 664 } \ 665 } \ 666 } while(0) 667 668#define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \ 669 x1, y1, x2, y2, \ 670 vertices) \ 671 do { \ 672 (vertices)[0] = v_from_x_coord_x(xscale, x1); \ 673 (vertices)[2] = v_from_x_coord_x(xscale, x2); \ 674 (vertices)[6] = (vertices)[2]; \ 675 (vertices)[4] = (vertices)[0]; \ 676 (vertices)[1] = v_from_x_coord_y(yscale, y1); \ 677 (vertices)[7] = v_from_x_coord_y(yscale, y2); \ 678 (vertices)[3] = (vertices)[1]; \ 679 (vertices)[5] = (vertices)[7]; \ 680 } while(0) 681 682#define glamor_set_normalize_pt(xscale, yscale, x, y, \ 683 pt) \ 684 do { \ 685 (pt)[0] = t_from_x_coord_x(xscale, x); \ 686 (pt)[1] = t_from_x_coord_y(yscale, y); \ 687 } while(0) 688 689#define glamor_set_circle_centre(width, height, x, y, \ 690 c) \ 691 do { \ 692 (c)[0] = (float)x; \ 693 (c)[1] = (float)y; \ 694 } while(0) 695 696#ifndef ARRAY_SIZE 697#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 698#endif 699 700#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) 701#define MIN(a,b) ((a) < (b) ? (a) : (b)) 702#define MAX(a,b) ((a) > (b) ? (a) : (b)) 703 704#define glamor_check_fbo_size(_glamor_,_w_, _h_) ((_w_) > 0 && (_h_) > 0 \ 705 && (_w_) <= _glamor_->max_fbo_size \ 706 && (_h_) <= _glamor_->max_fbo_size) 707 708/* For 1bpp pixmap, we don't store it as texture. */ 709#define glamor_check_pixmap_fbo_depth(_depth_) ( \ 710 _depth_ == 8 \ 711 || _depth_ == 15 \ 712 || _depth_ == 16 \ 713 || _depth_ == 24 \ 714 || _depth_ == 30 \ 715 || _depth_ == 32) 716 717#define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL) 718 719/** 720 * Borrow from uxa. 721 */ 722static inline CARD32 723format_for_depth(int depth) 724{ 725 switch (depth) { 726 case 1: 727 return PICT_a1; 728 case 4: 729 return PICT_a4; 730 case 8: 731 return PICT_a8; 732 case 15: 733 return PICT_x1r5g5b5; 734 case 16: 735 return PICT_r5g6b5; 736 default: 737 case 24: 738 return PICT_x8r8g8b8; 739#if XORG_VERSION_CURRENT >= 10699900 740 case 30: 741 return PICT_x2r10g10b10; 742#endif 743 case 32: 744 return PICT_a8r8g8b8; 745 } 746} 747 748static inline GLenum 749gl_iformat_for_pixmap(PixmapPtr pixmap) 750{ 751 glamor_screen_private *glamor_priv = 752 glamor_get_screen_private((pixmap)->drawable.pScreen); 753 754 if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && 755 ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) { 756 return glamor_priv->one_channel_format; 757 } else { 758 return GL_RGBA; 759 } 760} 761 762static inline CARD32 763format_for_pixmap(PixmapPtr pixmap) 764{ 765 return format_for_depth((pixmap)->drawable.depth); 766} 767 768#define REVERT_NONE 0 769#define REVERT_NORMAL 1 770#define REVERT_DOWNLOADING_A1 2 771#define REVERT_UPLOADING_A1 3 772#define REVERT_DOWNLOADING_2_10_10_10 4 773#define REVERT_UPLOADING_2_10_10_10 5 774#define REVERT_DOWNLOADING_1_5_5_5 7 775#define REVERT_UPLOADING_1_5_5_5 8 776#define REVERT_DOWNLOADING_10_10_10_2 9 777#define REVERT_UPLOADING_10_10_10_2 10 778 779#define SWAP_NONE_DOWNLOADING 0 780#define SWAP_DOWNLOADING 1 781#define SWAP_UPLOADING 2 782#define SWAP_NONE_UPLOADING 3 783 784/* borrowed from uxa */ 785static inline Bool 786glamor_get_rgba_from_pixel(CARD32 pixel, 787 float *red, 788 float *green, 789 float *blue, float *alpha, CARD32 format) 790{ 791 int rbits, bbits, gbits, abits; 792 int rshift, bshift, gshift, ashift; 793 794 rbits = PICT_FORMAT_R(format); 795 gbits = PICT_FORMAT_G(format); 796 bbits = PICT_FORMAT_B(format); 797 abits = PICT_FORMAT_A(format); 798 799 if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) { 800 rshift = gshift = bshift = ashift = 0; 801 } 802 else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) { 803 bshift = 0; 804 gshift = bbits; 805 rshift = gshift + gbits; 806 ashift = rshift + rbits; 807 } 808 else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) { 809 rshift = 0; 810 gshift = rbits; 811 bshift = gshift + gbits; 812 ashift = bshift + bbits; 813#if XORG_VERSION_CURRENT >= 10699900 814 } 815 else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) { 816 ashift = 0; 817 rshift = abits; 818 if (abits == 0) 819 rshift = PICT_FORMAT_BPP(format) - (rbits + gbits + bbits); 820 gshift = rshift + rbits; 821 bshift = gshift + gbits; 822#endif 823 } 824 else { 825 return FALSE; 826 } 827#define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_) \ 828 *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1)) \ 829 / (float)((1<<(_bits_)) - 1) 830 831 if (rbits) 832 COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits); 833 else 834 *red = 0; 835 836 if (gbits) 837 COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits); 838 else 839 *green = 0; 840 841 if (bbits) 842 COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits); 843 else 844 *blue = 0; 845 846 if (abits) 847 COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits); 848 else 849 *alpha = 1; 850 851 return TRUE; 852} 853 854inline static Bool 855glamor_is_large_pixmap(PixmapPtr pixmap) 856{ 857 glamor_pixmap_private *priv; 858 859 priv = glamor_get_pixmap_private(pixmap); 860 return (glamor_pixmap_priv_is_large(priv)); 861} 862 863static inline void 864_glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h) 865{ 866 int i, j; 867 unsigned char *p = (pixmap)->devPrivate.ptr; 868 int stride = (pixmap)->devKind; 869 870 p = p + y * stride + x; 871 872 for (i = 0; i < h; i++) { 873 ErrorF("line %3d: ", i); 874 for (j = 0; j < w; j++) 875 ErrorF("%2d ", (p[j / 8] & (1 << (j % 8))) >> (j % 8)); 876 p += stride; 877 ErrorF("\n"); 878 } 879} 880 881static inline void 882_glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h) 883{ 884 int i, j; 885 unsigned char *p = (pixmap)->devPrivate.ptr; 886 int stride = (pixmap)->devKind; 887 888 p = p + y * stride + x; 889 890 for (i = 0; i < h; i++) { 891 ErrorF("line %3d: ", i); 892 for (j = 0; j < w; j++) 893 ErrorF("%2x ", p[j]); 894 p += stride; 895 ErrorF("\n"); 896 } 897} 898 899static inline void 900_glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h) 901{ 902 int i, j; 903 unsigned short *p = (pixmap)->devPrivate.ptr; 904 int stride = (pixmap)->devKind / 2; 905 906 p = p + y * stride + x; 907 908 for (i = 0; i < h; i++) { 909 ErrorF("line %3d: ", i); 910 for (j = 0; j < w; j++) 911 ErrorF("%2x ", p[j]); 912 p += stride; 913 ErrorF("\n"); 914 } 915} 916 917static inline void 918_glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h) 919{ 920 int i, j; 921 unsigned int *p = (pixmap)->devPrivate.ptr; 922 int stride = (pixmap)->devKind / 4; 923 924 p = p + y * stride + x; 925 926 for (i = 0; i < h; i++) { 927 ErrorF("line %3d: ", i); 928 for (j = 0; j < w; j++) 929 ErrorF("%2x ", p[j]); 930 p += stride; 931 ErrorF("\n"); 932 } 933} 934 935static inline void 936glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h) 937{ 938 w = ((x + w) > (pixmap)->drawable.width) ? ((pixmap)->drawable.width - x) : w; 939 h = ((y + h) > (pixmap)->drawable.height) ? ((pixmap)->drawable.height - y) : h; 940 941 glamor_prepare_access(&(pixmap)->drawable, GLAMOR_ACCESS_RO); 942 switch ((pixmap)->drawable.depth) { 943 case 8: 944 _glamor_dump_pixmap_byte(pixmap, x, y, w, h); 945 break; 946 case 15: 947 case 16: 948 _glamor_dump_pixmap_sword(pixmap, x, y, w, h); 949 break; 950 951 case 24: 952 case 32: 953 _glamor_dump_pixmap_word(pixmap, x, y, w, h); 954 break; 955 case 1: 956 _glamor_dump_pixmap_bits(pixmap, x, y, w, h); 957 break; 958 default: 959 ErrorF("dump depth %d, not implemented.\n", (pixmap)->drawable.depth); 960 } 961 glamor_finish_access(&(pixmap)->drawable); 962} 963 964static inline void 965_glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2, 966 int x, int y, int w, int h, 967 PictFormatShort short_format, int all, int diffs) 968{ 969 int i, j; 970 unsigned char *p1 = pixmap1->devPrivate.ptr; 971 unsigned char *p2 = pixmap2->devPrivate.ptr; 972 int line_need_printed = 0; 973 int test_code = 0xAABBCCDD; 974 int little_endian = 0; 975 unsigned char *p_test; 976 int bpp = pixmap1->drawable.depth == 8 ? 1 : 4; 977 int stride = pixmap1->devKind; 978 979 assert(pixmap1->devKind == pixmap2->devKind); 980 981 ErrorF("stride:%d, width:%d, height:%d\n", stride, w, h); 982 983 p1 = p1 + y * stride + x; 984 p2 = p2 + y * stride + x; 985 986 if (all) { 987 for (i = 0; i < h; i++) { 988 ErrorF("line %3d: ", i); 989 990 for (j = 0; j < stride; j++) { 991 if (j % bpp == 0) 992 ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]); 993 else 994 ErrorF("%2x:%2x ", p1[j], p2[j]); 995 } 996 997 p1 += stride; 998 p2 += stride; 999 ErrorF("\n"); 1000 } 1001 } 1002 else { 1003 if (short_format == PICT_a8r8g8b8) { 1004 p_test = (unsigned char *) &test_code; 1005 little_endian = (*p_test == 0xDD); 1006 bpp = 4; 1007 1008 for (i = 0; i < h; i++) { 1009 line_need_printed = 0; 1010 1011 for (j = 0; j < stride; j++) { 1012 if (p1[j] != p2[j] && 1013 (p1[j] - p2[j] > diffs || p2[j] - p1[j] > diffs)) { 1014 if (line_need_printed) { 1015 if (little_endian) { 1016 switch (j % 4) { 1017 case 2: 1018 ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], 1019 p2[j]); 1020 break; 1021 case 1: 1022 ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], 1023 p2[j]); 1024 break; 1025 case 0: 1026 ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], 1027 p2[j]); 1028 break; 1029 case 3: 1030 ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], 1031 p2[j]); 1032 break; 1033 } 1034 } 1035 else { 1036 switch (j % 4) { 1037 case 1: 1038 ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j], 1039 p2[j]); 1040 break; 1041 case 2: 1042 ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j], 1043 p2[j]); 1044 break; 1045 case 3: 1046 ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j], 1047 p2[j]); 1048 break; 1049 case 0: 1050 ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j], 1051 p2[j]); 1052 break; 1053 } 1054 } 1055 } 1056 else { 1057 line_need_printed = 1; 1058 j = -1; 1059 ErrorF("line %3d: ", i); 1060 continue; 1061 } 1062 } 1063 } 1064 1065 p1 += stride; 1066 p2 += stride; 1067 ErrorF("\n"); 1068 } 1069 } //more format can be added here. 1070 else { // the default format, just print. 1071 for (i = 0; i < h; i++) { 1072 line_need_printed = 0; 1073 1074 for (j = 0; j < stride; j++) { 1075 if (p1[j] != p2[j]) { 1076 if (line_need_printed) { 1077 ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]); 1078 } 1079 else { 1080 line_need_printed = 1; 1081 j = -1; 1082 ErrorF("line %3d: ", i); 1083 continue; 1084 } 1085 } 1086 } 1087 1088 p1 += stride; 1089 p2 += stride; 1090 ErrorF("\n"); 1091 } 1092 } 1093 } 1094} 1095 1096static inline void 1097glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2, 1098 int x, int y, int w, int h, int all, int diffs) 1099{ 1100 assert(pixmap1->drawable.depth == pixmap2->drawable.depth); 1101 1102 if (glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO) && 1103 glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO)) { 1104 _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs); 1105 } 1106 glamor_finish_access(&pixmap1->drawable); 1107 glamor_finish_access(&pixmap2->drawable); 1108} 1109 1110/* This function is used to compare two pictures. 1111 If the picture has no drawable, we use fb functions to generate it. */ 1112static inline void 1113glamor_compare_pictures(ScreenPtr screen, 1114 PicturePtr fst_picture, 1115 PicturePtr snd_picture, 1116 int x_source, int y_source, 1117 int width, int height, int all, int diffs) 1118{ 1119 PixmapPtr fst_pixmap; 1120 PixmapPtr snd_pixmap; 1121 int fst_generated, snd_generated; 1122 int error; 1123 int fst_type = -1; 1124 int snd_type = -1; // -1 represent has drawable. 1125 1126 if (fst_picture->format != snd_picture->format) { 1127 ErrorF("Different picture format can not compare!\n"); 1128 return; 1129 } 1130 1131 if (!fst_picture->pDrawable) { 1132 fst_type = fst_picture->pSourcePict->type; 1133 } 1134 1135 if (!snd_picture->pDrawable) { 1136 snd_type = snd_picture->pSourcePict->type; 1137 } 1138 1139 if ((fst_type != -1) && (snd_type != -1) && (fst_type != snd_type)) { 1140 ErrorF("Different picture type will never be same!\n"); 1141 return; 1142 } 1143 1144 fst_generated = snd_generated = 0; 1145 1146 if (!fst_picture->pDrawable) { 1147 PicturePtr pixman_pic; 1148 PixmapPtr pixmap = NULL; 1149 PictFormatShort format; 1150 1151 format = fst_picture->format; 1152 1153 pixmap = glamor_create_pixmap(screen, 1154 width, height, 1155 PIXMAN_FORMAT_DEPTH(format), 1156 GLAMOR_CREATE_PIXMAP_CPU); 1157 1158 pixman_pic = CreatePicture(0, 1159 &(pixmap)->drawable, 1160 PictureMatchFormat(screen, 1161 PIXMAN_FORMAT_DEPTH 1162 (format), format), 0, 0, 1163 serverClient, &error); 1164 1165 fbComposite(PictOpSrc, fst_picture, NULL, pixman_pic, 1166 x_source, y_source, 0, 0, 0, 0, width, height); 1167 1168 glamor_destroy_pixmap(pixmap); 1169 1170 fst_picture = pixman_pic; 1171 fst_generated = 1; 1172 } 1173 1174 if (!snd_picture->pDrawable) { 1175 PicturePtr pixman_pic; 1176 PixmapPtr pixmap = NULL; 1177 PictFormatShort format; 1178 1179 format = snd_picture->format; 1180 1181 pixmap = glamor_create_pixmap(screen, 1182 width, height, 1183 PIXMAN_FORMAT_DEPTH(format), 1184 GLAMOR_CREATE_PIXMAP_CPU); 1185 1186 pixman_pic = CreatePicture(0, 1187 &(pixmap)->drawable, 1188 PictureMatchFormat(screen, 1189 PIXMAN_FORMAT_DEPTH 1190 (format), format), 0, 0, 1191 serverClient, &error); 1192 1193 fbComposite(PictOpSrc, snd_picture, NULL, pixman_pic, 1194 x_source, y_source, 0, 0, 0, 0, width, height); 1195 1196 glamor_destroy_pixmap(pixmap); 1197 1198 snd_picture = pixman_pic; 1199 snd_generated = 1; 1200 } 1201 1202 fst_pixmap = glamor_get_drawable_pixmap(fst_picture->pDrawable); 1203 snd_pixmap = glamor_get_drawable_pixmap(snd_picture->pDrawable); 1204 1205 if (fst_pixmap->drawable.depth != snd_pixmap->drawable.depth) { 1206 if (fst_generated) 1207 miDestroyPicture(fst_picture); 1208 if (snd_generated) 1209 miDestroyPicture(snd_picture); 1210 1211 ErrorF("Different pixmap depth can not compare!\n"); 1212 return; 1213 } 1214 1215 if ((fst_type == SourcePictTypeLinear) || 1216 (fst_type == SourcePictTypeRadial) || 1217 (fst_type == SourcePictTypeConical) || 1218 (snd_type == SourcePictTypeLinear) || 1219 (snd_type == SourcePictTypeRadial) || 1220 (snd_type == SourcePictTypeConical)) { 1221 x_source = y_source = 0; 1222 } 1223 1224 if (glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO) && 1225 glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO)) { 1226 _glamor_compare_pixmaps(fst_pixmap, snd_pixmap, 1227 x_source, y_source, 1228 width, height, fst_picture->format, 1229 all, diffs); 1230 } 1231 glamor_finish_access(&fst_pixmap->drawable); 1232 glamor_finish_access(&snd_pixmap->drawable); 1233 1234 if (fst_generated) 1235 miDestroyPicture(fst_picture); 1236 if (snd_generated) 1237 miDestroyPicture(snd_picture); 1238 1239 return; 1240} 1241 1242#ifdef __i386__ 1243static inline unsigned long 1244__fls(unsigned long x) 1245{ 1246 asm("bsr %1,%0":"=r"(x) 1247 : "rm"(x)); 1248 return x; 1249} 1250#else 1251static inline unsigned long 1252__fls(unsigned long x) 1253{ 1254 int n; 1255 1256 if (x == 0) 1257 return (0); 1258 n = 0; 1259 if (x <= 0x0000FFFF) { 1260 n = n + 16; 1261 x = x << 16; 1262 } 1263 if (x <= 0x00FFFFFF) { 1264 n = n + 8; 1265 x = x << 8; 1266 } 1267 if (x <= 0x0FFFFFFF) { 1268 n = n + 4; 1269 x = x << 4; 1270 } 1271 if (x <= 0x3FFFFFFF) { 1272 n = n + 2; 1273 x = x << 2; 1274 } 1275 if (x <= 0x7FFFFFFF) { 1276 n = n + 1; 1277 } 1278 return 31 - n; 1279} 1280#endif 1281 1282static inline void 1283glamor_make_current(glamor_screen_private *glamor_priv) 1284{ 1285 if (lastGLContext != &glamor_priv->ctx) { 1286 lastGLContext = &glamor_priv->ctx; 1287 glamor_priv->ctx.make_current(&glamor_priv->ctx); 1288 } 1289} 1290 1291/** 1292 * Helper function for implementing draws with GL_QUADS on GLES2, 1293 * where we don't have them. 1294 */ 1295static inline void 1296glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count) 1297{ 1298 if (glamor_priv->use_quads) { 1299 glDrawArrays(GL_QUADS, 0, count * 4); 1300 } else { 1301 glamor_gldrawarrays_quads_using_indices(glamor_priv, count); 1302 } 1303} 1304 1305 1306#endif 1307