OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkTextureCompressor_LATC.h" | 8 #include "SkTextureCompressor_LATC.h" |
9 #include "SkTextureCompressor_Blitter.h" | 9 #include "SkTextureCompressor_Blitter.h" |
10 | 10 |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 return compress_latc_block_bb_ignore_extremal(pixels); | 290 return compress_latc_block_bb_ignore_extremal(pixels); |
291 } | 291 } |
292 } | 292 } |
293 | 293 |
294 #endif // COMPRESS_LATC_SLOW | 294 #endif // COMPRESS_LATC_SLOW |
295 | 295 |
296 //////////////////////////////////////////////////////////////////////////////// | 296 //////////////////////////////////////////////////////////////////////////////// |
297 | 297 |
298 #if COMPRESS_LATC_FAST | 298 #if COMPRESS_LATC_FAST |
299 | 299 |
300 // Take the top three indices of each int and pack them into the low 12 | 300 // Take the top three bits of each index and pack them into the low 12 |
301 // bits of the integer. | 301 // bits of the integer. |
| 302 static inline uint32_t pack_index(uint32_t x) { |
| 303 // Pack it in... |
| 304 #if defined (SK_CPU_BENDIAN) |
| 305 return |
| 306 (x >> 24) | |
| 307 ((x >> 13) & 0x38) | |
| 308 ((x >> 2) & 0x1C0) | |
| 309 ((x << 9) & 0xE00); |
| 310 #else |
| 311 return |
| 312 (x & 0x7) | |
| 313 ((x >> 5) & 0x38) | |
| 314 ((x >> 10) & 0x1C0) | |
| 315 ((x >> 15) & 0xE00); |
| 316 #endif |
| 317 } |
| 318 |
| 319 // Converts each 8-bit byte in the integer into an LATC index, and then packs |
| 320 // the indices into the low 12 bits of the integer. |
302 static inline uint32_t convert_index(uint32_t x) { | 321 static inline uint32_t convert_index(uint32_t x) { |
303 // Since the palette is | 322 // Since the palette is |
304 // 255, 0, 219, 182, 146, 109, 73, 36 | 323 // 255, 0, 219, 182, 146, 109, 73, 36 |
305 // we need to map the high three bits of each byte in the integer | 324 // we need to map the high three bits of each byte in the integer |
306 // from | 325 // from |
307 // 0 1 2 3 4 5 6 7 | 326 // 0 1 2 3 4 5 6 7 |
308 // to | 327 // to |
309 // 1 7 6 5 4 3 2 0 | 328 // 1 7 6 5 4 3 2 0 |
310 // | 329 // |
311 // This first operation takes the mapping from | 330 // This first operation takes the mapping from |
312 // 0 1 2 3 4 5 6 7 --> 7 6 5 4 3 2 1 0 | 331 // 0 1 2 3 4 5 6 7 --> 7 6 5 4 3 2 1 0 |
313 x = 0x07070707 - ((x >> 5) & 0x07070707); | 332 x = 0x07070707 - ((x >> 5) & 0x07070707); |
314 | 333 |
315 // mask is 1 if index is non-zero | 334 // mask is 1 if index is non-zero |
316 const uint32_t mask = (x | (x >> 1) | (x >> 2)) & 0x01010101; | 335 const uint32_t mask = (x | (x >> 1) | (x >> 2)) & 0x01010101; |
317 | 336 |
318 // add mask: | 337 // add mask: |
319 // 7 6 5 4 3 2 1 0 --> 8 7 6 5 4 3 2 0 | 338 // 7 6 5 4 3 2 1 0 --> 8 7 6 5 4 3 2 0 |
320 x = (x + mask); | 339 x = (x + mask); |
321 | 340 |
322 // Handle overflow: | 341 // Handle overflow: |
323 // 8 7 6 5 4 3 2 0 --> 9 7 6 5 4 3 2 0 | 342 // 8 7 6 5 4 3 2 0 --> 9 7 6 5 4 3 2 0 |
324 x |= (x >> 3) & 0x01010101; | 343 x |= (x >> 3) & 0x01010101; |
325 | 344 |
326 // Mask out high bits: | 345 // Mask out high bits: |
327 // 9 7 6 5 4 3 2 0 --> 1 7 6 5 4 3 2 0 | 346 // 9 7 6 5 4 3 2 0 --> 1 7 6 5 4 3 2 0 |
328 x &= 0x07070707; | 347 x &= 0x07070707; |
329 | 348 |
330 // Pack it in... | 349 return pack_index(x); |
331 #if defined (SK_CPU_BENDIAN) | |
332 return | |
333 (x >> 24) | | |
334 ((x >> 13) & 0x38) | | |
335 ((x >> 2) & 0x1C0) | | |
336 ((x << 9) & 0xE00); | |
337 #else | |
338 return | |
339 (x & 0x7) | | |
340 ((x >> 5) & 0x38) | | |
341 ((x >> 10) & 0x1C0) | | |
342 ((x >> 15) & 0xE00); | |
343 #endif | |
344 } | 350 } |
345 | 351 |
346 typedef uint64_t (*PackIndicesProc)(const uint8_t* alpha, int rowBytes); | 352 typedef uint64_t (*PackIndicesProc)(const uint8_t* alpha, int rowBytes); |
347 template<PackIndicesProc packIndicesProc> | 353 template<PackIndicesProc packIndicesProc> |
348 static void compress_a8_latc_block(uint8_t** dstPtr, const uint8_t* src, int row
Bytes) { | 354 static void compress_a8_latc_block(uint8_t** dstPtr, const uint8_t* src, int row
Bytes) { |
349 *(reinterpret_cast<uint64_t*>(*dstPtr)) = | 355 *(reinterpret_cast<uint64_t*>(*dstPtr)) = |
350 SkEndian_SwapLE64(0xFF | (packIndicesProc(src, rowBytes) << 16)); | 356 SkEndian_SwapLE64(0xFF | (packIndicesProc(src, rowBytes) << 16)); |
351 *dstPtr += 8; | 357 *dstPtr += 8; |
352 } | 358 } |
353 | 359 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 struct CompressorLATC { | 426 struct CompressorLATC { |
421 static inline void CompressA8Vertical(uint8_t* dst, const uint8_t block[]) { | 427 static inline void CompressA8Vertical(uint8_t* dst, const uint8_t block[]) { |
422 compress_a8_latc_block<PackColumnMajor>(&dst, block, 4); | 428 compress_a8_latc_block<PackColumnMajor>(&dst, block, 4); |
423 } | 429 } |
424 | 430 |
425 static inline void CompressA8Horizontal(uint8_t* dst, const uint8_t* src, | 431 static inline void CompressA8Horizontal(uint8_t* dst, const uint8_t* src, |
426 int srcRowBytes) { | 432 int srcRowBytes) { |
427 compress_a8_latc_block<PackRowMajor>(&dst, src, srcRowBytes); | 433 compress_a8_latc_block<PackRowMajor>(&dst, src, srcRowBytes); |
428 } | 434 } |
429 | 435 |
430 static inline void UpdateBlock(uint8_t* dst, const uint8_t* src) { | 436 #if PEDANTIC_BLIT_RECT |
| 437 static inline void UpdateBlock(uint8_t* dst, const uint8_t* src, int srcRowB
ytes, |
| 438 const uint8_t* mask) { |
| 439 // Pack the mask |
| 440 uint64_t cmpMask = 0; |
| 441 for (int i = 0; i < 4; ++i) { |
| 442 const uint32_t idx = *(reinterpret_cast<const uint32_t*>(src + i*src
RowBytes)); |
| 443 cmpMask |= static_cast<uint64_t>(pack_index(idx)) << 12*i; |
| 444 } |
| 445 cmpMask = SkEndian_SwapLE64(cmpMask << 16); // avoid header |
| 446 |
| 447 uint64_t cmpSrc; |
| 448 uint8_t *cmpSrcPtr = reinterpret_cast<uint8_t*>(&cmpSrc); |
| 449 compress_a8_latc_block<PackRowMajor>(&cmpSrcPtr, src, srcRowBytes); |
| 450 |
| 451 // Mask out header |
| 452 cmpSrc = cmpSrc & cmpMask; |
| 453 |
| 454 // Read destination encoding |
| 455 uint64_t *cmpDst = reinterpret_cast<uint64_t*>(dst); |
| 456 |
| 457 // If the destination is the encoding for a blank block, then we need |
| 458 // to properly set the header |
| 459 if (0 == cmpDst) { |
| 460 *cmpDst = SkTEndian_SwapLE64(0x24924924924900FFULL); |
| 461 } |
| 462 |
| 463 // Set the new indices |
| 464 *cmpDst &= ~cmpMask; |
| 465 *cmpDst |= cmpSrc; |
431 } | 466 } |
| 467 #endif // PEDANTIC_BLIT_RECT |
432 }; | 468 }; |
433 | 469 |
434 //////////////////////////////////////////////////////////////////////////////// | 470 //////////////////////////////////////////////////////////////////////////////// |
435 | 471 |
436 namespace SkTextureCompressor { | 472 namespace SkTextureCompressor { |
437 | 473 |
438 bool CompressA8ToLATC(uint8_t* dst, const uint8_t* src, int width, int height, i
nt rowBytes) { | 474 bool CompressA8ToLATC(uint8_t* dst, const uint8_t* src, int width, int height, i
nt rowBytes) { |
439 #if COMPRESS_LATC_FAST | 475 #if COMPRESS_LATC_FAST |
440 return compress_4x4_a8_latc(dst, src, width, height, rowBytes); | 476 return compress_4x4_a8_latc(dst, src, width, height, rowBytes); |
441 #elif COMPRESS_LATC_SLOW | 477 #elif COMPRESS_LATC_SLOW |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 for (int j = 0; j < height; j += 4) { | 509 for (int j = 0; j < height; j += 4) { |
474 for (int i = 0; i < width; i += 4) { | 510 for (int i = 0; i < width; i += 4) { |
475 decompress_latc_block(dst + i, dstRowBytes, src); | 511 decompress_latc_block(dst + i, dstRowBytes, src); |
476 src += 8; | 512 src += 8; |
477 } | 513 } |
478 dst += 4 * dstRowBytes; | 514 dst += 4 * dstRowBytes; |
479 } | 515 } |
480 } | 516 } |
481 | 517 |
482 } // SkTextureCompressor | 518 } // SkTextureCompressor |
OLD | NEW |