| 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 #ifndef SkTextureCompressor_Blitter_DEFINED | 8 #ifndef SkTextureCompressor_Blitter_DEFINED | 
| 9 #define SkTextureCompressor_Blitter_DEFINED | 9 #define SkTextureCompressor_Blitter_DEFINED | 
| 10 | 10 | 
| 11 #include "SkTypes.h" | 11 #include "SkTypes.h" | 
| 12 #include "SkBlitter.h" | 12 #include "SkBlitter.h" | 
| 13 | 13 | 
| 14 namespace SkTextureCompressor { | 14 namespace SkTextureCompressor { | 
| 15 | 15 | 
| 16 // The function used to compress an A8 block. This function is expected to be |  | 
| 17 // used as a template argument to SkCompressedAlphaBlitter. The layout of the |  | 
| 18 // block is also expected to be in column-major order. |  | 
| 19 typedef void (*CompressA8Proc)(uint8_t* dst, const uint8_t block[]); |  | 
| 20 |  | 
| 21 // This class implements a blitter that blits directly into a buffer that will | 16 // This class implements a blitter that blits directly into a buffer that will | 
| 22 // be used as an compressed alpha texture. We compute this buffer by | 17 // be used as an compressed alpha texture. We compute this buffer by | 
| 23 // buffering scan lines and then outputting them all at once. The number of | 18 // buffering scan lines and then outputting them all at once. The number of | 
| 24 // scan lines buffered is controlled by kBlockSize | 19 // scan lines buffered is controlled by kBlockSize | 
| 25 template<int BlockDim, int EncodedBlockSize, CompressA8Proc CompressionProc> | 20 // | 
|  | 21 // The CompressorType is a struct with a bunch of static methods that provides | 
|  | 22 // the specialized compression functionality of the blitter. A complete Compress
     orType | 
|  | 23 // will implement the following static functions; | 
|  | 24 // | 
|  | 25 // struct CompressorType { | 
|  | 26 //     // The function used to compress an A8 block. The layout of the | 
|  | 27 //     // block is also expected to be in column-major order. | 
|  | 28 //     static void CompressA8Vertical(uint8_t* dst, const uint8_t block[]); | 
|  | 29 // | 
|  | 30 //     // The function used to compress an A8 block. The layout of the | 
|  | 31 //     // block is also expected to be in row-major order. | 
|  | 32 //     static void CompressA8Horizontal(uint8_t* dst, const uint8_t block[]); | 
|  | 33 // | 
|  | 34 //     // The function used to update an already compressed block. This will | 
|  | 35 //     // most likely be implementation dependent. | 
|  | 36 //     static void UpdateBlock(uint8_t* dst, const uint8_t* src); | 
|  | 37 // }; | 
|  | 38 // | 
|  | 39 template<int BlockDim, int EncodedBlockSize, typename CompressorType> | 
| 26 class SkTCompressedAlphaBlitter : public SkBlitter { | 40 class SkTCompressedAlphaBlitter : public SkBlitter { | 
| 27 public: | 41 public: | 
| 28     SkTCompressedAlphaBlitter(int width, int height, void *compressedBuffer) | 42     SkTCompressedAlphaBlitter(int width, int height, void *compressedBuffer) | 
| 29         // 0x7FFE is one minus the largest positive 16-bit int. We use it for | 43         // 0x7FFE is one minus the largest positive 16-bit int. We use it for | 
| 30         // debugging to make sure that we're properly setting the nextX distance | 44         // debugging to make sure that we're properly setting the nextX distance | 
| 31         // in flushRuns(). | 45         // in flushRuns(). | 
| 32         : kLongestRun(0x7FFE), kZeroAlpha(0) | 46         : kLongestRun(0x7FFE), kZeroAlpha(0) | 
| 33         , fNextRun(0) | 47         , fNextRun(0) | 
| 34         , fWidth(width) | 48         , fWidth(width) | 
| 35         , fHeight(height) | 49         , fHeight(height) | 
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 332 | 346 | 
| 333             // Do we need to populate the rest of the block? | 347             // Do we need to populate the rest of the block? | 
| 334             if ((finalX - (BlockDim*(curX / BlockDim))) >= BlockDim) { | 348             if ((finalX - (BlockDim*(curX / BlockDim))) >= BlockDim) { | 
| 335                 const int col = curX % BlockDim; | 349                 const int col = curX % BlockDim; | 
| 336                 const int colsLeft = BlockDim - col; | 350                 const int colsLeft = BlockDim - col; | 
| 337                 SkASSERT(curX + colsLeft <= finalX); | 351                 SkASSERT(curX + colsLeft <= finalX); | 
| 338 | 352 | 
| 339                 this->updateBlockColumns(block, col, colsLeft, curAlphaColumn); | 353                 this->updateBlockColumns(block, col, colsLeft, curAlphaColumn); | 
| 340 | 354 | 
| 341                 // Write this block | 355                 // Write this block | 
| 342                 CompressionProc(outPtr, reinterpret_cast<uint8_t*>(block)); | 356                 CompressorType::CompressA8Vertical(outPtr, reinterpret_cast<uint
     8_t*>(block)); | 
| 343                 outPtr += EncodedBlockSize; | 357                 outPtr += EncodedBlockSize; | 
| 344                 curX += colsLeft; | 358                 curX += colsLeft; | 
| 345             } | 359             } | 
| 346 | 360 | 
| 347             // If we can advance even further, then just keep memsetting the blo
     ck | 361             // If we can advance even further, then just keep memsetting the blo
     ck | 
| 348             if ((finalX - curX) >= BlockDim) { | 362             if ((finalX - curX) >= BlockDim) { | 
| 349                 SkASSERT((curX % BlockDim) == 0); | 363                 SkASSERT((curX % BlockDim) == 0); | 
| 350 | 364 | 
| 351                 const int col = 0; | 365                 const int col = 0; | 
| 352                 const int colsLeft = BlockDim; | 366                 const int colsLeft = BlockDim; | 
| 353 | 367 | 
| 354                 this->updateBlockColumns(block, col, colsLeft, curAlphaColumn); | 368                 this->updateBlockColumns(block, col, colsLeft, curAlphaColumn); | 
| 355 | 369 | 
| 356                 // While we can keep advancing, just keep writing the block. | 370                 // While we can keep advancing, just keep writing the block. | 
| 357                 uint8_t lastBlock[EncodedBlockSize]; | 371                 uint8_t lastBlock[EncodedBlockSize]; | 
| 358                 CompressionProc(lastBlock, reinterpret_cast<uint8_t*>(block)); | 372                 CompressorType::CompressA8Vertical(lastBlock, reinterpret_cast<u
     int8_t*>(block)); | 
| 359                 while((finalX - curX) >= BlockDim) { | 373                 while((finalX - curX) >= BlockDim) { | 
| 360                     memcpy(outPtr, lastBlock, EncodedBlockSize); | 374                     memcpy(outPtr, lastBlock, EncodedBlockSize); | 
| 361                     outPtr += EncodedBlockSize; | 375                     outPtr += EncodedBlockSize; | 
| 362                     curX += BlockDim; | 376                     curX += BlockDim; | 
| 363                 } | 377                 } | 
| 364             } | 378             } | 
| 365 | 379 | 
| 366             // If we haven't advanced within the block then do so. | 380             // If we haven't advanced within the block then do so. | 
| 367             if (curX < finalX) { | 381             if (curX < finalX) { | 
| 368                 const int col = curX % BlockDim; | 382                 const int col = curX % BlockDim; | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 386             } | 400             } | 
| 387 | 401 | 
| 388             finalX = 0xFFFFF; | 402             finalX = 0xFFFFF; | 
| 389             for (int i = 0; i < BlockDim; ++i) { | 403             for (int i = 0; i < BlockDim; ++i) { | 
| 390                 finalX = SkMin32(nextX[i], finalX); | 404                 finalX = SkMin32(nextX[i], finalX); | 
| 391             } | 405             } | 
| 392         } | 406         } | 
| 393 | 407 | 
| 394         // If we didn't land on a block boundary, output the block... | 408         // If we didn't land on a block boundary, output the block... | 
| 395         if ((curX % BlockDim) > 1) { | 409         if ((curX % BlockDim) > 1) { | 
| 396             CompressionProc(outPtr, reinterpret_cast<uint8_t*>(block)); | 410             CompressorType::CompressA8Vertical(outPtr, reinterpret_cast<uint8_t*
     >(block)); | 
| 397         } | 411         } | 
| 398 | 412 | 
| 399         fNextRun = 0; | 413         fNextRun = 0; | 
| 400     } | 414     } | 
| 401 }; | 415 }; | 
| 402 | 416 | 
| 403 }  // namespace SkTextureCompressor | 417 }  // namespace SkTextureCompressor | 
| 404 | 418 | 
| 405 #endif  // SkTextureCompressor_Blitter_DEFINED | 419 #endif  // SkTextureCompressor_Blitter_DEFINED | 
| OLD | NEW | 
|---|