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 v_from_x_coord_y_inverted(_yscale_, _y_) (2 * (_y_) * (_yscale_) - 1.0)
|
---|
41 | #define t_from_x_coord_x(_xscale_, _x_) ((_x_) * (_xscale_))
|
---|
42 | #define t_from_x_coord_y(_yscale_, _y_) (1.0 - (_y_) * (_yscale_))
|
---|
43 | #define t_from_x_coord_y_inverted(_yscale_, _y_) ((_y_) * (_yscale_))
|
---|
44 |
|
---|
45 | #define pixmap_priv_get_dest_scale(pixmap, _pixmap_priv_, _pxscale_, _pyscale_) \
|
---|
46 | do { \
|
---|
47 | int _w_,_h_; \
|
---|
48 | PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, _pixmap_priv_, _w_, _h_); \
|
---|
49 | *(_pxscale_) = 1.0 / _w_; \
|
---|
50 | *(_pyscale_) = 1.0 / _h_; \
|
---|
51 | } while(0)
|
---|
52 |
|
---|
53 | #define pixmap_priv_get_scale(_pixmap_priv_, _pxscale_, _pyscale_) \
|
---|
54 | do { \
|
---|
55 | *(_pxscale_) = 1.0 / (_pixmap_priv_)->fbo->width; \
|
---|
56 | *(_pyscale_) = 1.0 / (_pixmap_priv_)->fbo->height; \
|
---|
57 | } while(0)
|
---|
58 |
|
---|
59 | #define PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, w, h) \
|
---|
60 | do { \
|
---|
61 | if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \
|
---|
62 | w = priv->box.x2 - priv->box.x1; \
|
---|
63 | h = priv->box.y2 - priv->box.y1; \
|
---|
64 | } else { \
|
---|
65 | w = (pixmap)->drawable.width; \
|
---|
66 | h = (pixmap)->drawable.height; \
|
---|
67 | } \
|
---|
68 | } while(0)
|
---|
69 |
|
---|
70 | #define glamor_pixmap_fbo_fix_wh_ratio(wh, pixmap, priv) \
|
---|
71 | do { \
|
---|
72 | int actual_w, actual_h; \
|
---|
73 | PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap, priv, actual_w, actual_h); \
|
---|
74 | wh[0] = (float)priv->fbo->width / actual_w; \
|
---|
75 | wh[1] = (float)priv->fbo->height / actual_h; \
|
---|
76 | wh[2] = 1.0 / priv->fbo->width; \
|
---|
77 | wh[3] = 1.0 / priv->fbo->height; \
|
---|
78 | } while(0)
|
---|
79 |
|
---|
80 | #define pixmap_priv_get_fbo_off(_priv_, _xoff_, _yoff_) \
|
---|
81 | do { \
|
---|
82 | if (_X_UNLIKELY(_priv_ && glamor_pixmap_priv_is_large(_priv_))) { \
|
---|
83 | *(_xoff_) = - (_priv_)->box.x1; \
|
---|
84 | *(_yoff_) = - (_priv_)->box.y1; \
|
---|
85 | } else { \
|
---|
86 | *(_xoff_) = 0; \
|
---|
87 | *(_yoff_) = 0; \
|
---|
88 | } \
|
---|
89 | } while(0)
|
---|
90 |
|
---|
91 | #define xFixedToFloat(_val_) ((float)xFixedToInt(_val_) \
|
---|
92 | + ((float)xFixedFrac(_val_) / 65536.0))
|
---|
93 |
|
---|
94 | #define glamor_picture_get_matrixf(_picture_, _matrix_) \
|
---|
95 | do { \
|
---|
96 | int _i_; \
|
---|
97 | if ((_picture_)->transform) \
|
---|
98 | { \
|
---|
99 | for(_i_ = 0; _i_ < 3; _i_++) \
|
---|
100 | { \
|
---|
101 | (_matrix_)[_i_ * 3 + 0] = \
|
---|
102 | xFixedToFloat((_picture_)->transform->matrix[_i_][0]); \
|
---|
103 | (_matrix_)[_i_ * 3 + 1] = \
|
---|
104 | xFixedToFloat((_picture_)->transform->matrix[_i_][1]); \
|
---|
105 | (_matrix_)[_i_ * 3 + 2] = \
|
---|
106 | xFixedToFloat((_picture_)->transform->matrix[_i_][2]); \
|
---|
107 | } \
|
---|
108 | } \
|
---|
109 | } while(0)
|
---|
110 |
|
---|
111 | #define fmod(x, w) (x - w * floor((float)x/w))
|
---|
112 |
|
---|
113 | #define fmodulus(x, w, c) do {c = fmod(x, w); \
|
---|
114 | c = c >= 0 ? c : c + w;} \
|
---|
115 | while(0)
|
---|
116 | /* @x: is current coord
|
---|
117 | * @x2: is the right/bottom edge
|
---|
118 | * @w: is current width or height
|
---|
119 | * @odd: is output value, 0 means we are in an even region, 1 means we are in a
|
---|
120 | * odd region.
|
---|
121 | * @c: is output value, equal to x mod w. */
|
---|
122 | #define fodd_repeat_mod(x, x2, w, odd, c) \
|
---|
123 | do { \
|
---|
124 | float shift; \
|
---|
125 | fmodulus((x), w, c); \
|
---|
126 | shift = fabs((x) - (c)); \
|
---|
127 | shift = floor(fabs(round(shift)) / w); \
|
---|
128 | odd = (int)shift & 1; \
|
---|
129 | if (odd && (((x2 % w) == 0) && \
|
---|
130 | round(fabs(x)) == x2)) \
|
---|
131 | odd = 0; \
|
---|
132 | } while(0)
|
---|
133 |
|
---|
134 | /* @txy: output value, is the corrected coords.
|
---|
135 | * @xy: input coords to be fixed up.
|
---|
136 | * @cd: xy mod wh, is a input value.
|
---|
137 | * @wh: current width or height.
|
---|
138 | * @bxy1,bxy2: current box edge's x1/x2 or y1/y2
|
---|
139 | *
|
---|
140 | * case 1:
|
---|
141 | * ----------
|
---|
142 | * | * |
|
---|
143 | * | |
|
---|
144 | * ----------
|
---|
145 | * tx = (c - x1) mod w
|
---|
146 | *
|
---|
147 | * case 2:
|
---|
148 | * ---------
|
---|
149 | * * | |
|
---|
150 | * | |
|
---|
151 | * ---------
|
---|
152 | * tx = - (c - (x1 mod w))
|
---|
153 | *
|
---|
154 | * case 3:
|
---|
155 | *
|
---|
156 | * ----------
|
---|
157 | * | | *
|
---|
158 | * | |
|
---|
159 | * ----------
|
---|
160 | * tx = ((x2 mod x) - c) + (x2 - x1)
|
---|
161 | **/
|
---|
162 | #define __glamor_repeat_reflect_fixup(txy, xy, \
|
---|
163 | cd, wh, bxy1, bxy2) \
|
---|
164 | do { \
|
---|
165 | cd = wh - cd; \
|
---|
166 | if ( xy >= bxy1 && xy < bxy2) { \
|
---|
167 | cd = cd - bxy1; \
|
---|
168 | fmodulus(cd, wh, txy); \
|
---|
169 | } else if (xy < bxy1) { \
|
---|
170 | float bxy1_mod; \
|
---|
171 | fmodulus(bxy1, wh, bxy1_mod); \
|
---|
172 | txy = -(cd - bxy1_mod); \
|
---|
173 | } \
|
---|
174 | else if (xy >= bxy2) { \
|
---|
175 | float bxy2_mod; \
|
---|
176 | fmodulus(bxy2, wh, bxy2_mod); \
|
---|
177 | if (bxy2_mod == 0) \
|
---|
178 | bxy2_mod = wh; \
|
---|
179 | txy = (bxy2_mod - cd) + bxy2 - bxy1; \
|
---|
180 | } else {assert(0); txy = 0;} \
|
---|
181 | } while(0)
|
---|
182 |
|
---|
183 | #define _glamor_repeat_reflect_fixup(txy, xy, cd, odd, \
|
---|
184 | wh, bxy1, bxy2) \
|
---|
185 | do { \
|
---|
186 | if (odd) { \
|
---|
187 | __glamor_repeat_reflect_fixup(txy, xy, \
|
---|
188 | cd, wh, bxy1, bxy2); \
|
---|
189 | } else \
|
---|
190 | txy = xy - bxy1; \
|
---|
191 | } while(0)
|
---|
192 |
|
---|
193 | #define _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \
|
---|
194 | tx1, ty1, \
|
---|
195 | _x1_, _y1_) \
|
---|
196 | do { \
|
---|
197 | int odd_x, odd_y; \
|
---|
198 | float c, d; \
|
---|
199 | fodd_repeat_mod(_x1_,priv->box.x2, \
|
---|
200 | (pixmap)->drawable.width, \
|
---|
201 | odd_x, c); \
|
---|
202 | fodd_repeat_mod(_y1_, priv->box.y2, \
|
---|
203 | (pixmap)->drawable.height, \
|
---|
204 | odd_y, d); \
|
---|
205 | DEBUGF("c %f d %f oddx %d oddy %d \n", \
|
---|
206 | c, d, odd_x, odd_y); \
|
---|
207 | DEBUGF("x2 %d x1 %d fbo->width %d \n", priv->box.x2, \
|
---|
208 | priv->box.x1, priv->fbo->width); \
|
---|
209 | DEBUGF("y2 %d y1 %d fbo->height %d \n", priv->box.y2, \
|
---|
210 | priv->box.y1, priv->fbo->height); \
|
---|
211 | _glamor_repeat_reflect_fixup(tx1, _x1_, c, odd_x, \
|
---|
212 | (pixmap)->drawable.width, \
|
---|
213 | priv->box.x1, priv->box.x2); \
|
---|
214 | _glamor_repeat_reflect_fixup(ty1, _y1_, d, odd_y, \
|
---|
215 | (pixmap)->drawable.height, \
|
---|
216 | priv->box.y1, priv->box.y2); \
|
---|
217 | } while(0)
|
---|
218 |
|
---|
219 | #define _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, \
|
---|
220 | ty1, tx2, ty2, \
|
---|
221 | _x1_, _y1_, _x2_, \
|
---|
222 | _y2_, c, d, odd_x, odd_y) \
|
---|
223 | do { \
|
---|
224 | if (repeat_type == RepeatReflect) { \
|
---|
225 | DEBUGF("x1 y1 %d %d\n", \
|
---|
226 | _x1_, _y1_ ); \
|
---|
227 | DEBUGF("width %d box.x1 %d \n", \
|
---|
228 | (pixmap)->drawable.width, \
|
---|
229 | priv->box.x1); \
|
---|
230 | if (odd_x) { \
|
---|
231 | c = (pixmap)->drawable.width \
|
---|
232 | - c; \
|
---|
233 | tx1 = c - priv->box.x1; \
|
---|
234 | tx2 = tx1 - ((_x2_) - (_x1_)); \
|
---|
235 | } else { \
|
---|
236 | tx1 = c - priv->box.x1; \
|
---|
237 | tx2 = tx1 + ((_x2_) - (_x1_)); \
|
---|
238 | } \
|
---|
239 | if (odd_y){ \
|
---|
240 | d = (pixmap)->drawable.height\
|
---|
241 | - d; \
|
---|
242 | ty1 = d - priv->box.y1; \
|
---|
243 | ty2 = ty1 - ((_y2_) - (_y1_)); \
|
---|
244 | } else { \
|
---|
245 | ty1 = d - priv->box.y1; \
|
---|
246 | ty2 = ty1 + ((_y2_) - (_y1_)); \
|
---|
247 | } \
|
---|
248 | } else { /* RepeatNormal*/ \
|
---|
249 | tx1 = (c - priv->box.x1); \
|
---|
250 | ty1 = (d - priv->box.y1); \
|
---|
251 | tx2 = tx1 + ((_x2_) - (_x1_)); \
|
---|
252 | ty2 = ty1 + ((_y2_) - (_y1_)); \
|
---|
253 | } \
|
---|
254 | } while(0)
|
---|
255 |
|
---|
256 | /* _x1_ ... _y2_ may has fractional. */
|
---|
257 | #define glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, tx1, \
|
---|
258 | ty1, _x1_, _y1_) \
|
---|
259 | do { \
|
---|
260 | DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \
|
---|
261 | (pixmap)->drawable.width, \
|
---|
262 | priv->box.x1, priv->box.x2, priv->box.y1, \
|
---|
263 | priv->box.y2); \
|
---|
264 | DEBUGF("x1 %f y1 %f \n", _x1_, _y1_); \
|
---|
265 | if (repeat_type != RepeatReflect) { \
|
---|
266 | tx1 = _x1_ - priv->box.x1; \
|
---|
267 | ty1 = _y1_ - priv->box.y1; \
|
---|
268 | } else \
|
---|
269 | _glamor_get_reflect_transform_coords(pixmap, priv, repeat_type, \
|
---|
270 | tx1, ty1, \
|
---|
271 | _x1_, _y1_); \
|
---|
272 | DEBUGF("tx1 %f ty1 %f \n", tx1, ty1); \
|
---|
273 | } while(0)
|
---|
274 |
|
---|
275 | /* _x1_ ... _y2_ must be integer. */
|
---|
276 | #define glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, \
|
---|
277 | ty1, tx2, ty2, _x1_, _y1_, _x2_, \
|
---|
278 | _y2_) \
|
---|
279 | do { \
|
---|
280 | int c, d; \
|
---|
281 | int odd_x = 0, odd_y = 0; \
|
---|
282 | DEBUGF("width %d box.x1 %d x2 %d y1 %d y2 %d\n", \
|
---|
283 | (pixmap)->drawable.width, \
|
---|
284 | priv->box.x1, priv->box.x2, \
|
---|
285 | priv->box.y1, priv->box.y2); \
|
---|
286 | modulus((_x1_), (pixmap)->drawable.width, c); \
|
---|
287 | modulus((_y1_), (pixmap)->drawable.height, d); \
|
---|
288 | DEBUGF("c %d d %d \n", c, d); \
|
---|
289 | if (repeat_type == RepeatReflect) { \
|
---|
290 | odd_x = abs((_x1_ - c) \
|
---|
291 | / ((pixmap)->drawable.width)) & 1; \
|
---|
292 | odd_y = abs((_y1_ - d) \
|
---|
293 | / ((pixmap)->drawable.height)) & 1; \
|
---|
294 | } \
|
---|
295 | _glamor_get_repeat_coords(pixmap, priv, repeat_type, tx1, ty1, tx2, ty2, \
|
---|
296 | _x1_, _y1_, _x2_, _y2_, c, d, \
|
---|
297 | odd_x, odd_y); \
|
---|
298 | } while(0)
|
---|
299 |
|
---|
300 | #define glamor_transform_point(matrix, tx, ty, x, y) \
|
---|
301 | do { \
|
---|
302 | int _i_; \
|
---|
303 | float _result_[4]; \
|
---|
304 | for (_i_ = 0; _i_ < 3; _i_++) { \
|
---|
305 | _result_[_i_] = (matrix)[_i_ * 3] * (x) + (matrix)[_i_ * 3 + 1] * (y) \
|
---|
306 | + (matrix)[_i_ * 3 + 2]; \
|
---|
307 | } \
|
---|
308 | tx = _result_[0] / _result_[2]; \
|
---|
309 | ty = _result_[1] / _result_[2]; \
|
---|
310 | } while(0)
|
---|
311 |
|
---|
312 | #define _glamor_set_normalize_tpoint(xscale, yscale, _tx_, _ty_, \
|
---|
313 | texcoord) \
|
---|
314 | do { \
|
---|
315 | (texcoord)[0] = t_from_x_coord_x(xscale, _tx_); \
|
---|
316 | (texcoord)[1] = t_from_x_coord_y_inverted(yscale, _ty_); \
|
---|
317 | DEBUGF("normalized point tx %f ty %f \n", (texcoord)[0], \
|
---|
318 | (texcoord)[1]); \
|
---|
319 | } while(0)
|
---|
320 |
|
---|
321 | #define glamor_set_transformed_point(priv, matrix, xscale, \
|
---|
322 | yscale, texcoord, \
|
---|
323 | x, y) \
|
---|
324 | do { \
|
---|
325 | float tx, ty; \
|
---|
326 | int fbo_x_off, fbo_y_off; \
|
---|
327 | pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \
|
---|
328 | glamor_transform_point(matrix, tx, ty, x, y); \
|
---|
329 | DEBUGF("tx %f ty %f fbooff %d %d \n", \
|
---|
330 | tx, ty, fbo_x_off, fbo_y_off); \
|
---|
331 | \
|
---|
332 | tx += fbo_x_off; \
|
---|
333 | ty += fbo_y_off; \
|
---|
334 | (texcoord)[0] = t_from_x_coord_x(xscale, tx); \
|
---|
335 | (texcoord)[1] = t_from_x_coord_y_inverted(yscale, ty); \
|
---|
336 | DEBUGF("normalized tx %f ty %f \n", (texcoord)[0], (texcoord)[1]); \
|
---|
337 | } while(0)
|
---|
338 |
|
---|
339 | #define glamor_set_transformed_normalize_tri_tcoords(priv, \
|
---|
340 | matrix, \
|
---|
341 | xscale, \
|
---|
342 | yscale, \
|
---|
343 | vtx, \
|
---|
344 | texcoords) \
|
---|
345 | do { \
|
---|
346 | glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
---|
347 | texcoords, (vtx)[0], (vtx)[1]); \
|
---|
348 | glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
---|
349 | texcoords+2, (vtx)[2], (vtx)[3]); \
|
---|
350 | glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
---|
351 | texcoords+4, (vtx)[4], (vtx)[5]); \
|
---|
352 | } while (0)
|
---|
353 |
|
---|
354 | #define glamor_set_transformed_normalize_tcoords_ext( priv, \
|
---|
355 | matrix, \
|
---|
356 | xscale, \
|
---|
357 | yscale, \
|
---|
358 | tx1, ty1, tx2, ty2, \
|
---|
359 | texcoords, \
|
---|
360 | stride) \
|
---|
361 | do { \
|
---|
362 | glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
---|
363 | texcoords, tx1, ty1); \
|
---|
364 | glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
---|
365 | texcoords + 1 * stride, tx2, ty1); \
|
---|
366 | glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
---|
367 | texcoords + 2 * stride, tx2, ty2); \
|
---|
368 | glamor_set_transformed_point(priv, matrix, xscale, yscale, \
|
---|
369 | texcoords + 3 * stride, tx1, ty2); \
|
---|
370 | } while (0)
|
---|
371 |
|
---|
372 | #define glamor_set_transformed_normalize_tcoords( priv, \
|
---|
373 | matrix, \
|
---|
374 | xscale, \
|
---|
375 | yscale, \
|
---|
376 | tx1, ty1, tx2, ty2, \
|
---|
377 | texcoords) \
|
---|
378 | do { \
|
---|
379 | glamor_set_transformed_normalize_tcoords_ext( priv, \
|
---|
380 | matrix, \
|
---|
381 | xscale, \
|
---|
382 | yscale, \
|
---|
383 | tx1, ty1, tx2, ty2, \
|
---|
384 | texcoords, \
|
---|
385 | 2); \
|
---|
386 | } while (0)
|
---|
387 |
|
---|
388 | #define glamor_set_normalize_tri_tcoords(xscale, \
|
---|
389 | yscale, \
|
---|
390 | vtx, \
|
---|
391 | texcoords) \
|
---|
392 | do { \
|
---|
393 | _glamor_set_normalize_tpoint(xscale, yscale, \
|
---|
394 | (vtx)[0], (vtx)[1], \
|
---|
395 | texcoords); \
|
---|
396 | _glamor_set_normalize_tpoint(xscale, yscale, \
|
---|
397 | (vtx)[2], (vtx)[3], \
|
---|
398 | texcoords+2); \
|
---|
399 | _glamor_set_normalize_tpoint(xscale, yscale, \
|
---|
400 | (vtx)[4], (vtx)[5], \
|
---|
401 | texcoords+4); \
|
---|
402 | } while (0)
|
---|
403 |
|
---|
404 | #define glamor_set_repeat_transformed_normalize_tcoords_ext(pixmap, priv, \
|
---|
405 | repeat_type, \
|
---|
406 | matrix, \
|
---|
407 | xscale, \
|
---|
408 | yscale, \
|
---|
409 | _x1_, _y1_, \
|
---|
410 | _x2_, _y2_, \
|
---|
411 | texcoords, \
|
---|
412 | stride) \
|
---|
413 | do { \
|
---|
414 | if (_X_LIKELY(glamor_pixmap_priv_is_small(priv))) { \
|
---|
415 | glamor_set_transformed_normalize_tcoords_ext(priv, matrix, xscale, \
|
---|
416 | yscale, _x1_, _y1_, \
|
---|
417 | _x2_, _y2_, \
|
---|
418 | texcoords, stride); \
|
---|
419 | } else { \
|
---|
420 | float tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4; \
|
---|
421 | float ttx1, tty1, ttx2, tty2, ttx3, tty3, ttx4, tty4; \
|
---|
422 | DEBUGF("original coords %d %d %d %d\n", _x1_, _y1_, _x2_, _y2_); \
|
---|
423 | glamor_transform_point(matrix, tx1, ty1, _x1_, _y1_); \
|
---|
424 | glamor_transform_point(matrix, tx2, ty2, _x2_, _y1_); \
|
---|
425 | glamor_transform_point(matrix, tx3, ty3, _x2_, _y2_); \
|
---|
426 | glamor_transform_point(matrix, tx4, ty4, _x1_, _y2_); \
|
---|
427 | DEBUGF("transformed %f %f %f %f %f %f %f %f\n", \
|
---|
428 | tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4); \
|
---|
429 | glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
|
---|
430 | ttx1, tty1, \
|
---|
431 | tx1, ty1); \
|
---|
432 | glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
|
---|
433 | ttx2, tty2, \
|
---|
434 | tx2, ty2); \
|
---|
435 | glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
|
---|
436 | ttx3, tty3, \
|
---|
437 | tx3, ty3); \
|
---|
438 | glamor_get_repeat_transform_coords(pixmap, priv, repeat_type, \
|
---|
439 | ttx4, tty4, \
|
---|
440 | tx4, ty4); \
|
---|
441 | DEBUGF("repeat transformed %f %f %f %f %f %f %f %f\n", ttx1, tty1, \
|
---|
442 | ttx2, tty2, ttx3, tty3, ttx4, tty4); \
|
---|
443 | _glamor_set_normalize_tpoint(xscale, yscale, ttx1, tty1, \
|
---|
444 | texcoords); \
|
---|
445 | _glamor_set_normalize_tpoint(xscale, yscale, ttx2, tty2, \
|
---|
446 | texcoords + 1 * stride); \
|
---|
447 | _glamor_set_normalize_tpoint(xscale, yscale, ttx3, tty3, \
|
---|
448 | texcoords + 2 * stride); \
|
---|
449 | _glamor_set_normalize_tpoint(xscale, yscale, ttx4, tty4, \
|
---|
450 | texcoords + 3 * stride); \
|
---|
451 | } \
|
---|
452 | } while (0)
|
---|
453 |
|
---|
454 | #define glamor_set_repeat_transformed_normalize_tcoords( pixmap, \
|
---|
455 | priv, \
|
---|
456 | repeat_type, \
|
---|
457 | matrix, \
|
---|
458 | xscale, \
|
---|
459 | yscale, \
|
---|
460 | _x1_, _y1_, \
|
---|
461 | _x2_, _y2_, \
|
---|
462 | texcoords) \
|
---|
463 | do { \
|
---|
464 | glamor_set_repeat_transformed_normalize_tcoords_ext( pixmap, \
|
---|
465 | priv, \
|
---|
466 | repeat_type, \
|
---|
467 | matrix, \
|
---|
468 | xscale, \
|
---|
469 | yscale, \
|
---|
470 | _x1_, _y1_, \
|
---|
471 | _x2_, _y2_, \
|
---|
472 | texcoords, \
|
---|
473 | 2); \
|
---|
474 | } while (0)
|
---|
475 |
|
---|
476 | #define _glamor_set_normalize_tcoords(xscale, yscale, tx1, \
|
---|
477 | ty1, tx2, ty2, \
|
---|
478 | vertices, stride) \
|
---|
479 | do { \
|
---|
480 | /* vertices may be write-only, so we use following \
|
---|
481 | * temporary variable. */ \
|
---|
482 | float _t0_, _t1_, _t2_, _t5_; \
|
---|
483 | (vertices)[0] = _t0_ = t_from_x_coord_x(xscale, tx1); \
|
---|
484 | (vertices)[1 * stride] = _t2_ = t_from_x_coord_x(xscale, tx2); \
|
---|
485 | (vertices)[2 * stride] = _t2_; \
|
---|
486 | (vertices)[3 * stride] = _t0_; \
|
---|
487 | (vertices)[1] = _t1_ = t_from_x_coord_y_inverted(yscale, ty1); \
|
---|
488 | (vertices)[2 * stride + 1] = _t5_ = t_from_x_coord_y_inverted(yscale, ty2); \
|
---|
489 | (vertices)[1 * stride + 1] = _t1_; \
|
---|
490 | (vertices)[3 * stride + 1] = _t5_; \
|
---|
491 | } while(0)
|
---|
492 |
|
---|
493 | #define glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
|
---|
494 | x1, y1, x2, y2, \
|
---|
495 | vertices, stride) \
|
---|
496 | do { \
|
---|
497 | if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \
|
---|
498 | float tx1, tx2, ty1, ty2; \
|
---|
499 | int fbo_x_off, fbo_y_off; \
|
---|
500 | pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \
|
---|
501 | tx1 = x1 + fbo_x_off; \
|
---|
502 | tx2 = x2 + fbo_x_off; \
|
---|
503 | ty1 = y1 + fbo_y_off; \
|
---|
504 | ty2 = y2 + fbo_y_off; \
|
---|
505 | _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
|
---|
506 | tx2, ty2, vertices, \
|
---|
507 | stride); \
|
---|
508 | } else \
|
---|
509 | _glamor_set_normalize_tcoords(xscale, yscale, x1, y1, \
|
---|
510 | x2, y2, vertices, stride); \
|
---|
511 | } while(0)
|
---|
512 |
|
---|
513 | #define glamor_set_normalize_tcoords(priv, xscale, yscale, \
|
---|
514 | x1, y1, x2, y2, \
|
---|
515 | vertices) \
|
---|
516 | do { \
|
---|
517 | glamor_set_normalize_tcoords_ext(priv, xscale, yscale, \
|
---|
518 | x1, y1, x2, y2, \
|
---|
519 | vertices, 2); \
|
---|
520 | } while(0)
|
---|
521 |
|
---|
522 | #define glamor_set_repeat_normalize_tcoords_ext(pixmap, priv, repeat_type, \
|
---|
523 | xscale, yscale, \
|
---|
524 | _x1_, _y1_, _x2_, _y2_, \
|
---|
525 | vertices, stride) \
|
---|
526 | do { \
|
---|
527 | if (_X_UNLIKELY(glamor_pixmap_priv_is_large(priv))) { \
|
---|
528 | float tx1, tx2, ty1, ty2; \
|
---|
529 | if (repeat_type == RepeatPad) { \
|
---|
530 | tx1 = _x1_ - priv->box.x1; \
|
---|
531 | ty1 = _y1_ - priv->box.y1; \
|
---|
532 | tx2 = tx1 + ((_x2_) - (_x1_)); \
|
---|
533 | ty2 = ty1 + ((_y2_) - (_y1_)); \
|
---|
534 | } else { \
|
---|
535 | glamor_get_repeat_coords(pixmap, priv, repeat_type, \
|
---|
536 | tx1, ty1, tx2, ty2, \
|
---|
537 | _x1_, _y1_, _x2_, _y2_); \
|
---|
538 | } \
|
---|
539 | _glamor_set_normalize_tcoords(xscale, yscale, tx1, ty1, \
|
---|
540 | tx2, ty2, vertices, \
|
---|
541 | stride); \
|
---|
542 | } else \
|
---|
543 | _glamor_set_normalize_tcoords(xscale, yscale, _x1_, _y1_, \
|
---|
544 | _x2_, _y2_, vertices, \
|
---|
545 | stride); \
|
---|
546 | } while(0)
|
---|
547 |
|
---|
548 | #define glamor_set_repeat_normalize_tcoords(priv, repeat_type, \
|
---|
549 | xscale, yscale, \
|
---|
550 | _x1_, _y1_, _x2_, _y2_, \
|
---|
551 | vertices) \
|
---|
552 | do { \
|
---|
553 | glamor_set_repeat_normalize_tcoords_ext(priv, repeat_type, \
|
---|
554 | xscale, yscale, \
|
---|
555 | _x1_, _y1_, _x2_, _y2_, \
|
---|
556 | vertices, 2); \
|
---|
557 | } while(0)
|
---|
558 |
|
---|
559 | #define glamor_set_normalize_tcoords_tri_stripe(xscale, yscale, \
|
---|
560 | x1, y1, x2, y2, \
|
---|
561 | vertices) \
|
---|
562 | do { \
|
---|
563 | (vertices)[0] = t_from_x_coord_x(xscale, x1); \
|
---|
564 | (vertices)[2] = t_from_x_coord_x(xscale, x2); \
|
---|
565 | (vertices)[6] = (vertices)[2]; \
|
---|
566 | (vertices)[4] = (vertices)[0]; \
|
---|
567 | (vertices)[1] = t_from_x_coord_y_inverted(yscale, y1); \
|
---|
568 | (vertices)[7] = t_from_x_coord_y_inverted(yscale, y2); \
|
---|
569 | (vertices)[3] = (vertices)[1]; \
|
---|
570 | (vertices)[5] = (vertices)[7]; \
|
---|
571 | } while(0)
|
---|
572 |
|
---|
573 | #define glamor_set_tcoords(x1, y1, x2, y2, vertices) \
|
---|
574 | do { \
|
---|
575 | (vertices)[0] = (x1); \
|
---|
576 | (vertices)[2] = (x2); \
|
---|
577 | (vertices)[4] = (vertices)[2]; \
|
---|
578 | (vertices)[6] = (vertices)[0]; \
|
---|
579 | (vertices)[1] = (y1); \
|
---|
580 | (vertices)[5] = (y2); \
|
---|
581 | (vertices)[3] = (vertices)[1]; \
|
---|
582 | (vertices)[7] = (vertices)[5]; \
|
---|
583 | } while(0)
|
---|
584 |
|
---|
585 | #define glamor_set_tcoords_ext(x1, y1, x2, y2, vertices, stride) \
|
---|
586 | do { \
|
---|
587 | (vertices)[0] = (x1); \
|
---|
588 | (vertices)[1*stride] = (x2); \
|
---|
589 | (vertices)[2*stride] = (vertices)[1*stride]; \
|
---|
590 | (vertices)[3*stride] = (vertices)[0]; \
|
---|
591 | (vertices)[1] = (y1); \
|
---|
592 | (vertices)[2*stride + 1] = (y2); \
|
---|
593 | (vertices)[1*stride + 1] = (vertices)[1]; \
|
---|
594 | (vertices)[3*stride + 1] = (vertices)[2*stride + 1]; \
|
---|
595 | } while(0)
|
---|
596 |
|
---|
597 | #define glamor_set_normalize_one_vcoord(xscale, yscale, x, y, \
|
---|
598 | vertices) \
|
---|
599 | do { \
|
---|
600 | (vertices)[0] = v_from_x_coord_x(xscale, x); \
|
---|
601 | (vertices)[1] = v_from_x_coord_y_inverted(yscale, y); \
|
---|
602 | } while(0)
|
---|
603 |
|
---|
604 | #define glamor_set_normalize_tri_vcoords(xscale, yscale, vtx, \
|
---|
605 | vertices) \
|
---|
606 | do { \
|
---|
607 | glamor_set_normalize_one_vcoord(xscale, yscale, \
|
---|
608 | (vtx)[0], (vtx)[1], \
|
---|
609 | vertices); \
|
---|
610 | glamor_set_normalize_one_vcoord(xscale, yscale, \
|
---|
611 | (vtx)[2], (vtx)[3], \
|
---|
612 | vertices+2); \
|
---|
613 | glamor_set_normalize_one_vcoord(xscale, yscale, \
|
---|
614 | (vtx)[4], (vtx)[5], \
|
---|
615 | vertices+4); \
|
---|
616 | } while(0)
|
---|
617 |
|
---|
618 | #define glamor_set_tcoords_tri_strip(x1, y1, x2, y2, vertices) \
|
---|
619 | do { \
|
---|
620 | (vertices)[0] = (x1); \
|
---|
621 | (vertices)[2] = (x2); \
|
---|
622 | (vertices)[6] = (vertices)[2]; \
|
---|
623 | (vertices)[4] = (vertices)[0]; \
|
---|
624 | (vertices)[1] = (y1); \
|
---|
625 | (vertices)[7] = (y2); \
|
---|
626 | (vertices)[3] = (vertices)[1]; \
|
---|
627 | (vertices)[5] = (vertices)[7]; \
|
---|
628 | } while(0)
|
---|
629 |
|
---|
630 | #define glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
|
---|
631 | x1, y1, x2, y2, \
|
---|
632 | vertices, stride) \
|
---|
633 | do { \
|
---|
634 | int fbo_x_off, fbo_y_off; \
|
---|
635 | /* vertices may be write-only, so we use following \
|
---|
636 | * temporary variable. */ \
|
---|
637 | float _t0_, _t1_, _t2_, _t5_; \
|
---|
638 | pixmap_priv_get_fbo_off(priv, &fbo_x_off, &fbo_y_off); \
|
---|
639 | (vertices)[0] = _t0_ = v_from_x_coord_x(xscale, x1 + fbo_x_off); \
|
---|
640 | (vertices)[1 * stride] = _t2_ = v_from_x_coord_x(xscale, \
|
---|
641 | x2 + fbo_x_off); \
|
---|
642 | (vertices)[2 * stride] = _t2_; \
|
---|
643 | (vertices)[3 * stride] = _t0_; \
|
---|
644 | (vertices)[1] = _t1_ = v_from_x_coord_y_inverted(yscale, \
|
---|
645 | y1 + fbo_y_off); \
|
---|
646 | (vertices)[2 * stride + 1] = _t5_ = \
|
---|
647 | v_from_x_coord_y_inverted(yscale, \
|
---|
648 | y2 + fbo_y_off); \
|
---|
649 | (vertices)[1 * stride + 1] = _t1_; \
|
---|
650 | (vertices)[3 * stride + 1] = _t5_; \
|
---|
651 | } while(0)
|
---|
652 |
|
---|
653 | #define glamor_set_normalize_vcoords(priv, xscale, yscale, \
|
---|
654 | x1, y1, x2, y2, \
|
---|
655 | vertices) \
|
---|
656 | do { \
|
---|
657 | glamor_set_normalize_vcoords_ext(priv, xscale, yscale, \
|
---|
658 | x1, y1, x2, y2, \
|
---|
659 | vertices, 2); \
|
---|
660 | } while(0)
|
---|
661 |
|
---|
662 | #define glamor_set_const_ext(params, nparam, vertices, nverts, stride) \
|
---|
663 | do { \
|
---|
664 | int _i_ = 0, _j_ = 0; \
|
---|
665 | for(; _i_ < nverts; _i_++) { \
|
---|
666 | for(_j_ = 0; _j_ < nparam; _j_++) { \
|
---|
667 | vertices[stride*_i_ + _j_] = params[_j_]; \
|
---|
668 | } \
|
---|
669 | } \
|
---|
670 | } while(0)
|
---|
671 |
|
---|
672 | #define glamor_set_normalize_vcoords_tri_strip(xscale, yscale, \
|
---|
673 | x1, y1, x2, y2, \
|
---|
674 | vertices) \
|
---|
675 | do { \
|
---|
676 | (vertices)[0] = v_from_x_coord_x(xscale, x1); \
|
---|
677 | (vertices)[2] = v_from_x_coord_x(xscale, x2); \
|
---|
678 | (vertices)[6] = (vertices)[2]; \
|
---|
679 | (vertices)[4] = (vertices)[0]; \
|
---|
680 | (vertices)[1] = v_from_x_coord_y_inverted(yscale, y1); \
|
---|
681 | (vertices)[7] = v_from_x_coord_y_inverted(yscale, y2); \
|
---|
682 | (vertices)[3] = (vertices)[1]; \
|
---|
683 | (vertices)[5] = (vertices)[7]; \
|
---|
684 | } while(0)
|
---|
685 |
|
---|
686 | #define glamor_set_normalize_pt(xscale, yscale, x, y, \
|
---|
687 | pt) \
|
---|
688 | do { \
|
---|
689 | (pt)[0] = t_from_x_coord_x(xscale, x); \
|
---|
690 | (pt)[1] = t_from_x_coord_y_inverted(yscale, y); \
|
---|
691 | } while(0)
|
---|
692 |
|
---|
693 | #define glamor_set_circle_centre(width, height, x, y, \
|
---|
694 | c) \
|
---|
695 | do { \
|
---|
696 | (c)[0] = (float)x; \
|
---|
697 | (c)[1] = (float)y; \
|
---|
698 | } while(0)
|
---|
699 |
|
---|
700 | #ifndef ARRAY_SIZE
|
---|
701 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
---|
702 | #endif
|
---|
703 |
|
---|
704 | #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
|
---|
705 | #define MIN(a,b) ((a) < (b) ? (a) : (b))
|
---|
706 | #define MAX(a,b) ((a) > (b) ? (a) : (b))
|
---|
707 |
|
---|
708 | #define glamor_check_fbo_size(_glamor_,_w_, _h_) ((_w_) > 0 && (_h_) > 0 \
|
---|
709 | && (_w_) <= _glamor_->max_fbo_size \
|
---|
710 | && (_h_) <= _glamor_->max_fbo_size)
|
---|
711 |
|
---|
712 | /* For 1bpp pixmap, we don't store it as texture. */
|
---|
713 | #define glamor_check_pixmap_fbo_depth(_depth_) ( \
|
---|
714 | _depth_ == 8 \
|
---|
715 | || _depth_ == 15 \
|
---|
716 | || _depth_ == 16 \
|
---|
717 | || _depth_ == 24 \
|
---|
718 | || _depth_ == 30 \
|
---|
719 | || _depth_ == 32)
|
---|
720 |
|
---|
721 | #define GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv) (pixmap_priv->gl_fbo == GLAMOR_FBO_NORMAL)
|
---|
722 |
|
---|
723 | /**
|
---|
724 | * Borrow from uxa.
|
---|
725 | */
|
---|
726 | static inline CARD32
|
---|
727 | format_for_depth(int depth)
|
---|
728 | {
|
---|
729 | switch (depth) {
|
---|
730 | case 1:
|
---|
731 | return PICT_a1;
|
---|
732 | case 4:
|
---|
733 | return PICT_a4;
|
---|
734 | case 8:
|
---|
735 | return PICT_a8;
|
---|
736 | case 15:
|
---|
737 | return PICT_x1r5g5b5;
|
---|
738 | case 16:
|
---|
739 | return PICT_r5g6b5;
|
---|
740 | default:
|
---|
741 | case 24:
|
---|
742 | return PICT_x8r8g8b8;
|
---|
743 | #if XORG_VERSION_CURRENT >= 10699900
|
---|
744 | case 30:
|
---|
745 | return PICT_x2r10g10b10;
|
---|
746 | #endif
|
---|
747 | case 32:
|
---|
748 | return PICT_a8r8g8b8;
|
---|
749 | }
|
---|
750 | }
|
---|
751 |
|
---|
752 | static inline GLenum
|
---|
753 | gl_iformat_for_pixmap(PixmapPtr pixmap)
|
---|
754 | {
|
---|
755 | glamor_screen_private *glamor_priv =
|
---|
756 | glamor_get_screen_private((pixmap)->drawable.pScreen);
|
---|
757 |
|
---|
758 | if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP &&
|
---|
759 | ((pixmap)->drawable.depth == 1 || (pixmap)->drawable.depth == 8)) {
|
---|
760 | return GL_ALPHA;
|
---|
761 | } else {
|
---|
762 | return GL_RGBA;
|
---|
763 | }
|
---|
764 | }
|
---|
765 |
|
---|
766 | static inline CARD32
|
---|
767 | format_for_pixmap(PixmapPtr pixmap)
|
---|
768 | {
|
---|
769 | return format_for_depth((pixmap)->drawable.depth);
|
---|
770 | }
|
---|
771 |
|
---|
772 | #define REVERT_NONE 0
|
---|
773 | #define REVERT_NORMAL 1
|
---|
774 | #define REVERT_DOWNLOADING_A1 2
|
---|
775 | #define REVERT_UPLOADING_A1 3
|
---|
776 | #define REVERT_DOWNLOADING_2_10_10_10 4
|
---|
777 | #define REVERT_UPLOADING_2_10_10_10 5
|
---|
778 | #define REVERT_DOWNLOADING_1_5_5_5 7
|
---|
779 | #define REVERT_UPLOADING_1_5_5_5 8
|
---|
780 | #define REVERT_DOWNLOADING_10_10_10_2 9
|
---|
781 | #define REVERT_UPLOADING_10_10_10_2 10
|
---|
782 |
|
---|
783 | #define SWAP_NONE_DOWNLOADING 0
|
---|
784 | #define SWAP_DOWNLOADING 1
|
---|
785 | #define SWAP_UPLOADING 2
|
---|
786 | #define SWAP_NONE_UPLOADING 3
|
---|
787 |
|
---|
788 | /* borrowed from uxa */
|
---|
789 | static inline Bool
|
---|
790 | glamor_get_rgba_from_pixel(CARD32 pixel,
|
---|
791 | float *red,
|
---|
792 | float *green,
|
---|
793 | float *blue, float *alpha, CARD32 format)
|
---|
794 | {
|
---|
795 | int rbits, bbits, gbits, abits;
|
---|
796 | int rshift, bshift, gshift, ashift;
|
---|
797 |
|
---|
798 | rbits = PICT_FORMAT_R(format);
|
---|
799 | gbits = PICT_FORMAT_G(format);
|
---|
800 | bbits = PICT_FORMAT_B(format);
|
---|
801 | abits = PICT_FORMAT_A(format);
|
---|
802 |
|
---|
803 | if (PICT_FORMAT_TYPE(format) == PICT_TYPE_A) {
|
---|
804 | rshift = gshift = bshift = ashift = 0;
|
---|
805 | }
|
---|
806 | else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
|
---|
807 | bshift = 0;
|
---|
808 | gshift = bbits;
|
---|
809 | rshift = gshift + gbits;
|
---|
810 | ashift = rshift + rbits;
|
---|
811 | }
|
---|
812 | else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
|
---|
813 | rshift = 0;
|
---|
814 | gshift = rbits;
|
---|
815 | bshift = gshift + gbits;
|
---|
816 | ashift = bshift + bbits;
|
---|
817 | #if XORG_VERSION_CURRENT >= 10699900
|
---|
818 | }
|
---|
819 | else if (PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
|
---|
820 | ashift = 0;
|
---|
821 | rshift = abits;
|
---|
822 | if (abits == 0)
|
---|
823 | rshift = PICT_FORMAT_BPP(format) - (rbits + gbits + bbits);
|
---|
824 | gshift = rshift + rbits;
|
---|
825 | bshift = gshift + gbits;
|
---|
826 | #endif
|
---|
827 | }
|
---|
828 | else {
|
---|
829 | return FALSE;
|
---|
830 | }
|
---|
831 | #define COLOR_INT_TO_FLOAT(_fc_, _p_, _s_, _bits_) \
|
---|
832 | *_fc_ = (((_p_) >> (_s_)) & (( 1 << (_bits_)) - 1)) \
|
---|
833 | / (float)((1<<(_bits_)) - 1)
|
---|
834 |
|
---|
835 | if (rbits)
|
---|
836 | COLOR_INT_TO_FLOAT(red, pixel, rshift, rbits);
|
---|
837 | else
|
---|
838 | *red = 0;
|
---|
839 |
|
---|
840 | if (gbits)
|
---|
841 | COLOR_INT_TO_FLOAT(green, pixel, gshift, gbits);
|
---|
842 | else
|
---|
843 | *green = 0;
|
---|
844 |
|
---|
845 | if (bbits)
|
---|
846 | COLOR_INT_TO_FLOAT(blue, pixel, bshift, bbits);
|
---|
847 | else
|
---|
848 | *blue = 0;
|
---|
849 |
|
---|
850 | if (abits)
|
---|
851 | COLOR_INT_TO_FLOAT(alpha, pixel, ashift, abits);
|
---|
852 | else
|
---|
853 | *alpha = 1;
|
---|
854 |
|
---|
855 | return TRUE;
|
---|
856 | }
|
---|
857 |
|
---|
858 | inline static Bool
|
---|
859 | glamor_pict_format_is_compatible(PicturePtr picture)
|
---|
860 | {
|
---|
861 | GLenum iformat;
|
---|
862 | PixmapPtr pixmap = glamor_get_drawable_pixmap(picture->pDrawable);
|
---|
863 |
|
---|
864 | iformat = gl_iformat_for_pixmap(pixmap);
|
---|
865 | switch (iformat) {
|
---|
866 | case GL_RGBA:
|
---|
867 | return (picture->format == PICT_a8r8g8b8 ||
|
---|
868 | picture->format == PICT_x8r8g8b8);
|
---|
869 | case GL_ALPHA:
|
---|
870 | return (picture->format == PICT_a8);
|
---|
871 | default:
|
---|
872 | return FALSE;
|
---|
873 | }
|
---|
874 | }
|
---|
875 |
|
---|
876 | inline static Bool
|
---|
877 | glamor_is_large_pixmap(PixmapPtr pixmap)
|
---|
878 | {
|
---|
879 | glamor_pixmap_private *priv;
|
---|
880 |
|
---|
881 | priv = glamor_get_pixmap_private(pixmap);
|
---|
882 | return (glamor_pixmap_priv_is_large(priv));
|
---|
883 | }
|
---|
884 |
|
---|
885 | static inline void
|
---|
886 | _glamor_dump_pixmap_bits(PixmapPtr pixmap, int x, int y, int w, int h)
|
---|
887 | {
|
---|
888 | int i, j;
|
---|
889 | unsigned char *p = (pixmap)->devPrivate.ptr;
|
---|
890 | int stride = (pixmap)->devKind;
|
---|
891 |
|
---|
892 | p = p + y * stride + x;
|
---|
893 |
|
---|
894 | for (i = 0; i < h; i++) {
|
---|
895 | ErrorF("line %3d: ", i);
|
---|
896 | for (j = 0; j < w; j++)
|
---|
897 | ErrorF("%2d ", (p[j / 8] & (1 << (j % 8))) >> (j % 8));
|
---|
898 | p += stride;
|
---|
899 | ErrorF("\n");
|
---|
900 | }
|
---|
901 | }
|
---|
902 |
|
---|
903 | static inline void
|
---|
904 | _glamor_dump_pixmap_byte(PixmapPtr pixmap, int x, int y, int w, int h)
|
---|
905 | {
|
---|
906 | int i, j;
|
---|
907 | unsigned char *p = (pixmap)->devPrivate.ptr;
|
---|
908 | int stride = (pixmap)->devKind;
|
---|
909 |
|
---|
910 | p = p + y * stride + x;
|
---|
911 |
|
---|
912 | for (i = 0; i < h; i++) {
|
---|
913 | ErrorF("line %3d: ", i);
|
---|
914 | for (j = 0; j < w; j++)
|
---|
915 | ErrorF("%2x ", p[j]);
|
---|
916 | p += stride;
|
---|
917 | ErrorF("\n");
|
---|
918 | }
|
---|
919 | }
|
---|
920 |
|
---|
921 | static inline void
|
---|
922 | _glamor_dump_pixmap_sword(PixmapPtr pixmap, int x, int y, int w, int h)
|
---|
923 | {
|
---|
924 | int i, j;
|
---|
925 | unsigned short *p = (pixmap)->devPrivate.ptr;
|
---|
926 | int stride = (pixmap)->devKind / 2;
|
---|
927 |
|
---|
928 | p = p + y * stride + x;
|
---|
929 |
|
---|
930 | for (i = 0; i < h; i++) {
|
---|
931 | ErrorF("line %3d: ", i);
|
---|
932 | for (j = 0; j < w; j++)
|
---|
933 | ErrorF("%2x ", p[j]);
|
---|
934 | p += stride;
|
---|
935 | ErrorF("\n");
|
---|
936 | }
|
---|
937 | }
|
---|
938 |
|
---|
939 | static inline void
|
---|
940 | _glamor_dump_pixmap_word(PixmapPtr pixmap, int x, int y, int w, int h)
|
---|
941 | {
|
---|
942 | int i, j;
|
---|
943 | unsigned int *p = (pixmap)->devPrivate.ptr;
|
---|
944 | int stride = (pixmap)->devKind / 4;
|
---|
945 |
|
---|
946 | p = p + y * stride + x;
|
---|
947 |
|
---|
948 | for (i = 0; i < h; i++) {
|
---|
949 | ErrorF("line %3d: ", i);
|
---|
950 | for (j = 0; j < w; j++)
|
---|
951 | ErrorF("%2x ", p[j]);
|
---|
952 | p += stride;
|
---|
953 | ErrorF("\n");
|
---|
954 | }
|
---|
955 | }
|
---|
956 |
|
---|
957 | static inline void
|
---|
958 | glamor_dump_pixmap(PixmapPtr pixmap, int x, int y, int w, int h)
|
---|
959 | {
|
---|
960 | w = ((x + w) > (pixmap)->drawable.width) ? ((pixmap)->drawable.width - x) : w;
|
---|
961 | h = ((y + h) > (pixmap)->drawable.height) ? ((pixmap)->drawable.height - y) : h;
|
---|
962 |
|
---|
963 | glamor_prepare_access(&(pixmap)->drawable, GLAMOR_ACCESS_RO);
|
---|
964 | switch ((pixmap)->drawable.depth) {
|
---|
965 | case 8:
|
---|
966 | _glamor_dump_pixmap_byte(pixmap, x, y, w, h);
|
---|
967 | break;
|
---|
968 | case 15:
|
---|
969 | case 16:
|
---|
970 | _glamor_dump_pixmap_sword(pixmap, x, y, w, h);
|
---|
971 | break;
|
---|
972 |
|
---|
973 | case 24:
|
---|
974 | case 32:
|
---|
975 | _glamor_dump_pixmap_word(pixmap, x, y, w, h);
|
---|
976 | break;
|
---|
977 | case 1:
|
---|
978 | _glamor_dump_pixmap_bits(pixmap, x, y, w, h);
|
---|
979 | break;
|
---|
980 | default:
|
---|
981 | ErrorF("dump depth %d, not implemented.\n", (pixmap)->drawable.depth);
|
---|
982 | }
|
---|
983 | glamor_finish_access(&(pixmap)->drawable);
|
---|
984 | }
|
---|
985 |
|
---|
986 | static inline void
|
---|
987 | _glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
|
---|
988 | int x, int y, int w, int h,
|
---|
989 | PictFormatShort short_format, int all, int diffs)
|
---|
990 | {
|
---|
991 | int i, j;
|
---|
992 | unsigned char *p1 = pixmap1->devPrivate.ptr;
|
---|
993 | unsigned char *p2 = pixmap2->devPrivate.ptr;
|
---|
994 | int line_need_printed = 0;
|
---|
995 | int test_code = 0xAABBCCDD;
|
---|
996 | int little_endian = 0;
|
---|
997 | unsigned char *p_test;
|
---|
998 | int bpp = pixmap1->drawable.depth == 8 ? 1 : 4;
|
---|
999 | int stride = pixmap1->devKind;
|
---|
1000 |
|
---|
1001 | assert(pixmap1->devKind == pixmap2->devKind);
|
---|
1002 |
|
---|
1003 | ErrorF("stride:%d, width:%d, height:%d\n", stride, w, h);
|
---|
1004 |
|
---|
1005 | p1 = p1 + y * stride + x;
|
---|
1006 | p2 = p2 + y * stride + x;
|
---|
1007 |
|
---|
1008 | if (all) {
|
---|
1009 | for (i = 0; i < h; i++) {
|
---|
1010 | ErrorF("line %3d: ", i);
|
---|
1011 |
|
---|
1012 | for (j = 0; j < stride; j++) {
|
---|
1013 | if (j % bpp == 0)
|
---|
1014 | ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]);
|
---|
1015 | else
|
---|
1016 | ErrorF("%2x:%2x ", p1[j], p2[j]);
|
---|
1017 | }
|
---|
1018 |
|
---|
1019 | p1 += stride;
|
---|
1020 | p2 += stride;
|
---|
1021 | ErrorF("\n");
|
---|
1022 | }
|
---|
1023 | }
|
---|
1024 | else {
|
---|
1025 | if (short_format == PICT_a8r8g8b8) {
|
---|
1026 | p_test = (unsigned char *) &test_code;
|
---|
1027 | little_endian = (*p_test == 0xDD);
|
---|
1028 | bpp = 4;
|
---|
1029 |
|
---|
1030 | for (i = 0; i < h; i++) {
|
---|
1031 | line_need_printed = 0;
|
---|
1032 |
|
---|
1033 | for (j = 0; j < stride; j++) {
|
---|
1034 | if (p1[j] != p2[j] &&
|
---|
1035 | (p1[j] - p2[j] > diffs || p2[j] - p1[j] > diffs)) {
|
---|
1036 | if (line_need_printed) {
|
---|
1037 | if (little_endian) {
|
---|
1038 | switch (j % 4) {
|
---|
1039 | case 2:
|
---|
1040 | ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j],
|
---|
1041 | p2[j]);
|
---|
1042 | break;
|
---|
1043 | case 1:
|
---|
1044 | ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j],
|
---|
1045 | p2[j]);
|
---|
1046 | break;
|
---|
1047 | case 0:
|
---|
1048 | ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j],
|
---|
1049 | p2[j]);
|
---|
1050 | break;
|
---|
1051 | case 3:
|
---|
1052 | ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j],
|
---|
1053 | p2[j]);
|
---|
1054 | break;
|
---|
1055 | }
|
---|
1056 | }
|
---|
1057 | else {
|
---|
1058 | switch (j % 4) {
|
---|
1059 | case 1:
|
---|
1060 | ErrorF("[%d]RED:%2x:%2x ", j / bpp, p1[j],
|
---|
1061 | p2[j]);
|
---|
1062 | break;
|
---|
1063 | case 2:
|
---|
1064 | ErrorF("[%d]GREEN:%2x:%2x ", j / bpp, p1[j],
|
---|
1065 | p2[j]);
|
---|
1066 | break;
|
---|
1067 | case 3:
|
---|
1068 | ErrorF("[%d]BLUE:%2x:%2x ", j / bpp, p1[j],
|
---|
1069 | p2[j]);
|
---|
1070 | break;
|
---|
1071 | case 0:
|
---|
1072 | ErrorF("[%d]Alpha:%2x:%2x ", j / bpp, p1[j],
|
---|
1073 | p2[j]);
|
---|
1074 | break;
|
---|
1075 | }
|
---|
1076 | }
|
---|
1077 | }
|
---|
1078 | else {
|
---|
1079 | line_need_printed = 1;
|
---|
1080 | j = -1;
|
---|
1081 | ErrorF("line %3d: ", i);
|
---|
1082 | continue;
|
---|
1083 | }
|
---|
1084 | }
|
---|
1085 | }
|
---|
1086 |
|
---|
1087 | p1 += stride;
|
---|
1088 | p2 += stride;
|
---|
1089 | ErrorF("\n");
|
---|
1090 | }
|
---|
1091 | } //more format can be added here.
|
---|
1092 | else { // the default format, just print.
|
---|
1093 | for (i = 0; i < h; i++) {
|
---|
1094 | line_need_printed = 0;
|
---|
1095 |
|
---|
1096 | for (j = 0; j < stride; j++) {
|
---|
1097 | if (p1[j] != p2[j]) {
|
---|
1098 | if (line_need_printed) {
|
---|
1099 | ErrorF("[%d]%2x:%2x ", j / bpp, p1[j], p2[j]);
|
---|
1100 | }
|
---|
1101 | else {
|
---|
1102 | line_need_printed = 1;
|
---|
1103 | j = -1;
|
---|
1104 | ErrorF("line %3d: ", i);
|
---|
1105 | continue;
|
---|
1106 | }
|
---|
1107 | }
|
---|
1108 | }
|
---|
1109 |
|
---|
1110 | p1 += stride;
|
---|
1111 | p2 += stride;
|
---|
1112 | ErrorF("\n");
|
---|
1113 | }
|
---|
1114 | }
|
---|
1115 | }
|
---|
1116 | }
|
---|
1117 |
|
---|
1118 | static inline void
|
---|
1119 | glamor_compare_pixmaps(PixmapPtr pixmap1, PixmapPtr pixmap2,
|
---|
1120 | int x, int y, int w, int h, int all, int diffs)
|
---|
1121 | {
|
---|
1122 | assert(pixmap1->drawable.depth == pixmap2->drawable.depth);
|
---|
1123 |
|
---|
1124 | if (glamor_prepare_access(&pixmap1->drawable, GLAMOR_ACCESS_RO) &&
|
---|
1125 | glamor_prepare_access(&pixmap2->drawable, GLAMOR_ACCESS_RO)) {
|
---|
1126 | _glamor_compare_pixmaps(pixmap1, pixmap2, x, y, w, h, -1, all, diffs);
|
---|
1127 | }
|
---|
1128 | glamor_finish_access(&pixmap1->drawable);
|
---|
1129 | glamor_finish_access(&pixmap2->drawable);
|
---|
1130 | }
|
---|
1131 |
|
---|
1132 | /* This function is used to compare two pictures.
|
---|
1133 | If the picture has no drawable, we use fb functions to generate it. */
|
---|
1134 | static inline void
|
---|
1135 | glamor_compare_pictures(ScreenPtr screen,
|
---|
1136 | PicturePtr fst_picture,
|
---|
1137 | PicturePtr snd_picture,
|
---|
1138 | int x_source, int y_source,
|
---|
1139 | int width, int height, int all, int diffs)
|
---|
1140 | {
|
---|
1141 | PixmapPtr fst_pixmap;
|
---|
1142 | PixmapPtr snd_pixmap;
|
---|
1143 | int fst_generated, snd_generated;
|
---|
1144 | int error;
|
---|
1145 | int fst_type = -1;
|
---|
1146 | int snd_type = -1; // -1 represent has drawable.
|
---|
1147 |
|
---|
1148 | if (fst_picture->format != snd_picture->format) {
|
---|
1149 | ErrorF("Different picture format can not compare!\n");
|
---|
1150 | return;
|
---|
1151 | }
|
---|
1152 |
|
---|
1153 | if (!fst_picture->pDrawable) {
|
---|
1154 | fst_type = fst_picture->pSourcePict->type;
|
---|
1155 | }
|
---|
1156 |
|
---|
1157 | if (!snd_picture->pDrawable) {
|
---|
1158 | snd_type = snd_picture->pSourcePict->type;
|
---|
1159 | }
|
---|
1160 |
|
---|
1161 | if ((fst_type != -1) && (snd_type != -1) && (fst_type != snd_type)) {
|
---|
1162 | ErrorF("Different picture type will never be same!\n");
|
---|
1163 | return;
|
---|
1164 | }
|
---|
1165 |
|
---|
1166 | fst_generated = snd_generated = 0;
|
---|
1167 |
|
---|
1168 | if (!fst_picture->pDrawable) {
|
---|
1169 | PicturePtr pixman_pic;
|
---|
1170 | PixmapPtr pixmap = NULL;
|
---|
1171 | PictFormatShort format;
|
---|
1172 |
|
---|
1173 | format = fst_picture->format;
|
---|
1174 |
|
---|
1175 | pixmap = glamor_create_pixmap(screen,
|
---|
1176 | width, height,
|
---|
1177 | PIXMAN_FORMAT_DEPTH(format),
|
---|
1178 | GLAMOR_CREATE_PIXMAP_CPU);
|
---|
1179 |
|
---|
1180 | pixman_pic = CreatePicture(0,
|
---|
1181 | &(pixmap)->drawable,
|
---|
1182 | PictureMatchFormat(screen,
|
---|
1183 | PIXMAN_FORMAT_DEPTH
|
---|
1184 | (format), format), 0, 0,
|
---|
1185 | serverClient, &error);
|
---|
1186 |
|
---|
1187 | fbComposite(PictOpSrc, fst_picture, NULL, pixman_pic,
|
---|
1188 | x_source, y_source, 0, 0, 0, 0, width, height);
|
---|
1189 |
|
---|
1190 | glamor_destroy_pixmap(pixmap);
|
---|
1191 |
|
---|
1192 | fst_picture = pixman_pic;
|
---|
1193 | fst_generated = 1;
|
---|
1194 | }
|
---|
1195 |
|
---|
1196 | if (!snd_picture->pDrawable) {
|
---|
1197 | PicturePtr pixman_pic;
|
---|
1198 | PixmapPtr pixmap = NULL;
|
---|
1199 | PictFormatShort format;
|
---|
1200 |
|
---|
1201 | format = snd_picture->format;
|
---|
1202 |
|
---|
1203 | pixmap = glamor_create_pixmap(screen,
|
---|
1204 | width, height,
|
---|
1205 | PIXMAN_FORMAT_DEPTH(format),
|
---|
1206 | GLAMOR_CREATE_PIXMAP_CPU);
|
---|
1207 |
|
---|
1208 | pixman_pic = CreatePicture(0,
|
---|
1209 | &(pixmap)->drawable,
|
---|
1210 | PictureMatchFormat(screen,
|
---|
1211 | PIXMAN_FORMAT_DEPTH
|
---|
1212 | (format), format), 0, 0,
|
---|
1213 | serverClient, &error);
|
---|
1214 |
|
---|
1215 | fbComposite(PictOpSrc, snd_picture, NULL, pixman_pic,
|
---|
1216 | x_source, y_source, 0, 0, 0, 0, width, height);
|
---|
1217 |
|
---|
1218 | glamor_destroy_pixmap(pixmap);
|
---|
1219 |
|
---|
1220 | snd_picture = pixman_pic;
|
---|
1221 | snd_generated = 1;
|
---|
1222 | }
|
---|
1223 |
|
---|
1224 | fst_pixmap = glamor_get_drawable_pixmap(fst_picture->pDrawable);
|
---|
1225 | snd_pixmap = glamor_get_drawable_pixmap(snd_picture->pDrawable);
|
---|
1226 |
|
---|
1227 | if (fst_pixmap->drawable.depth != snd_pixmap->drawable.depth) {
|
---|
1228 | if (fst_generated)
|
---|
1229 | miDestroyPicture(fst_picture);
|
---|
1230 | if (snd_generated)
|
---|
1231 | miDestroyPicture(snd_picture);
|
---|
1232 |
|
---|
1233 | ErrorF("Different pixmap depth can not compare!\n");
|
---|
1234 | return;
|
---|
1235 | }
|
---|
1236 |
|
---|
1237 | if ((fst_type == SourcePictTypeLinear) ||
|
---|
1238 | (fst_type == SourcePictTypeRadial) ||
|
---|
1239 | (fst_type == SourcePictTypeConical) ||
|
---|
1240 | (snd_type == SourcePictTypeLinear) ||
|
---|
1241 | (snd_type == SourcePictTypeRadial) ||
|
---|
1242 | (snd_type == SourcePictTypeConical)) {
|
---|
1243 | x_source = y_source = 0;
|
---|
1244 | }
|
---|
1245 |
|
---|
1246 | if (glamor_prepare_access(&fst_pixmap->drawable, GLAMOR_ACCESS_RO) &&
|
---|
1247 | glamor_prepare_access(&snd_pixmap->drawable, GLAMOR_ACCESS_RO)) {
|
---|
1248 | _glamor_compare_pixmaps(fst_pixmap, snd_pixmap,
|
---|
1249 | x_source, y_source,
|
---|
1250 | width, height, fst_picture->format,
|
---|
1251 | all, diffs);
|
---|
1252 | }
|
---|
1253 | glamor_finish_access(&fst_pixmap->drawable);
|
---|
1254 | glamor_finish_access(&snd_pixmap->drawable);
|
---|
1255 |
|
---|
1256 | if (fst_generated)
|
---|
1257 | miDestroyPicture(fst_picture);
|
---|
1258 | if (snd_generated)
|
---|
1259 | miDestroyPicture(snd_picture);
|
---|
1260 |
|
---|
1261 | return;
|
---|
1262 | }
|
---|
1263 |
|
---|
1264 | #ifdef __i386__
|
---|
1265 | static inline unsigned long
|
---|
1266 | __fls(unsigned long x)
|
---|
1267 | {
|
---|
1268 | asm("bsr %1,%0":"=r"(x)
|
---|
1269 | : "rm"(x));
|
---|
1270 | return x;
|
---|
1271 | }
|
---|
1272 | #else
|
---|
1273 | static inline unsigned long
|
---|
1274 | __fls(unsigned long x)
|
---|
1275 | {
|
---|
1276 | int n;
|
---|
1277 |
|
---|
1278 | if (x == 0)
|
---|
1279 | return (0);
|
---|
1280 | n = 0;
|
---|
1281 | if (x <= 0x0000FFFF) {
|
---|
1282 | n = n + 16;
|
---|
1283 | x = x << 16;
|
---|
1284 | }
|
---|
1285 | if (x <= 0x00FFFFFF) {
|
---|
1286 | n = n + 8;
|
---|
1287 | x = x << 8;
|
---|
1288 | }
|
---|
1289 | if (x <= 0x0FFFFFFF) {
|
---|
1290 | n = n + 4;
|
---|
1291 | x = x << 4;
|
---|
1292 | }
|
---|
1293 | if (x <= 0x3FFFFFFF) {
|
---|
1294 | n = n + 2;
|
---|
1295 | x = x << 2;
|
---|
1296 | }
|
---|
1297 | if (x <= 0x7FFFFFFF) {
|
---|
1298 | n = n + 1;
|
---|
1299 | }
|
---|
1300 | return 31 - n;
|
---|
1301 | }
|
---|
1302 | #endif
|
---|
1303 |
|
---|
1304 | static inline void
|
---|
1305 | glamor_make_current(glamor_screen_private *glamor_priv)
|
---|
1306 | {
|
---|
1307 | if (lastGLContext != &glamor_priv->ctx) {
|
---|
1308 | lastGLContext = &glamor_priv->ctx;
|
---|
1309 | glamor_priv->ctx.make_current(&glamor_priv->ctx);
|
---|
1310 | }
|
---|
1311 | }
|
---|
1312 |
|
---|
1313 | /**
|
---|
1314 | * Helper function for implementing draws with GL_QUADS on GLES2,
|
---|
1315 | * where we don't have them.
|
---|
1316 | */
|
---|
1317 | static inline void
|
---|
1318 | glamor_glDrawArrays_GL_QUADS(glamor_screen_private *glamor_priv, unsigned count)
|
---|
1319 | {
|
---|
1320 | if (glamor_priv->use_quads) {
|
---|
1321 | glDrawArrays(GL_QUADS, 0, count * 4);
|
---|
1322 | } else {
|
---|
1323 | glamor_gldrawarrays_quads_using_indices(glamor_priv, count);
|
---|
1324 | }
|
---|
1325 | }
|
---|
1326 |
|
---|
1327 |
|
---|
1328 | #endif
|
---|