1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SkBitmapProcState.h" 9#include "SkBitmapProcState_filter.h" 10#include "SkColorPriv.h" 11#include "SkFilterProc.h" 12#include "SkPaint.h" 13#include "SkShader.h" // for tilemodes 14 15// returns expanded * 5bits 16static inline uint32_t Filter_565_Expanded(unsigned x, unsigned y, 17 uint32_t a00, uint32_t a01, 18 uint32_t a10, uint32_t a11) { 19 SkASSERT((unsigned)x <= 0xF); 20 SkASSERT((unsigned)y <= 0xF); 21 22 a00 = SkExpand_rgb_16(a00); 23 a01 = SkExpand_rgb_16(a01); 24 a10 = SkExpand_rgb_16(a10); 25 a11 = SkExpand_rgb_16(a11); 26 27 int xy = x * y >> 3; 28 return a00 * (32 - 2*y - 2*x + xy) + 29 a01 * (2*x - xy) + 30 a10 * (2*y - xy) + 31 a11 * xy; 32} 33 34// turn an expanded 565 * 5bits into SkPMColor 35// g:11 | r:10 | x:1 | b:10 36static inline SkPMColor SkExpanded_565_To_PMColor(uint32_t c) { 37 unsigned r = (c >> 13) & 0xFF; 38 unsigned g = (c >> 24); 39 unsigned b = (c >> 2) & 0xFF; 40 return SkPackARGB32(0xFF, r, g, b); 41} 42 43// returns answer in SkPMColor format 44static inline SkPMColor Filter_4444_D32(unsigned x, unsigned y, 45 uint32_t a00, uint32_t a01, 46 uint32_t a10, uint32_t a11) { 47 SkASSERT((unsigned)x <= 0xF); 48 SkASSERT((unsigned)y <= 0xF); 49 50 a00 = SkExpand_4444(a00); 51 a01 = SkExpand_4444(a01); 52 a10 = SkExpand_4444(a10); 53 a11 = SkExpand_4444(a11); 54 55 int xy = x * y >> 4; 56 uint32_t result = a00 * (16 - y - x + xy) + 57 a01 * (x - xy) + 58 a10 * (y - xy) + 59 a11 * xy; 60 61 return SkCompact_8888(result); 62} 63 64static inline U8CPU Filter_8(unsigned x, unsigned y, 65 U8CPU a00, U8CPU a01, 66 U8CPU a10, U8CPU a11) { 67 SkASSERT((unsigned)x <= 0xF); 68 SkASSERT((unsigned)y <= 0xF); 69 70 int xy = x * y; 71 unsigned result = a00 * (256 - 16*y - 16*x + xy) + 72 a01 * (16*x - xy) + 73 a10 * (16*y - xy) + 74 a11 * xy; 75 76 return result >> 8; 77} 78 79/***************************************************************************** 80 * 81 * D32 functions 82 * 83 */ 84 85// SRC == 8888 86 87#define FILTER_PROC(x, y, a, b, c, d, dst) Filter_32_opaque(x, y, a, b, c, d, dst) 88 89#define MAKENAME(suffix) S32_opaque_D32 ## suffix 90#define DSTSIZE 32 91#define SRCTYPE SkPMColor 92#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_8888_Config); \ 93 SkASSERT(state.fAlphaScale == 256) 94#define RETURNDST(src) src 95#define SRC_TO_FILTER(src) src 96#include "SkBitmapProcState_sample.h" 97 98#undef FILTER_PROC 99#define FILTER_PROC(x, y, a, b, c, d, dst) Filter_32_alpha(x, y, a, b, c, d, dst, alphaScale) 100 101#define MAKENAME(suffix) S32_alpha_D32 ## suffix 102#define DSTSIZE 32 103#define SRCTYPE SkPMColor 104#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_8888_Config); \ 105 SkASSERT(state.fAlphaScale < 256) 106#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale 107#define RETURNDST(src) SkAlphaMulQ(src, alphaScale) 108#define SRC_TO_FILTER(src) src 109#include "SkBitmapProcState_sample.h" 110 111// SRC == 565 112 113#undef FILTER_PROC 114#define FILTER_PROC(x, y, a, b, c, d, dst) \ 115 do { \ 116 uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d); \ 117 *(dst) = SkExpanded_565_To_PMColor(tmp); \ 118 } while (0) 119 120#define MAKENAME(suffix) S16_opaque_D32 ## suffix 121#define DSTSIZE 32 122#define SRCTYPE uint16_t 123#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config); \ 124 SkASSERT(state.fAlphaScale == 256) 125#define RETURNDST(src) SkPixel16ToPixel32(src) 126#define SRC_TO_FILTER(src) src 127#include "SkBitmapProcState_sample.h" 128 129#undef FILTER_PROC 130#define FILTER_PROC(x, y, a, b, c, d, dst) \ 131 do { \ 132 uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d); \ 133 *(dst) = SkAlphaMulQ(SkExpanded_565_To_PMColor(tmp), alphaScale); \ 134 } while (0) 135 136#define MAKENAME(suffix) S16_alpha_D32 ## suffix 137#define DSTSIZE 32 138#define SRCTYPE uint16_t 139#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config); \ 140 SkASSERT(state.fAlphaScale < 256) 141#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale 142#define RETURNDST(src) SkAlphaMulQ(SkPixel16ToPixel32(src), alphaScale) 143#define SRC_TO_FILTER(src) src 144#include "SkBitmapProcState_sample.h" 145 146// SRC == Index8 147 148#undef FILTER_PROC 149#define FILTER_PROC(x, y, a, b, c, d, dst) Filter_32_opaque(x, y, a, b, c, d, dst) 150 151#define MAKENAME(suffix) SI8_opaque_D32 ## suffix 152#define DSTSIZE 32 153#define SRCTYPE uint8_t 154#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kIndex8_Config); \ 155 SkASSERT(state.fAlphaScale == 256) 156#define PREAMBLE(state) const SkPMColor* SK_RESTRICT table = state.fBitmap->getColorTable()->lockColors() 157#define RETURNDST(src) table[src] 158#define SRC_TO_FILTER(src) table[src] 159#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlockColors(false) 160#include "SkBitmapProcState_sample.h" 161 162#undef FILTER_PROC 163#define FILTER_PROC(x, y, a, b, c, d, dst) Filter_32_alpha(x, y, a, b, c, d, dst, alphaScale) 164 165#define MAKENAME(suffix) SI8_alpha_D32 ## suffix 166#define DSTSIZE 32 167#define SRCTYPE uint8_t 168#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kIndex8_Config); \ 169 SkASSERT(state.fAlphaScale < 256) 170#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale; \ 171 const SkPMColor* SK_RESTRICT table = state.fBitmap->getColorTable()->lockColors() 172#define RETURNDST(src) SkAlphaMulQ(table[src], alphaScale) 173#define SRC_TO_FILTER(src) table[src] 174#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlockColors(false) 175#include "SkBitmapProcState_sample.h" 176 177// SRC == 4444 178 179#undef FILTER_PROC 180#define FILTER_PROC(x, y, a, b, c, d, dst) *(dst) = Filter_4444_D32(x, y, a, b, c, d) 181 182#define MAKENAME(suffix) S4444_opaque_D32 ## suffix 183#define DSTSIZE 32 184#define SRCTYPE SkPMColor16 185#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_4444_Config); \ 186 SkASSERT(state.fAlphaScale == 256) 187#define RETURNDST(src) SkPixel4444ToPixel32(src) 188#define SRC_TO_FILTER(src) src 189#include "SkBitmapProcState_sample.h" 190 191#undef FILTER_PROC 192#define FILTER_PROC(x, y, a, b, c, d, dst) \ 193 do { \ 194 uint32_t tmp = Filter_4444_D32(x, y, a, b, c, d); \ 195 *(dst) = SkAlphaMulQ(tmp, alphaScale); \ 196 } while (0) 197 198#define MAKENAME(suffix) S4444_alpha_D32 ## suffix 199#define DSTSIZE 32 200#define SRCTYPE SkPMColor16 201#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_4444_Config); \ 202 SkASSERT(state.fAlphaScale < 256) 203#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale 204#define RETURNDST(src) SkAlphaMulQ(SkPixel4444ToPixel32(src), alphaScale) 205#define SRC_TO_FILTER(src) src 206#include "SkBitmapProcState_sample.h" 207 208// SRC == A8 209 210#undef FILTER_PROC 211#define FILTER_PROC(x, y, a, b, c, d, dst) \ 212 do { \ 213 unsigned tmp = Filter_8(x, y, a, b, c, d); \ 214 *(dst) = SkAlphaMulQ(pmColor, SkAlpha255To256(tmp)); \ 215 } while (0) 216 217#define MAKENAME(suffix) SA8_alpha_D32 ## suffix 218#define DSTSIZE 32 219#define SRCTYPE uint8_t 220#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kA8_Config); \ 221 SkASSERT(state.fAlphaScale == 256) 222#define PREAMBLE(state) const SkPMColor pmColor = state.fPaintPMColor; 223#define RETURNDST(src) SkAlphaMulQ(pmColor, SkAlpha255To256(src)) 224#define SRC_TO_FILTER(src) src 225#include "SkBitmapProcState_sample.h" 226 227/***************************************************************************** 228 * 229 * D16 functions 230 * 231 */ 232 233// SRC == 8888 234 235#undef FILTER_PROC 236#define FILTER_PROC(x, y, a, b, c, d, dst) \ 237 do { \ 238 SkPMColor dstColor; \ 239 Filter_32_opaque(x, y, a, b, c, d, &dstColor); \ 240 (*dst) = SkPixel32ToPixel16(dstColor); \ 241 } while (0) 242 243#define MAKENAME(suffix) S32_D16 ## suffix 244#define DSTSIZE 16 245#define SRCTYPE SkPMColor 246#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_8888_Config); \ 247 SkASSERT(state.fBitmap->isOpaque()) 248#define RETURNDST(src) SkPixel32ToPixel16(src) 249#define SRC_TO_FILTER(src) src 250#include "SkBitmapProcState_sample.h" 251 252// SRC == 565 253 254#undef FILTER_PROC 255#define FILTER_PROC(x, y, a, b, c, d, dst) \ 256 do { \ 257 uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d); \ 258 *(dst) = SkCompact_rgb_16((tmp) >> 5); \ 259 } while (0) 260 261#define MAKENAME(suffix) S16_D16 ## suffix 262#define DSTSIZE 16 263#define SRCTYPE uint16_t 264#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config) 265#define RETURNDST(src) src 266#define SRC_TO_FILTER(src) src 267#include "SkBitmapProcState_sample.h" 268 269// SRC == Index8 270 271#undef FILTER_PROC 272#define FILTER_PROC(x, y, a, b, c, d, dst) \ 273 do { \ 274 uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d); \ 275 *(dst) = SkCompact_rgb_16((tmp) >> 5); \ 276 } while (0) 277 278#define MAKENAME(suffix) SI8_D16 ## suffix 279#define DSTSIZE 16 280#define SRCTYPE uint8_t 281#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kIndex8_Config); \ 282 SkASSERT(state.fBitmap->isOpaque()) 283#define PREAMBLE(state) const uint16_t* SK_RESTRICT table = state.fBitmap->getColorTable()->lock16BitCache() 284#define RETURNDST(src) table[src] 285#define SRC_TO_FILTER(src) table[src] 286#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlock16BitCache() 287#include "SkBitmapProcState_sample.h" 288 289/////////////////////////////////////////////////////////////////////////////// 290 291#undef FILTER_PROC 292#define FILTER_PROC(x, y, a, b, c, d, dst) \ 293 do { \ 294 uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d); \ 295 *(dst) = SkCompact_rgb_16((tmp) >> 5); \ 296 } while (0) 297 298 299// clamp 300 301#define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max) 302#define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max) 303#define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) 304#define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) 305 306#define MAKENAME(suffix) Clamp_S16_D16 ## suffix 307#define SRCTYPE uint16_t 308#define DSTTYPE uint16_t 309#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config) 310#define SRC_TO_FILTER(src) src 311#include "SkBitmapProcState_shaderproc.h" 312 313 314#define TILEX_PROCF(fx, max) (((fx) & 0xFFFF) * ((max) + 1) >> 16) 315#define TILEY_PROCF(fy, max) (((fy) & 0xFFFF) * ((max) + 1) >> 16) 316#define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 317#define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 318 319#define MAKENAME(suffix) Repeat_S16_D16 ## suffix 320#define SRCTYPE uint16_t 321#define DSTTYPE uint16_t 322#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config) 323#define SRC_TO_FILTER(src) src 324#include "SkBitmapProcState_shaderproc.h" 325 326 327#define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max) 328#define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max) 329#define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) 330#define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) 331 332#undef FILTER_PROC 333#define FILTER_PROC(x, y, a, b, c, d, dst) Filter_32_opaque(x, y, a, b, c, d, dst) 334#define MAKENAME(suffix) Clamp_SI8_opaque_D32 ## suffix 335#define SRCTYPE uint8_t 336#define DSTTYPE uint32_t 337#define CHECKSTATE(state) SkASSERT(state.fBitmap->config() == SkBitmap::kIndex8_Config) 338#define PREAMBLE(state) const SkPMColor* SK_RESTRICT table = state.fBitmap->getColorTable()->lockColors() 339#define SRC_TO_FILTER(src) table[src] 340#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlockColors(false) 341#include "SkBitmapProcState_shaderproc.h" 342 343/////////////////////////////////////////////////////////////////////////////// 344 345static bool valid_for_filtering(unsigned dimension) { 346 // for filtering, width and height must fit in 14bits, since we use steal 347 // 2 bits from each to store our 4bit subpixel data 348 return (dimension & ~0x3FFF) == 0; 349} 350 351bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { 352 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) { 353 return false; 354 } 355 356 const SkMatrix* m; 357 bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0; 358 bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX && 359 SkShader::kClamp_TileMode == fTileModeY; 360 361 if (clamp_clamp || trivial_matrix) { 362 m = &inv; 363 } else { 364 fUnitInvMatrix = inv; 365 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); 366 m = &fUnitInvMatrix; 367 } 368 369 fBitmap = &fOrigBitmap; 370 if (fOrigBitmap.hasMipMap()) { 371 int shift = fOrigBitmap.extractMipLevel(&fMipBitmap, 372 SkScalarToFixed(m->getScaleX()), 373 SkScalarToFixed(m->getSkewY())); 374 375 if (shift > 0) { 376 if (m != &fUnitInvMatrix) { 377 fUnitInvMatrix = *m; 378 m = &fUnitInvMatrix; 379 } 380 381 SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift); 382 fUnitInvMatrix.postScale(scale, scale); 383 384 // now point here instead of fOrigBitmap 385 fBitmap = &fMipBitmap; 386 } 387 } 388 389 fInvMatrix = m; 390 fInvProc = m->getMapXYProc(); 391 fInvType = m->getType(); 392 fInvSx = SkScalarToFixed(m->getScaleX()); 393 fInvKy = SkScalarToFixed(m->getSkewY()); 394 395 fAlphaScale = SkAlpha255To256(paint.getAlpha()); 396 397 // pick-up filtering from the paint, but only if the matrix is 398 // more complex than identity/translate (i.e. no need to pay the cost 399 // of filtering if we're not scaled etc.). 400 // note: we explicitly check inv, since m might be scaled due to unitinv 401 // trickery, but we don't want to see that for this test 402 fDoFilter = paint.isFilterBitmap() && 403 (inv.getType() > SkMatrix::kTranslate_Mask && 404 valid_for_filtering(fBitmap->width() | fBitmap->height())); 405 406 fShaderProc32 = NULL; 407 fShaderProc16 = NULL; 408 fSampleProc32 = NULL; 409 fSampleProc16 = NULL; 410 411 fMatrixProc = this->chooseMatrixProc(trivial_matrix); 412 if (NULL == fMatrixProc) { 413 return false; 414 } 415 416 /////////////////////////////////////////////////////////////////////// 417 418 int index = 0; 419 if (fAlphaScale < 256) { // note: this distinction is not used for D16 420 index |= 1; 421 } 422 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { 423 index |= 2; 424 } 425 if (fDoFilter) { 426 index |= 4; 427 } 428 // bits 3,4,5 encoding the source bitmap format 429 switch (fBitmap->config()) { 430 case SkBitmap::kARGB_8888_Config: 431 index |= 0; 432 break; 433 case SkBitmap::kRGB_565_Config: 434 index |= 8; 435 break; 436 case SkBitmap::kIndex8_Config: 437 index |= 16; 438 break; 439 case SkBitmap::kARGB_4444_Config: 440 index |= 24; 441 break; 442 case SkBitmap::kA8_Config: 443 index |= 32; 444 fPaintPMColor = SkPreMultiplyColor(paint.getColor()); 445 break; 446 default: 447 return false; 448 } 449 450 static const SampleProc32 gSample32[] = { 451 S32_opaque_D32_nofilter_DXDY, 452 S32_alpha_D32_nofilter_DXDY, 453 S32_opaque_D32_nofilter_DX, 454 S32_alpha_D32_nofilter_DX, 455 S32_opaque_D32_filter_DXDY, 456 S32_alpha_D32_filter_DXDY, 457 S32_opaque_D32_filter_DX, 458 S32_alpha_D32_filter_DX, 459 460 S16_opaque_D32_nofilter_DXDY, 461 S16_alpha_D32_nofilter_DXDY, 462 S16_opaque_D32_nofilter_DX, 463 S16_alpha_D32_nofilter_DX, 464 S16_opaque_D32_filter_DXDY, 465 S16_alpha_D32_filter_DXDY, 466 S16_opaque_D32_filter_DX, 467 S16_alpha_D32_filter_DX, 468 469 SI8_opaque_D32_nofilter_DXDY, 470 SI8_alpha_D32_nofilter_DXDY, 471 SI8_opaque_D32_nofilter_DX, 472 SI8_alpha_D32_nofilter_DX, 473 SI8_opaque_D32_filter_DXDY, 474 SI8_alpha_D32_filter_DXDY, 475 SI8_opaque_D32_filter_DX, 476 SI8_alpha_D32_filter_DX, 477 478 S4444_opaque_D32_nofilter_DXDY, 479 S4444_alpha_D32_nofilter_DXDY, 480 S4444_opaque_D32_nofilter_DX, 481 S4444_alpha_D32_nofilter_DX, 482 S4444_opaque_D32_filter_DXDY, 483 S4444_alpha_D32_filter_DXDY, 484 S4444_opaque_D32_filter_DX, 485 S4444_alpha_D32_filter_DX, 486 487 // A8 treats alpha/opauqe the same (equally efficient) 488 SA8_alpha_D32_nofilter_DXDY, 489 SA8_alpha_D32_nofilter_DXDY, 490 SA8_alpha_D32_nofilter_DX, 491 SA8_alpha_D32_nofilter_DX, 492 SA8_alpha_D32_filter_DXDY, 493 SA8_alpha_D32_filter_DXDY, 494 SA8_alpha_D32_filter_DX, 495 SA8_alpha_D32_filter_DX 496 }; 497 498 static const SampleProc16 gSample16[] = { 499 S32_D16_nofilter_DXDY, 500 S32_D16_nofilter_DX, 501 S32_D16_filter_DXDY, 502 S32_D16_filter_DX, 503 504 S16_D16_nofilter_DXDY, 505 S16_D16_nofilter_DX, 506 S16_D16_filter_DXDY, 507 S16_D16_filter_DX, 508 509 SI8_D16_nofilter_DXDY, 510 SI8_D16_nofilter_DX, 511 SI8_D16_filter_DXDY, 512 SI8_D16_filter_DX, 513 514 // Don't support 4444 -> 565 515 NULL, NULL, NULL, NULL, 516 // Don't support A8 -> 565 517 NULL, NULL, NULL, NULL 518 }; 519 520 fSampleProc32 = gSample32[index]; 521 index >>= 1; // shift away any opaque/alpha distinction 522 fSampleProc16 = gSample16[index]; 523 524 // our special-case shaderprocs 525 if (S16_D16_filter_DX == fSampleProc16) { 526 if (clamp_clamp) { 527 fShaderProc16 = Clamp_S16_D16_filter_DX_shaderproc; 528 } else if (SkShader::kRepeat_TileMode == fTileModeX && 529 SkShader::kRepeat_TileMode == fTileModeY) { 530 fShaderProc16 = Repeat_S16_D16_filter_DX_shaderproc; 531 } 532 } else if (SI8_opaque_D32_filter_DX == fSampleProc32 && clamp_clamp) { 533 fShaderProc32 = Clamp_SI8_opaque_D32_filter_DX_shaderproc; 534 } 535 536 // see if our platform has any accelerated overrides 537 this->platformProcs(); 538 return true; 539} 540 541/////////////////////////////////////////////////////////////////////////////// 542/* 543 The storage requirements for the different matrix procs are as follows, 544 where each X or Y is 2 bytes, and N is the number of pixels/elements: 545 546 scale/translate nofilter Y(4bytes) + N * X 547 affine/perspective nofilter N * (X Y) 548 scale/translate filter Y Y + N * (X X) 549 affine/perspective filter N * (Y Y X X) 550 */ 551int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const { 552 int32_t size = static_cast<int32_t>(bufferSize); 553 554 size &= ~3; // only care about 4-byte aligned chunks 555 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) { 556 size -= 4; // the shared Y (or YY) coordinate 557 if (size < 0) { 558 size = 0; 559 } 560 size >>= 1; 561 } else { 562 size >>= 2; 563 } 564 565 if (fDoFilter) { 566 size >>= 1; 567 } 568 569 return size; 570} 571 572