sna_trapezoids.h revision 428d7b3d
1#include <stdbool.h> 2 3#ifndef SNA_TRAPEZOIDS_H 4#define SNA_TRAPEZOIDS_H 5 6#define NO_ACCEL 0 7#define FORCE_FALLBACK 0 8#define NO_ALIGNED_BOXES 0 9#define NO_UNALIGNED_BOXES 0 10#define NO_SCAN_CONVERTER 0 11#define NO_GPU_THREADS 0 12 13#define NO_IMPRECISE 0 14#define NO_PRECISE 0 15 16#if 0 17#define __DBG DBG 18#else 19#define __DBG(x) 20#endif 21 22bool 23composite_aligned_boxes(struct sna *sna, 24 CARD8 op, 25 PicturePtr src, 26 PicturePtr dst, 27 PictFormatPtr maskFormat, 28 INT16 src_x, INT16 src_y, 29 int ntrap, const xTrapezoid *traps, 30 bool force_fallback); 31 32bool 33composite_unaligned_boxes(struct sna *sna, 34 CARD8 op, 35 PicturePtr src, 36 PicturePtr dst, 37 PictFormatPtr maskFormat, 38 INT16 src_x, INT16 src_y, 39 int ntrap, const xTrapezoid *traps, 40 bool force_fallback); 41 42bool 43mono_trapezoids_span_converter(struct sna *sna, 44 CARD8 op, PicturePtr src, PicturePtr dst, 45 INT16 src_x, INT16 src_y, 46 int ntrap, xTrapezoid *traps); 47 48bool 49mono_trapezoid_span_inplace(struct sna *sna, 50 CARD8 op, 51 PicturePtr src, 52 PicturePtr dst, 53 INT16 src_x, INT16 src_y, 54 int ntrap, xTrapezoid *traps); 55 56bool 57mono_triangles_span_converter(struct sna *sna, 58 CARD8 op, PicturePtr src, PicturePtr dst, 59 INT16 src_x, INT16 src_y, 60 int count, xTriangle *tri); 61 62bool 63imprecise_trapezoid_span_inplace(struct sna *sna, 64 CARD8 op, PicturePtr src, PicturePtr dst, 65 PictFormatPtr maskFormat, unsigned flags, 66 INT16 src_x, INT16 src_y, 67 int ntrap, xTrapezoid *traps, 68 bool fallback); 69 70bool 71imprecise_trapezoid_span_converter(struct sna *sna, 72 CARD8 op, PicturePtr src, PicturePtr dst, 73 PictFormatPtr maskFormat, unsigned int flags, 74 INT16 src_x, INT16 src_y, 75 int ntrap, xTrapezoid *traps); 76 77bool 78imprecise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, 79 PictFormatPtr maskFormat, unsigned flags, 80 INT16 src_x, INT16 src_y, 81 int ntrap, xTrapezoid *traps); 82 83bool 84imprecise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, 85 PictFormatPtr maskFormat, unsigned flags, 86 INT16 src_x, INT16 src_y, 87 int ntrap, xTrapezoid *traps); 88 89bool 90precise_trapezoid_span_inplace(struct sna *sna, 91 CARD8 op, PicturePtr src, PicturePtr dst, 92 PictFormatPtr maskFormat, unsigned flags, 93 INT16 src_x, INT16 src_y, 94 int ntrap, xTrapezoid *traps, 95 bool fallback); 96 97bool 98precise_trapezoid_span_converter(struct sna *sna, 99 CARD8 op, PicturePtr src, PicturePtr dst, 100 PictFormatPtr maskFormat, unsigned int flags, 101 INT16 src_x, INT16 src_y, 102 int ntrap, xTrapezoid *traps); 103 104bool 105precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, 106 PictFormatPtr maskFormat, unsigned flags, 107 INT16 src_x, INT16 src_y, 108 int ntrap, xTrapezoid *traps); 109 110bool 111precise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, 112 PictFormatPtr maskFormat, unsigned flags, 113 INT16 src_x, INT16 src_y, 114 int ntrap, xTrapezoid *traps); 115 116static inline bool is_mono(PicturePtr dst, PictFormatPtr mask) 117{ 118 return mask ? mask->depth < 8 : dst->polyEdge==PolyEdgeSharp; 119} 120 121static inline bool is_precise(PicturePtr dst, PictFormatPtr mask) 122{ 123 return dst->polyMode == PolyModePrecise && !is_mono(dst, mask); 124} 125 126static inline bool 127trapezoid_span_inplace(struct sna *sna, 128 CARD8 op, PicturePtr src, PicturePtr dst, 129 PictFormatPtr maskFormat, unsigned flags, 130 INT16 src_x, INT16 src_y, 131 int ntrap, xTrapezoid *traps, 132 bool fallback) 133{ 134 if (NO_SCAN_CONVERTER) 135 return false; 136 137 if (dst->alphaMap) { 138 DBG(("%s: fallback -- dst alphamap\n", 139 __FUNCTION__)); 140 return false; 141 } 142 143 if (!fallback && is_gpu(sna, dst->pDrawable, PREFER_GPU_SPANS)) { 144 DBG(("%s: fallback -- can not perform operation in place, destination busy\n", 145 __FUNCTION__)); 146 147 return false; 148 } 149 150 if (is_mono(dst, maskFormat)) 151 return mono_trapezoid_span_inplace(sna, op, src, dst, src_x, src_y, ntrap, traps); 152 else if (is_precise(dst, maskFormat)) 153 return precise_trapezoid_span_inplace(sna, op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps, fallback); 154 else 155 return imprecise_trapezoid_span_inplace(sna, op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps, fallback); 156} 157 158static inline bool 159trapezoid_span_converter(struct sna *sna, 160 CARD8 op, PicturePtr src, PicturePtr dst, 161 PictFormatPtr maskFormat, unsigned int flags, 162 INT16 src_x, INT16 src_y, 163 int ntrap, xTrapezoid *traps) 164{ 165 if (NO_SCAN_CONVERTER) 166 return false; 167 168 if (is_mono(dst, maskFormat)) 169 return mono_trapezoids_span_converter(sna, op, src, dst, src_x, src_y, ntrap, traps); 170 else if (is_precise(dst, maskFormat)) 171 return precise_trapezoid_span_converter(sna, op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); 172 else 173 return imprecise_trapezoid_span_converter(sna, op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); 174} 175 176static inline bool 177trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, 178 PictFormatPtr maskFormat, unsigned flags, 179 INT16 src_x, INT16 src_y, 180 int ntrap, xTrapezoid *traps) 181{ 182 if (NO_SCAN_CONVERTER) 183 return false; 184 185 if (is_precise(dst, maskFormat)) 186 return precise_trapezoid_mask_converter(op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); 187 else 188 return imprecise_trapezoid_mask_converter(op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); 189} 190 191static inline bool 192trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst, 193 PictFormatPtr maskFormat, unsigned flags, 194 INT16 src_x, INT16 src_y, 195 int ntrap, xTrapezoid *traps) 196{ 197 if (NO_SCAN_CONVERTER) 198 return false; 199 200 if (is_precise(dst, maskFormat)) 201 return precise_trapezoid_span_fallback(op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); 202 else 203 return imprecise_trapezoid_span_fallback(op, src, dst, maskFormat, flags, src_x, src_y, ntrap, traps); 204} 205 206bool 207mono_trap_span_converter(struct sna *sna, 208 PicturePtr dst, 209 INT16 x, INT16 y, 210 int ntrap, xTrap *traps); 211 212bool 213precise_trap_span_converter(struct sna *sna, 214 PicturePtr dst, 215 INT16 src_x, INT16 src_y, 216 int ntrap, xTrap *trap); 217 218bool 219imprecise_trap_span_converter(struct sna *sna, 220 PicturePtr dst, 221 INT16 src_x, INT16 src_y, 222 int ntrap, xTrap *trap); 223 224static inline bool 225trap_span_converter(struct sna *sna, 226 PicturePtr dst, 227 INT16 src_x, INT16 src_y, 228 int ntrap, xTrap *trap) 229{ 230 if (NO_SCAN_CONVERTER) 231 return false; 232 233 if (dst->polyEdge == PolyEdgeSharp || dst->pDrawable->depth < 8) 234 return mono_trap_span_converter(sna, dst, src_x, src_y, ntrap, trap); 235 else if (dst->polyMode == PolyModePrecise) 236 return precise_trap_span_converter(sna, dst, src_x, src_y, ntrap, trap); 237 else 238 return imprecise_trap_span_converter(sna, dst, src_x, src_y, ntrap, trap); 239} 240 241bool 242trap_mask_converter(struct sna *sna, 243 PicturePtr picture, 244 INT16 x, INT16 y, 245 int ntrap, xTrap *trap); 246 247bool 248triangles_span_converter(struct sna *sna, 249 CARD8 op, PicturePtr src, PicturePtr dst, 250 PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, 251 int count, xTriangle *tri); 252 253bool 254triangles_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst, 255 PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, 256 int count, xTriangle *tri); 257 258bool 259mono_tristrip_span_converter(struct sna *sna, 260 CARD8 op, PicturePtr src, PicturePtr dst, 261 INT16 src_x, INT16 src_y, 262 int count, xPointFixed *points); 263bool 264imprecise_tristrip_span_converter(struct sna *sna, 265 CARD8 op, PicturePtr src, PicturePtr dst, 266 PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, 267 int count, xPointFixed *points); 268bool 269precise_tristrip_span_converter(struct sna *sna, 270 CARD8 op, PicturePtr src, PicturePtr dst, 271 PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, 272 int count, xPointFixed *points); 273 274static inline bool 275tristrip_span_converter(struct sna *sna, 276 CARD8 op, PicturePtr src, PicturePtr dst, 277 PictFormatPtr maskFormat, INT16 src_x, INT16 src_y, 278 int count, xPointFixed *points) 279{ 280 if (NO_SCAN_CONVERTER) 281 return false; 282 283 if (is_mono(dst, maskFormat)) 284 return mono_tristrip_span_converter(sna, op, src, dst, src_x, src_y, count, points); 285 else if (is_precise(dst, maskFormat)) 286 return precise_tristrip_span_converter(sna, op, src, dst, maskFormat, src_x, src_y, count, points); 287 else 288 return imprecise_tristrip_span_converter(sna, op, src, dst, maskFormat, src_x, src_y, count, points); 289} 290 291inline static void trapezoid_origin(const xLineFixed *l, int16_t *x, int16_t *y) 292{ 293 if (l->p1.y < l->p2.y) { 294 *x = pixman_fixed_to_int(l->p1.x); 295 *y = pixman_fixed_to_int(l->p1.y); 296 } else { 297 *x = pixman_fixed_to_int(l->p2.x); 298 *y = pixman_fixed_to_int(l->p2.y); 299 } 300} 301 302#define ONE_HALF 0x7f 303#define RB_MASK 0x00ff00ff 304#define RB_ONE_HALF 0x007f007f 305#define RB_MASK_PLUS_ONE 0x01000100 306#define G_SHIFT 8 307 308static force_inline uint32_t 309mul8x2_8 (uint32_t a, uint8_t b) 310{ 311 uint32_t t = (a & RB_MASK) * b + RB_ONE_HALF; 312 return ((t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT) & RB_MASK; 313} 314 315static force_inline uint32_t 316add8x2_8x2(uint32_t a, uint32_t b) 317{ 318 uint32_t t = a + b; 319 t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); 320 return t & RB_MASK; 321} 322 323static force_inline uint32_t 324lerp8x4(uint32_t src, uint8_t a, uint32_t dst) 325{ 326 return (add8x2_8x2(mul8x2_8(src, a), 327 mul8x2_8(dst, ~a)) | 328 add8x2_8x2(mul8x2_8(src >> G_SHIFT, a), 329 mul8x2_8(dst >> G_SHIFT, ~a)) << G_SHIFT); 330} 331 332static force_inline uint8_t 333mul_8_8(uint8_t a, uint8_t b) 334{ 335 uint16_t t = a * (uint16_t)b + 0x7f; 336 return ((t >> 8) + t) >> 8; 337} 338 339static inline uint32_t multa(uint32_t s, uint8_t a, int shift) 340{ 341 return mul_8_8((s >> shift) & 0xff, a) << shift; 342} 343 344static inline uint32_t mul_4x8_8(uint32_t color, uint8_t alpha) 345{ 346 uint32_t v; 347 348 v = 0; 349 v |= multa(color, alpha, 24); 350 v |= multa(color, alpha, 16); 351 v |= multa(color, alpha, 8); 352 v |= multa(color, alpha, 0); 353 354 return v; 355} 356 357static inline bool 358xTriangleValid(const xTriangle *t) 359{ 360 xPointFixed v1, v2; 361 362 v1.x = t->p2.x - t->p1.x; 363 v1.y = t->p2.y - t->p1.y; 364 365 v2.x = t->p3.x - t->p1.x; 366 v2.y = t->p3.y - t->p1.y; 367 368 /* if the length of any edge is zero, the area must be zero */ 369 if (v1.x == 0 && v1.y == 0) 370 return false; 371 if (v2.x == 0 && v2.y == 0) 372 return false; 373 374 /* if the cross-product is zero, so it the size */ 375 return v2.y * v1.x != v1.y * v2.x; 376} 377 378#define SAMPLES_X 17 379#define SAMPLES_Y 15 380 381#define FAST_SAMPLES_shift 2 382#define FAST_SAMPLES_X (1<<FAST_SAMPLES_shift) 383#define FAST_SAMPLES_Y (1<<FAST_SAMPLES_shift) 384#define FAST_SAMPLES_mask ((1<<FAST_SAMPLES_shift)-1) 385 386#define pixman_fixed_integer_floor(V) pixman_fixed_to_int(V) 387#define pixman_fixed_integer_ceil(V) pixman_fixed_to_int(pixman_fixed_ceil(V)) 388 389static inline int pixman_fixed_to_fast(pixman_fixed_t v) 390{ 391 return (v + (1<<(16-FAST_SAMPLES_shift-1))) >> (16 - FAST_SAMPLES_shift); 392} 393 394bool trapezoids_bounds(int n, const xTrapezoid *t, BoxPtr box); 395 396#define TOR_INPLACE_SIZE 128 397 398#endif /* SNA_TRAPEZOIDS_H */ 399