Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(654)

Side by Side Diff: src/utils/SkTextureCompressor_Blitter.h

Issue 456873003: Add BlitRect to SkTCompressedAlphaBlitter (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Small nit Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/utils/SkTextureCompressor_ASTC.cpp ('k') | src/utils/SkTextureCompressor_LATC.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // Ostensibly, SkBlitter::BlitRect is supposed to set a rect of pixels to full
17 // alpha. This becomes problematic when using compressed texture blitters, since
18 // the rect rarely falls along block boundaries. The proper way to handle this i s
19 // to update the compressed encoding of a block by resetting the proper paramete rs
20 // (and even recompressing the block) where a rect falls inbetween block boundar ies.
21 // PEDANTIC_BLIT_RECT attempts to do this by requiring the struct passed to
22 // SkTCompressedAlphaBlitter to implement an UpdateBlock function call.
23 //
24 // However, the way that BlitRect gets used almost exclusively is to bracket inv erse
25 // fills for paths. In other words, the top few rows and bottom few rows of a pa th
26 // that's getting inverse filled are called using blitRect. The rest are called using
27 // the standard blitAntiH. As a result, we can just call blitAntiH with a faux RLE
28 // of full alpha values, and then check in our flush() call that we don't run of f the
29 // edge of the buffer. This is why we do not need this flag to be turned on.
30 #define PEDANTIC_BLIT_RECT 1
31
16 // This class implements a blitter that blits directly into a buffer that will 32 // This class implements a blitter that blits directly into a buffer that will
17 // be used as an compressed alpha texture. We compute this buffer by 33 // be used as an compressed alpha texture. We compute this buffer by
18 // buffering scan lines and then outputting them all at once. The number of 34 // buffering scan lines and then outputting them all at once. The number of
19 // scan lines buffered is controlled by kBlockSize 35 // scan lines buffered is controlled by kBlockSize
20 // 36 //
21 // The CompressorType is a struct with a bunch of static methods that provides 37 // 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 38 // the specialized compression functionality of the blitter. A complete Compress orType
23 // will implement the following static functions; 39 // will implement the following static functions;
24 // 40 //
25 // struct CompressorType { 41 // struct CompressorType {
26 // // The function used to compress an A8 block. The layout of the 42 // // The function used to compress an A8 block. The layout of the
27 // // block is also expected to be in column-major order. 43 // // block is also expected to be in column-major order.
28 // static void CompressA8Vertical(uint8_t* dst, const uint8_t block[]); 44 // static void CompressA8Vertical(uint8_t* dst, const uint8_t block[]);
29 // 45 //
30 // // The function used to compress an A8 block. The layout of the 46 // // The function used to compress an A8 block. The layout of the
31 // // block is also expected to be in row-major order. 47 // // block is also expected to be in row-major order.
32 // static void CompressA8Horizontal(uint8_t* dst, const uint8_t block[]); 48 // static void CompressA8Horizontal(uint8_t* dst, const uint8_t* src, int sr cRowBytes);
33 // 49 //
50 #if PEDANTIC_BLIT_RECT
34 // // The function used to update an already compressed block. This will 51 // // The function used to update an already compressed block. This will
35 // // most likely be implementation dependent. 52 // // most likely be implementation dependent. The mask variable will have
36 // static void UpdateBlock(uint8_t* dst, const uint8_t* src); 53 // // 0xFF in positions where the block should be updated and 0 in positions
54 // // where it shouldn't. src contains an uncompressed buffer of pixels.
55 // static void UpdateBlock(uint8_t* dst, const uint8_t* src, int srcRowBytes ,
56 // const uint8_t* mask);
57 #endif
37 // }; 58 // };
38 //
39 template<int BlockDim, int EncodedBlockSize, typename CompressorType> 59 template<int BlockDim, int EncodedBlockSize, typename CompressorType>
40 class SkTCompressedAlphaBlitter : public SkBlitter { 60 class SkTCompressedAlphaBlitter : public SkBlitter {
41 public: 61 public:
42 SkTCompressedAlphaBlitter(int width, int height, void *compressedBuffer) 62 SkTCompressedAlphaBlitter(int width, int height, void *compressedBuffer)
43 // 0x7FFE is one minus the largest positive 16-bit int. We use it for 63 // 0x7FFE is one minus the largest positive 16-bit int. We use it for
44 // debugging to make sure that we're properly setting the nextX distance 64 // debugging to make sure that we're properly setting the nextX distance
45 // in flushRuns(). 65 // in flushRuns().
46 #ifdef SK_DEBUG 66 #ifdef SK_DEBUG
47 : fBlitMaskCalled(false), 67 : fCalledOnceWithNonzeroY(false)
68 , fBlitMaskCalled(false),
48 #else 69 #else
49 : 70 :
50 #endif 71 #endif
51 kLongestRun(0x7FFE), kZeroAlpha(0) 72 kLongestRun(0x7FFE), kZeroAlpha(0)
52 , fNextRun(0) 73 , fNextRun(0)
53 , fWidth(width) 74 , fWidth(width)
54 , fHeight(height) 75 , fHeight(height)
55 , fBuffer(compressedBuffer) 76 , fBuffer(compressedBuffer)
56 { 77 {
57 SkASSERT((width % BlockDim) == 0); 78 SkASSERT((width % BlockDim) == 0);
58 SkASSERT((height % BlockDim) == 0); 79 SkASSERT((height % BlockDim) == 0);
59 } 80 }
60 81
61 virtual ~SkTCompressedAlphaBlitter() { this->flushRuns(); } 82 virtual ~SkTCompressedAlphaBlitter() { this->flushRuns(); }
62 83
63 // Blit a horizontal run of one or more pixels. 84 // Blit a horizontal run of one or more pixels.
64 virtual void blitH(int x, int y, int width) SK_OVERRIDE { 85 virtual void blitH(int x, int y, int width) SK_OVERRIDE {
65 // This function is intended to be called from any standard RGB 86 // This function is intended to be called from any standard RGB
66 // buffer, so we should never encounter it. However, if some code 87 // buffer, so we should never encounter it. However, if some code
67 // path does end up here, then this needs to be investigated. 88 // path does end up here, then this needs to be investigated.
68 SkFAIL("Not implemented!"); 89 SkFAIL("Not implemented!");
69 } 90 }
70 91
71 // Blit a horizontal run of antialiased pixels; runs[] is a *sparse* 92 // Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
72 // zero-terminated run-length encoding of spans of constant alpha values. 93 // zero-terminated run-length encoding of spans of constant alpha values.
73 virtual void blitAntiH(int x, int y, 94 virtual void blitAntiH(int x, int y,
74 const SkAlpha antialias[], 95 const SkAlpha antialias[],
75 const int16_t runs[]) SK_OVERRIDE { 96 const int16_t runs[]) SK_OVERRIDE {
97 SkASSERT(0 == x);
98
76 // Make sure that the new row to blit is either the first 99 // Make sure that the new row to blit is either the first
77 // row that we're blitting, or it's exactly the next scan row 100 // row that we're blitting, or it's exactly the next scan row
78 // since the last row that we blit. This is to ensure that when 101 // since the last row that we blit. This is to ensure that when
79 // we go to flush the runs, that they are all the same four 102 // we go to flush the runs, that they are all the same four
80 // runs. 103 // runs.
81 if (fNextRun > 0 && 104 if (fNextRun > 0 &&
82 ((x != fBufferedRuns[fNextRun-1].fX) || 105 ((x != fBufferedRuns[fNextRun-1].fX) ||
83 (y-1 != fBufferedRuns[fNextRun-1].fY))) { 106 (y-1 != fBufferedRuns[fNextRun-1].fY))) {
84 this->flushRuns(); 107 this->flushRuns();
85 } 108 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 // This function will be most easily implemented in one of two ways: 147 // This function will be most easily implemented in one of two ways:
125 // 1. Buffer each vertical column value and then construct a list 148 // 1. Buffer each vertical column value and then construct a list
126 // of alpha values and output all of the blocks at once. This only 149 // of alpha values and output all of the blocks at once. This only
127 // requires a write to the compressed buffer 150 // requires a write to the compressed buffer
128 // 2. Replace the indices of each block with the proper indices based 151 // 2. Replace the indices of each block with the proper indices based
129 // on the alpha value. This requires a read and write of the compress ed 152 // on the alpha value. This requires a read and write of the compress ed
130 // buffer, but much less overhead. 153 // buffer, but much less overhead.
131 SkFAIL("Not implemented!"); 154 SkFAIL("Not implemented!");
132 } 155 }
133 156
134 // Blit a solid rectangle one or more pixels wide. 157 // Blit a solid rectangle one or more pixels wide. It's assumed that blitRec t
158 // is called as a way to bracket blitAntiH where above and below the path th e
159 // called path just needs a solid rectangle to fill in the mask.
160 #ifdef SK_DEBUG
161 bool fCalledOnceWithNonzeroY;
162 #endif
135 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE { 163 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE {
136 // Analogous to blitRow, this function is intended for RGB targets 164
137 // and should never be called by this blitter. Any calls to this functio n 165 // Assumptions:
138 // are probably a bug and should be investigated. 166 SkASSERT(0 == x);
139 SkFAIL("Not implemented!"); 167 SkASSERT(width <= fWidth);
168
169 // Make sure that we're only ever bracketing calls to blitAntiH.
170 SkASSERT((0 == y) || (!fCalledOnceWithNonzeroY && (fCalledOnceWithNonzer oY = true)));
171
172 #if !(PEDANTIC_BLIT_RECT)
173 for (int i = 0; i < height; ++i) {
174 const SkAlpha kFullAlpha = 0xFF;
175 this->blitAntiH(x, y+i, &kFullAlpha, &kLongestRun);
176 }
177 #else
178 const int startBlockX = (x / BlockDim) * BlockDim;
179 const int startBlockY = (y / BlockDim) * BlockDim;
180
181 const int endBlockX = ((x + width) / BlockDim) * BlockDim;
182 const int endBlockY = ((y + height) / BlockDim) * BlockDim;
183
184 // If start and end are the same, then we only need to update a single b lock...
185 if (startBlockY == endBlockY && startBlockX == endBlockX) {
186 uint8_t mask[BlockDim*BlockDim];
187 memset(mask, 0, sizeof(mask));
188
189 const int xoff = x - startBlockX;
190 SkASSERT((xoff + width) <= BlockDim);
191
192 const int yoff = y - startBlockY;
193 SkASSERT((yoff + height) <= BlockDim);
194
195 for (int j = 0; j < height; ++j) {
196 memset(mask + (j + yoff)*BlockDim + xoff, 0xFF, width);
197 }
198
199 uint8_t* dst = this->getBlock(startBlockX, startBlockY);
200 CompressorType::UpdateBlock(dst, mask, BlockDim, mask);
201
202 // If start and end are the same in the y dimension, then we can freely update an
203 // entire row of blocks...
204 } else if (startBlockY == endBlockY) {
205
206 this->updateBlockRow(x, y, width, height, startBlockY, startBlockX, endBlockX);
207
208 // Similarly, if the start and end are in the same column, then we can j ust update
209 // an entire column of blocks...
210 } else if (startBlockX == endBlockX) {
211
212 this->updateBlockCol(x, y, width, height, startBlockX, startBlockY, endBlockY);
213
214 // Otherwise, the rect spans a non-trivial region of blocks, and we have to construct
215 // a kind of 9-patch to update each of the pieces of the rect. The top a nd bottom
216 // rows are updated using updateBlockRow, and the left and right columns are updated
217 // using updateBlockColumn. Anything in the middle is simply memset to a n opaque block
218 // encoding.
219 } else {
220
221 const int innerStartBlockX = startBlockX + BlockDim;
222 const int innerStartBlockY = startBlockY + BlockDim;
223
224 // Blit top row
225 const int topRowHeight = innerStartBlockY - y;
226 this->updateBlockRow(x, y, width, topRowHeight, startBlockY,
227 startBlockX, endBlockX);
228
229 // Advance y
230 y += topRowHeight;
231 height -= topRowHeight;
232
233 // Blit middle
234 if (endBlockY > innerStartBlockY) {
235
236 // Update left row
237 this->updateBlockCol(x, y, innerStartBlockX - x, endBlockY, star tBlockY,
238 startBlockX, innerStartBlockX);
239
240 // Update the middle with an opaque encoding...
241 uint8_t mask[BlockDim*BlockDim];
242 memset(mask, 0xFF, sizeof(mask));
243
244 uint8_t opaqueEncoding[EncodedBlockSize];
245 CompressorType::CompressA8Horizontal(opaqueEncoding, mask, Block Dim);
246
247 for (int j = innerStartBlockY; j < endBlockY; j += BlockDim) {
248 uint8_t* opaqueDst = this->getBlock(innerStartBlockX, j);
249 for (int i = innerStartBlockX; i < endBlockX; i += BlockDim) {
250 memcpy(opaqueDst, opaqueEncoding, EncodedBlockSize);
251 opaqueDst += EncodedBlockSize;
252 }
253 }
254
255 // If we need to update the right column, do that too
256 if (x + width > endBlockX) {
257 this->updateBlockCol(endBlockX, y, x + width - endBlockX, en dBlockY,
258 endBlockX, innerStartBlockY, endBlockY) ;
259 }
260
261 // Advance y
262 height = y + height - endBlockY;
263 y = endBlockY;
264 }
265
266 // If we need to update the last row, then do that, too.
267 if (height > 0) {
268 this->updateBlockRow(x, y, width, height, endBlockY,
269 startBlockX, endBlockX);
270 }
271 }
272 #endif
140 } 273 }
141 274
142 // Blit a rectangle with one alpha-blended column on the left, 275 // Blit a rectangle with one alpha-blended column on the left,
143 // width (zero or more) opaque pixels, and one alpha-blended column 276 // width (zero or more) opaque pixels, and one alpha-blended column
144 // on the right. The result will always be at least two pixels wide. 277 // on the right. The result will always be at least two pixels wide.
145 virtual void blitAntiRect(int x, int y, int width, int height, 278 virtual void blitAntiRect(int x, int y, int width, int height,
146 SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE { 279 SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE {
147 // This function is currently not implemented. It is not explicitly 280 // This function is currently not implemented. It is not explicitly
148 // required by the contract, but if at some time a code path runs into 281 // required by the contract, but if at some time a code path runs into
149 // this function (which is entirely possible), it needs to be implemente d. 282 // this function (which is entirely possible), it needs to be implemente d.
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 for (int i = 0; i < BlockDim; ++i) { 526 for (int i = 0; i < BlockDim; ++i) {
394 nextX[i] = *(fBufferedRuns[i].fRuns); 527 nextX[i] = *(fBufferedRuns[i].fRuns);
395 curAlpha[i] = *(fBufferedRuns[i].fAlphas); 528 curAlpha[i] = *(fBufferedRuns[i].fAlphas);
396 529
397 finalX = SkMin32(nextX[i], finalX); 530 finalX = SkMin32(nextX[i], finalX);
398 } 531 }
399 532
400 // Make sure that we have a valid right-bound X value 533 // Make sure that we have a valid right-bound X value
401 SkASSERT(finalX < 0xFFFFF); 534 SkASSERT(finalX < 0xFFFFF);
402 535
536 // If the finalX is the longest run, then just blit until we have
537 // width...
538 if (kLongestRun == finalX) {
539 finalX = fWidth;
540 }
541
403 // Run the blitter... 542 // Run the blitter...
404 while (curX != finalX) { 543 while (curX != finalX) {
405 SkASSERT(finalX >= curX); 544 SkASSERT(finalX >= curX);
406 545
407 // Do we need to populate the rest of the block? 546 // Do we need to populate the rest of the block?
408 if ((finalX - (BlockDim*(curX / BlockDim))) >= BlockDim) { 547 if ((finalX - (BlockDim*(curX / BlockDim))) >= BlockDim) {
409 const int col = curX % BlockDim; 548 const int col = curX % BlockDim;
410 const int colsLeft = BlockDim - col; 549 const int colsLeft = BlockDim - col;
411 SkASSERT(curX + colsLeft <= finalX); 550 SkASSERT(curX + colsLeft <= finalX);
412 551
(...skipping 29 matching lines...) Expand all
442 const int col = curX % BlockDim; 581 const int col = curX % BlockDim;
443 const int colsLeft = finalX - curX; 582 const int colsLeft = finalX - curX;
444 583
445 this->updateBlockColumns(block, col, colsLeft, curAlphaColumn); 584 this->updateBlockColumns(block, col, colsLeft, curAlphaColumn);
446 curX += colsLeft; 585 curX += colsLeft;
447 } 586 }
448 587
449 SkASSERT(curX == finalX); 588 SkASSERT(curX == finalX);
450 589
451 // Figure out what the next advancement is... 590 // Figure out what the next advancement is...
452 for (int i = 0; i < BlockDim; ++i) { 591 if (finalX < fWidth) {
453 if (nextX[i] == finalX) { 592 for (int i = 0; i < BlockDim; ++i) {
454 const int16_t run = *(fBufferedRuns[i].fRuns); 593 if (nextX[i] == finalX) {
455 fBufferedRuns[i].fRuns += run; 594 const int16_t run = *(fBufferedRuns[i].fRuns);
456 fBufferedRuns[i].fAlphas += run; 595 fBufferedRuns[i].fRuns += run;
457 curAlpha[i] = *(fBufferedRuns[i].fAlphas); 596 fBufferedRuns[i].fAlphas += run;
458 nextX[i] += *(fBufferedRuns[i].fRuns); 597 curAlpha[i] = *(fBufferedRuns[i].fAlphas);
598 nextX[i] += *(fBufferedRuns[i].fRuns);
599 }
459 } 600 }
460 }
461 601
462 finalX = 0xFFFFF; 602 finalX = 0xFFFFF;
463 for (int i = 0; i < BlockDim; ++i) { 603 for (int i = 0; i < BlockDim; ++i) {
464 finalX = SkMin32(nextX[i], finalX); 604 finalX = SkMin32(nextX[i], finalX);
605 }
606 } else {
607 curX = finalX;
465 } 608 }
466 } 609 }
467 610
468 // If we didn't land on a block boundary, output the block... 611 // If we didn't land on a block boundary, output the block...
469 if ((curX % BlockDim) > 0) { 612 if ((curX % BlockDim) > 0) {
470 #ifdef SK_DEBUG 613 #ifdef SK_DEBUG
471 for (int i = 0; i < BlockDim; ++i) { 614 for (int i = 0; i < BlockDim; ++i) {
472 SkASSERT(nextX[i] == kLongestRun || nextX[i] == curX); 615 SkASSERT(nextX[i] == kLongestRun || nextX[i] == curX);
473 } 616 }
474 #endif 617 #endif
475 const int col = curX % BlockDim; 618 const int col = curX % BlockDim;
476 const int colsLeft = BlockDim - col; 619 const int colsLeft = BlockDim - col;
477 620
478 memset(curAlphaColumn, 0, sizeof(curAlphaColumn)); 621 memset(curAlphaColumn, 0, sizeof(curAlphaColumn));
479 this->updateBlockColumns(block, col, colsLeft, curAlphaColumn); 622 this->updateBlockColumns(block, col, colsLeft, curAlphaColumn);
480 623
481 CompressorType::CompressA8Vertical(outPtr, reinterpret_cast<uint8_t* >(block)); 624 CompressorType::CompressA8Vertical(outPtr, reinterpret_cast<uint8_t* >(block));
482 } 625 }
483 626
484 fNextRun = 0; 627 fNextRun = 0;
485 } 628 }
629
630 #if PEDANTIC_BLIT_RECT
631 void updateBlockRow(int x, int y, int width, int height,
632 int blockRow, int startBlockX, int endBlockX) {
633 if (0 == width || 0 == height || startBlockX == endBlockX) {
634 return;
635 }
636
637 uint8_t* dst = this->getBlock(startBlockX, BlockDim * (y / BlockDim));
638
639 // One horizontal strip to update
640 uint8_t mask[BlockDim*BlockDim];
641 memset(mask, 0, sizeof(mask));
642
643 // Update the left cap
644 int blockX = startBlockX;
645 const int yoff = y - blockRow;
646 for (int j = 0; j < height; ++j) {
647 const int xoff = x - blockX;
648 memset(mask + (j + yoff)*BlockDim + xoff, 0xFF, BlockDim - xoff);
649 }
650 CompressorType::UpdateBlock(dst, mask, BlockDim, mask);
651 dst += EncodedBlockSize;
652 blockX += BlockDim;
653
654 // Update the middle
655 if (blockX < endBlockX) {
656 for (int j = 0; j < height; ++j) {
657 memset(mask + (j + yoff)*BlockDim, 0xFF, BlockDim);
658 }
659 while (blockX < endBlockX) {
660 CompressorType::UpdateBlock(dst, mask, BlockDim, mask);
661 dst += EncodedBlockSize;
662 blockX += BlockDim;
663 }
664 }
665
666 SkASSERT(endBlockX == blockX);
667
668 // Update the right cap (if we need to)
669 if (x + width > endBlockX) {
670 memset(mask, 0, sizeof(mask));
671 for (int j = 0; j < height; ++j) {
672 const int xoff = (x+width-blockX);
673 memset(mask + (j+yoff)*BlockDim, 0xFF, xoff);
674 }
675 CompressorType::UpdateBlock(dst, mask, BlockDim, mask);
676 }
677 }
678
679 void updateBlockCol(int x, int y, int width, int height,
680 int blockCol, int startBlockY, int endBlockY) {
681 if (0 == width || 0 == height || startBlockY == endBlockY) {
682 return;
683 }
684
685 // One vertical strip to update
686 uint8_t mask[BlockDim*BlockDim];
687 memset(mask, 0, sizeof(mask));
688 const int maskX0 = x - blockCol;
689 const int maskWidth = maskX0 + width;
690 SkASSERT(maskWidth <= BlockDim);
691
692 // Update the top cap
693 int blockY = startBlockY;
694 for (int j = (y - blockY); j < BlockDim; ++j) {
695 memset(mask + maskX0 + j*BlockDim, 0xFF, maskWidth);
696 }
697 CompressorType::UpdateBlock(this->getBlock(blockCol, blockY), mask, Bloc kDim, mask);
698 blockY += BlockDim;
699
700 // Update middle
701 if (blockY < endBlockY) {
702 for (int j = 0; j < BlockDim; ++j) {
703 memset(mask + maskX0 + j*BlockDim, 0xFF, maskWidth);
704 }
705 while (blockY < endBlockY) {
706 CompressorType::UpdateBlock(this->getBlock(blockCol, blockY),
707 mask, BlockDim, mask);
708 blockY += BlockDim;
709 }
710 }
711
712 SkASSERT(endBlockY == blockY);
713
714 // Update bottom
715 if (y + height > endBlockY) {
716 for (int j = y+height; j < endBlockY + BlockDim; ++j) {
717 memset(mask + (j-endBlockY)*BlockDim, 0, BlockDim);
718 }
719 CompressorType::UpdateBlock(this->getBlock(blockCol, blockY),
720 mask, BlockDim, mask);
721 }
722 }
723 #endif // PEDANTIC_BLIT_RECT
724
486 }; 725 };
487 726
488 } // namespace SkTextureCompressor 727 } // namespace SkTextureCompressor
489 728
490 #endif // SkTextureCompressor_Blitter_DEFINED 729 #endif // SkTextureCompressor_Blitter_DEFINED
OLDNEW
« no previous file with comments | « src/utils/SkTextureCompressor_ASTC.cpp ('k') | src/utils/SkTextureCompressor_LATC.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698