gfx/skia/trunk/src/core/SkBlitMask_D32.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 #include "SkBlitMask.h"
michael@0 2 #include "SkColor.h"
michael@0 3 #include "SkColorPriv.h"
michael@0 4
michael@0 5 static void D32_A8_Color(void* SK_RESTRICT dst, size_t dstRB,
michael@0 6 const void* SK_RESTRICT maskPtr, size_t maskRB,
michael@0 7 SkColor color, int width, int height) {
michael@0 8 SkPMColor pmc = SkPreMultiplyColor(color);
michael@0 9 size_t dstOffset = dstRB - (width << 2);
michael@0 10 size_t maskOffset = maskRB - width;
michael@0 11 SkPMColor* SK_RESTRICT device = (SkPMColor *)dst;
michael@0 12 const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr;
michael@0 13
michael@0 14 do {
michael@0 15 int w = width;
michael@0 16 do {
michael@0 17 unsigned aa = *mask++;
michael@0 18 *device = SkBlendARGB32(pmc, *device, aa);
michael@0 19 device += 1;
michael@0 20 } while (--w != 0);
michael@0 21 device = (uint32_t*)((char*)device + dstOffset);
michael@0 22 mask += maskOffset;
michael@0 23 } while (--height != 0);
michael@0 24 }
michael@0 25
michael@0 26 static void D32_A8_Opaque(void* SK_RESTRICT dst, size_t dstRB,
michael@0 27 const void* SK_RESTRICT maskPtr, size_t maskRB,
michael@0 28 SkColor color, int width, int height) {
michael@0 29 SkPMColor pmc = SkPreMultiplyColor(color);
michael@0 30 SkPMColor* SK_RESTRICT device = (SkPMColor*)dst;
michael@0 31 const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr;
michael@0 32
michael@0 33 maskRB -= width;
michael@0 34 dstRB -= (width << 2);
michael@0 35 do {
michael@0 36 int w = width;
michael@0 37 do {
michael@0 38 unsigned aa = *mask++;
michael@0 39 *device = SkAlphaMulQ(pmc, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
michael@0 40 device += 1;
michael@0 41 } while (--w != 0);
michael@0 42 device = (uint32_t*)((char*)device + dstRB);
michael@0 43 mask += maskRB;
michael@0 44 } while (--height != 0);
michael@0 45 }
michael@0 46
michael@0 47 static void D32_A8_Black(void* SK_RESTRICT dst, size_t dstRB,
michael@0 48 const void* SK_RESTRICT maskPtr, size_t maskRB,
michael@0 49 SkColor, int width, int height) {
michael@0 50 SkPMColor* SK_RESTRICT device = (SkPMColor*)dst;
michael@0 51 const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr;
michael@0 52
michael@0 53 maskRB -= width;
michael@0 54 dstRB -= (width << 2);
michael@0 55 do {
michael@0 56 int w = width;
michael@0 57 do {
michael@0 58 unsigned aa = *mask++;
michael@0 59 *device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
michael@0 60 device += 1;
michael@0 61 } while (--w != 0);
michael@0 62 device = (uint32_t*)((char*)device + dstRB);
michael@0 63 mask += maskRB;
michael@0 64 } while (--height != 0);
michael@0 65 }
michael@0 66
michael@0 67 SkBlitMask::BlitLCD16RowProc SkBlitMask::BlitLCD16RowFactory(bool isOpaque) {
michael@0 68 BlitLCD16RowProc proc = PlatformBlitRowProcs16(isOpaque);
michael@0 69 if (proc) {
michael@0 70 return proc;
michael@0 71 }
michael@0 72
michael@0 73 if (isOpaque) {
michael@0 74 return SkBlitLCD16OpaqueRow;
michael@0 75 } else {
michael@0 76 return SkBlitLCD16Row;
michael@0 77 }
michael@0 78 }
michael@0 79
michael@0 80 static void D32_LCD16_Proc(void* SK_RESTRICT dst, size_t dstRB,
michael@0 81 const void* SK_RESTRICT mask, size_t maskRB,
michael@0 82 SkColor color, int width, int height) {
michael@0 83
michael@0 84 SkPMColor* dstRow = (SkPMColor*)dst;
michael@0 85 const uint16_t* srcRow = (const uint16_t*)mask;
michael@0 86 SkPMColor opaqueDst;
michael@0 87
michael@0 88 SkBlitMask::BlitLCD16RowProc proc = NULL;
michael@0 89 bool isOpaque = (0xFF == SkColorGetA(color));
michael@0 90 proc = SkBlitMask::BlitLCD16RowFactory(isOpaque);
michael@0 91 SkASSERT(proc != NULL);
michael@0 92
michael@0 93 if (isOpaque) {
michael@0 94 opaqueDst = SkPreMultiplyColor(color);
michael@0 95 } else {
michael@0 96 opaqueDst = 0; // ignored
michael@0 97 }
michael@0 98
michael@0 99 do {
michael@0 100 proc(dstRow, srcRow, color, width, opaqueDst);
michael@0 101 dstRow = (SkPMColor*)((char*)dstRow + dstRB);
michael@0 102 srcRow = (const uint16_t*)((const char*)srcRow + maskRB);
michael@0 103 } while (--height != 0);
michael@0 104 }
michael@0 105
michael@0 106 ///////////////////////////////////////////////////////////////////////////////
michael@0 107
michael@0 108 static void blit_lcd32_opaque_row(SkPMColor* SK_RESTRICT dst,
michael@0 109 const SkPMColor* SK_RESTRICT src,
michael@0 110 SkColor color, int width) {
michael@0 111 int srcR = SkColorGetR(color);
michael@0 112 int srcG = SkColorGetG(color);
michael@0 113 int srcB = SkColorGetB(color);
michael@0 114
michael@0 115 for (int i = 0; i < width; i++) {
michael@0 116 SkPMColor mask = src[i];
michael@0 117 if (0 == mask) {
michael@0 118 continue;
michael@0 119 }
michael@0 120
michael@0 121 SkPMColor d = dst[i];
michael@0 122
michael@0 123 int maskR = SkGetPackedR32(mask);
michael@0 124 int maskG = SkGetPackedG32(mask);
michael@0 125 int maskB = SkGetPackedB32(mask);
michael@0 126
michael@0 127 // Now upscale them to 0..256, so we can use SkAlphaBlend
michael@0 128 maskR = SkAlpha255To256(maskR);
michael@0 129 maskG = SkAlpha255To256(maskG);
michael@0 130 maskB = SkAlpha255To256(maskB);
michael@0 131
michael@0 132 int dstR = SkGetPackedR32(d);
michael@0 133 int dstG = SkGetPackedG32(d);
michael@0 134 int dstB = SkGetPackedB32(d);
michael@0 135
michael@0 136 // LCD blitting is only supported if the dst is known/required
michael@0 137 // to be opaque
michael@0 138 dst[i] = SkPackARGB32(0xFF,
michael@0 139 SkAlphaBlend(srcR, dstR, maskR),
michael@0 140 SkAlphaBlend(srcG, dstG, maskG),
michael@0 141 SkAlphaBlend(srcB, dstB, maskB));
michael@0 142 }
michael@0 143 }
michael@0 144
michael@0 145 static void blit_lcd32_row(SkPMColor* SK_RESTRICT dst,
michael@0 146 const SkPMColor* SK_RESTRICT src,
michael@0 147 SkColor color, int width) {
michael@0 148 int srcA = SkColorGetA(color);
michael@0 149 int srcR = SkColorGetR(color);
michael@0 150 int srcG = SkColorGetG(color);
michael@0 151 int srcB = SkColorGetB(color);
michael@0 152
michael@0 153 srcA = SkAlpha255To256(srcA);
michael@0 154
michael@0 155 for (int i = 0; i < width; i++) {
michael@0 156 SkPMColor mask = src[i];
michael@0 157 if (0 == mask) {
michael@0 158 continue;
michael@0 159 }
michael@0 160
michael@0 161 SkPMColor d = dst[i];
michael@0 162
michael@0 163 int maskR = SkGetPackedR32(mask);
michael@0 164 int maskG = SkGetPackedG32(mask);
michael@0 165 int maskB = SkGetPackedB32(mask);
michael@0 166
michael@0 167 // Now upscale them to 0..256, so we can use SkAlphaBlend
michael@0 168 maskR = SkAlpha255To256(maskR);
michael@0 169 maskG = SkAlpha255To256(maskG);
michael@0 170 maskB = SkAlpha255To256(maskB);
michael@0 171
michael@0 172 maskR = maskR * srcA >> 8;
michael@0 173 maskG = maskG * srcA >> 8;
michael@0 174 maskB = maskB * srcA >> 8;
michael@0 175
michael@0 176 int dstR = SkGetPackedR32(d);
michael@0 177 int dstG = SkGetPackedG32(d);
michael@0 178 int dstB = SkGetPackedB32(d);
michael@0 179
michael@0 180 // LCD blitting is only supported if the dst is known/required
michael@0 181 // to be opaque
michael@0 182 dst[i] = SkPackARGB32(0xFF,
michael@0 183 SkAlphaBlend(srcR, dstR, maskR),
michael@0 184 SkAlphaBlend(srcG, dstG, maskG),
michael@0 185 SkAlphaBlend(srcB, dstB, maskB));
michael@0 186 }
michael@0 187 }
michael@0 188
michael@0 189 static void D32_LCD32_Blend(void* SK_RESTRICT dst, size_t dstRB,
michael@0 190 const void* SK_RESTRICT mask, size_t maskRB,
michael@0 191 SkColor color, int width, int height) {
michael@0 192 SkASSERT(height > 0);
michael@0 193 SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst;
michael@0 194 const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask;
michael@0 195
michael@0 196 do {
michael@0 197 blit_lcd32_row(dstRow, srcRow, color, width);
michael@0 198 dstRow = (SkPMColor*)((char*)dstRow + dstRB);
michael@0 199 srcRow = (const SkPMColor*)((const char*)srcRow + maskRB);
michael@0 200 } while (--height != 0);
michael@0 201 }
michael@0 202
michael@0 203 static void D32_LCD32_Opaque(void* SK_RESTRICT dst, size_t dstRB,
michael@0 204 const void* SK_RESTRICT mask, size_t maskRB,
michael@0 205 SkColor color, int width, int height) {
michael@0 206 SkASSERT(height > 0);
michael@0 207 SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst;
michael@0 208 const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask;
michael@0 209
michael@0 210 do {
michael@0 211 blit_lcd32_opaque_row(dstRow, srcRow, color, width);
michael@0 212 dstRow = (SkPMColor*)((char*)dstRow + dstRB);
michael@0 213 srcRow = (const SkPMColor*)((const char*)srcRow + maskRB);
michael@0 214 } while (--height != 0);
michael@0 215 }
michael@0 216
michael@0 217 ///////////////////////////////////////////////////////////////////////////////
michael@0 218
michael@0 219 static SkBlitMask::ColorProc D32_A8_Factory(SkColor color) {
michael@0 220 if (SK_ColorBLACK == color) {
michael@0 221 return D32_A8_Black;
michael@0 222 } else if (0xFF == SkColorGetA(color)) {
michael@0 223 return D32_A8_Opaque;
michael@0 224 } else {
michael@0 225 return D32_A8_Color;
michael@0 226 }
michael@0 227 }
michael@0 228
michael@0 229 static SkBlitMask::ColorProc D32_LCD32_Factory(SkColor color) {
michael@0 230 return (0xFF == SkColorGetA(color)) ? D32_LCD32_Opaque : D32_LCD32_Blend;
michael@0 231 }
michael@0 232
michael@0 233 SkBlitMask::ColorProc SkBlitMask::ColorFactory(SkBitmap::Config config,
michael@0 234 SkMask::Format format,
michael@0 235 SkColor color) {
michael@0 236 ColorProc proc = PlatformColorProcs(config, format, color);
michael@0 237 if (proc) {
michael@0 238 return proc;
michael@0 239 }
michael@0 240
michael@0 241 switch (config) {
michael@0 242 case SkBitmap::kARGB_8888_Config:
michael@0 243 switch (format) {
michael@0 244 case SkMask::kA8_Format:
michael@0 245 return D32_A8_Factory(color);
michael@0 246 case SkMask::kLCD16_Format:
michael@0 247 return D32_LCD16_Proc;
michael@0 248 case SkMask::kLCD32_Format:
michael@0 249 return D32_LCD32_Factory(color);
michael@0 250 default:
michael@0 251 break;
michael@0 252 }
michael@0 253 break;
michael@0 254 default:
michael@0 255 break;
michael@0 256 }
michael@0 257 return NULL;
michael@0 258 }
michael@0 259
michael@0 260 bool SkBlitMask::BlitColor(const SkBitmap& device, const SkMask& mask,
michael@0 261 const SkIRect& clip, SkColor color) {
michael@0 262 ColorProc proc = ColorFactory(device.config(), mask.fFormat, color);
michael@0 263 if (proc) {
michael@0 264 int x = clip.fLeft;
michael@0 265 int y = clip.fTop;
michael@0 266 proc(device.getAddr32(x, y), device.rowBytes(), mask.getAddr(x, y),
michael@0 267 mask.fRowBytes, color, clip.width(), clip.height());
michael@0 268 return true;
michael@0 269 }
michael@0 270 return false;
michael@0 271 }
michael@0 272
michael@0 273 ///////////////////////////////////////////////////////////////////////////////
michael@0 274 ///////////////////////////////////////////////////////////////////////////////
michael@0 275
michael@0 276 static void BW_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
michael@0 277 const uint8_t* SK_RESTRICT mask,
michael@0 278 const SkPMColor* SK_RESTRICT src, int count) {
michael@0 279 int i, octuple = (count + 7) >> 3;
michael@0 280 for (i = 0; i < octuple; ++i) {
michael@0 281 int m = *mask++;
michael@0 282 if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
michael@0 283 if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); }
michael@0 284 if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); }
michael@0 285 if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); }
michael@0 286 if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); }
michael@0 287 if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); }
michael@0 288 if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); }
michael@0 289 if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); }
michael@0 290 src += 8;
michael@0 291 dst += 8;
michael@0 292 }
michael@0 293 count &= 7;
michael@0 294 if (count > 0) {
michael@0 295 int m = *mask;
michael@0 296 do {
michael@0 297 if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
michael@0 298 m <<= 1;
michael@0 299 src += 1;
michael@0 300 dst += 1;
michael@0 301 } while (--count > 0);
michael@0 302 }
michael@0 303 }
michael@0 304
michael@0 305 static void BW_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
michael@0 306 const uint8_t* SK_RESTRICT mask,
michael@0 307 const SkPMColor* SK_RESTRICT src, int count) {
michael@0 308 int i, octuple = (count + 7) >> 3;
michael@0 309 for (i = 0; i < octuple; ++i) {
michael@0 310 int m = *mask++;
michael@0 311 if (m & 0x80) { dst[0] = src[0]; }
michael@0 312 if (m & 0x40) { dst[1] = src[1]; }
michael@0 313 if (m & 0x20) { dst[2] = src[2]; }
michael@0 314 if (m & 0x10) { dst[3] = src[3]; }
michael@0 315 if (m & 0x08) { dst[4] = src[4]; }
michael@0 316 if (m & 0x04) { dst[5] = src[5]; }
michael@0 317 if (m & 0x02) { dst[6] = src[6]; }
michael@0 318 if (m & 0x01) { dst[7] = src[7]; }
michael@0 319 src += 8;
michael@0 320 dst += 8;
michael@0 321 }
michael@0 322 count &= 7;
michael@0 323 if (count > 0) {
michael@0 324 int m = *mask;
michael@0 325 do {
michael@0 326 if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
michael@0 327 m <<= 1;
michael@0 328 src += 1;
michael@0 329 dst += 1;
michael@0 330 } while (--count > 0);
michael@0 331 }
michael@0 332 }
michael@0 333
michael@0 334 static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
michael@0 335 const uint8_t* SK_RESTRICT mask,
michael@0 336 const SkPMColor* SK_RESTRICT src, int count) {
michael@0 337 for (int i = 0; i < count; ++i) {
michael@0 338 if (mask[i]) {
michael@0 339 dst[i] = SkBlendARGB32(src[i], dst[i], mask[i]);
michael@0 340 }
michael@0 341 }
michael@0 342 }
michael@0 343
michael@0 344 // expand the steps that SkAlphaMulQ performs, but this way we can
michael@0 345 // exand.. add.. combine
michael@0 346 // instead of
michael@0 347 // expand..combine add expand..combine
michael@0 348 //
michael@0 349 #define EXPAND0(v, m, s) ((v) & (m)) * (s)
michael@0 350 #define EXPAND1(v, m, s) (((v) >> 8) & (m)) * (s)
michael@0 351 #define COMBINE(e0, e1, m) ((((e0) >> 8) & (m)) | ((e1) & ~(m)))
michael@0 352
michael@0 353 static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
michael@0 354 const uint8_t* SK_RESTRICT mask,
michael@0 355 const SkPMColor* SK_RESTRICT src, int count) {
michael@0 356 #if 0 // suppress warning
michael@0 357 const uint32_t rbmask = gMask_00FF00FF;
michael@0 358 #endif
michael@0 359 for (int i = 0; i < count; ++i) {
michael@0 360 int m = mask[i];
michael@0 361 if (m) {
michael@0 362 m += (m >> 7);
michael@0 363 #if 1
michael@0 364 // this is slightly slower than the expand/combine version, but it
michael@0 365 // is much closer to the old results, so we use it for now to reduce
michael@0 366 // rebaselining.
michael@0 367 dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m);
michael@0 368 #else
michael@0 369 uint32_t v = src[i];
michael@0 370 uint32_t s0 = EXPAND0(v, rbmask, m);
michael@0 371 uint32_t s1 = EXPAND1(v, rbmask, m);
michael@0 372 v = dst[i];
michael@0 373 uint32_t d0 = EXPAND0(v, rbmask, m);
michael@0 374 uint32_t d1 = EXPAND1(v, rbmask, m);
michael@0 375 dst[i] = COMBINE(s0 + d0, s1 + d1, rbmask);
michael@0 376 #endif
michael@0 377 }
michael@0 378 }
michael@0 379 }
michael@0 380
michael@0 381 static int upscale31To255(int value) {
michael@0 382 value = (value << 3) | (value >> 2);
michael@0 383 return value;
michael@0 384 }
michael@0 385
michael@0 386 static int src_alpha_blend(int src, int dst, int srcA, int mask) {
michael@0 387
michael@0 388 return dst + SkAlphaMul(src - SkAlphaMul(srcA, dst), mask);
michael@0 389 }
michael@0 390
michael@0 391 static void LCD16_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
michael@0 392 const uint16_t* SK_RESTRICT mask,
michael@0 393 const SkPMColor* SK_RESTRICT src, int count) {
michael@0 394 for (int i = 0; i < count; ++i) {
michael@0 395 uint16_t m = mask[i];
michael@0 396 if (0 == m) {
michael@0 397 continue;
michael@0 398 }
michael@0 399
michael@0 400 SkPMColor s = src[i];
michael@0 401 SkPMColor d = dst[i];
michael@0 402
michael@0 403 int srcA = SkGetPackedA32(s);
michael@0 404 int srcR = SkGetPackedR32(s);
michael@0 405 int srcG = SkGetPackedG32(s);
michael@0 406 int srcB = SkGetPackedB32(s);
michael@0 407
michael@0 408 srcA += srcA >> 7;
michael@0 409
michael@0 410 /* We want all of these in 5bits, hence the shifts in case one of them
michael@0 411 * (green) is 6bits.
michael@0 412 */
michael@0 413 int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5);
michael@0 414 int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5);
michael@0 415 int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5);
michael@0 416
michael@0 417 maskR = upscale31To255(maskR);
michael@0 418 maskG = upscale31To255(maskG);
michael@0 419 maskB = upscale31To255(maskB);
michael@0 420
michael@0 421 int dstR = SkGetPackedR32(d);
michael@0 422 int dstG = SkGetPackedG32(d);
michael@0 423 int dstB = SkGetPackedB32(d);
michael@0 424
michael@0 425 // LCD blitting is only supported if the dst is known/required
michael@0 426 // to be opaque
michael@0 427 dst[i] = SkPackARGB32(0xFF,
michael@0 428 src_alpha_blend(srcR, dstR, srcA, maskR),
michael@0 429 src_alpha_blend(srcG, dstG, srcA, maskG),
michael@0 430 src_alpha_blend(srcB, dstB, srcA, maskB));
michael@0 431 }
michael@0 432 }
michael@0 433
michael@0 434 static void LCD16_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
michael@0 435 const uint16_t* SK_RESTRICT mask,
michael@0 436 const SkPMColor* SK_RESTRICT src, int count) {
michael@0 437 for (int i = 0; i < count; ++i) {
michael@0 438 uint16_t m = mask[i];
michael@0 439 if (0 == m) {
michael@0 440 continue;
michael@0 441 }
michael@0 442
michael@0 443 SkPMColor s = src[i];
michael@0 444 SkPMColor d = dst[i];
michael@0 445
michael@0 446 int srcR = SkGetPackedR32(s);
michael@0 447 int srcG = SkGetPackedG32(s);
michael@0 448 int srcB = SkGetPackedB32(s);
michael@0 449
michael@0 450 /* We want all of these in 5bits, hence the shifts in case one of them
michael@0 451 * (green) is 6bits.
michael@0 452 */
michael@0 453 int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5);
michael@0 454 int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5);
michael@0 455 int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5);
michael@0 456
michael@0 457 // Now upscale them to 0..32, so we can use blend32
michael@0 458 maskR = SkUpscale31To32(maskR);
michael@0 459 maskG = SkUpscale31To32(maskG);
michael@0 460 maskB = SkUpscale31To32(maskB);
michael@0 461
michael@0 462 int dstR = SkGetPackedR32(d);
michael@0 463 int dstG = SkGetPackedG32(d);
michael@0 464 int dstB = SkGetPackedB32(d);
michael@0 465
michael@0 466 // LCD blitting is only supported if the dst is known/required
michael@0 467 // to be opaque
michael@0 468 dst[i] = SkPackARGB32(0xFF,
michael@0 469 SkBlend32(srcR, dstR, maskR),
michael@0 470 SkBlend32(srcG, dstG, maskG),
michael@0 471 SkBlend32(srcB, dstB, maskB));
michael@0 472 }
michael@0 473 }
michael@0 474
michael@0 475 static void LCD32_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
michael@0 476 const SkPMColor* SK_RESTRICT mask,
michael@0 477 const SkPMColor* SK_RESTRICT src, int count) {
michael@0 478 for (int i = 0; i < count; ++i) {
michael@0 479 SkPMColor m = mask[i];
michael@0 480 if (0 == m) {
michael@0 481 continue;
michael@0 482 }
michael@0 483
michael@0 484 SkPMColor s = src[i];
michael@0 485 int srcA = SkGetPackedA32(s);
michael@0 486 int srcR = SkGetPackedR32(s);
michael@0 487 int srcG = SkGetPackedG32(s);
michael@0 488 int srcB = SkGetPackedB32(s);
michael@0 489
michael@0 490 srcA = SkAlpha255To256(srcA);
michael@0 491
michael@0 492 SkPMColor d = dst[i];
michael@0 493
michael@0 494 int maskR = SkGetPackedR32(m);
michael@0 495 int maskG = SkGetPackedG32(m);
michael@0 496 int maskB = SkGetPackedB32(m);
michael@0 497
michael@0 498 // Now upscale them to 0..256
michael@0 499 maskR = SkAlpha255To256(maskR);
michael@0 500 maskG = SkAlpha255To256(maskG);
michael@0 501 maskB = SkAlpha255To256(maskB);
michael@0 502
michael@0 503 int dstR = SkGetPackedR32(d);
michael@0 504 int dstG = SkGetPackedG32(d);
michael@0 505 int dstB = SkGetPackedB32(d);
michael@0 506
michael@0 507 // LCD blitting is only supported if the dst is known/required
michael@0 508 // to be opaque
michael@0 509 dst[i] = SkPackARGB32(0xFF,
michael@0 510 src_alpha_blend(srcR, dstR, srcA, maskR),
michael@0 511 src_alpha_blend(srcG, dstG, srcA, maskG),
michael@0 512 src_alpha_blend(srcB, dstB, srcA, maskB));
michael@0 513 }
michael@0 514 }
michael@0 515
michael@0 516 static void LCD32_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
michael@0 517 const SkPMColor* SK_RESTRICT mask,
michael@0 518 const SkPMColor* SK_RESTRICT src, int count) {
michael@0 519 for (int i = 0; i < count; ++i) {
michael@0 520 SkPMColor m = mask[i];
michael@0 521 if (0 == m) {
michael@0 522 continue;
michael@0 523 }
michael@0 524
michael@0 525 SkPMColor s = src[i];
michael@0 526 SkPMColor d = dst[i];
michael@0 527
michael@0 528 int maskR = SkGetPackedR32(m);
michael@0 529 int maskG = SkGetPackedG32(m);
michael@0 530 int maskB = SkGetPackedB32(m);
michael@0 531
michael@0 532 int srcR = SkGetPackedR32(s);
michael@0 533 int srcG = SkGetPackedG32(s);
michael@0 534 int srcB = SkGetPackedB32(s);
michael@0 535
michael@0 536 int dstR = SkGetPackedR32(d);
michael@0 537 int dstG = SkGetPackedG32(d);
michael@0 538 int dstB = SkGetPackedB32(d);
michael@0 539
michael@0 540 // Now upscale them to 0..256, so we can use SkAlphaBlend
michael@0 541 maskR = SkAlpha255To256(maskR);
michael@0 542 maskG = SkAlpha255To256(maskG);
michael@0 543 maskB = SkAlpha255To256(maskB);
michael@0 544
michael@0 545 // LCD blitting is only supported if the dst is known/required
michael@0 546 // to be opaque
michael@0 547 dst[i] = SkPackARGB32(0xFF,
michael@0 548 SkAlphaBlend(srcR, dstR, maskR),
michael@0 549 SkAlphaBlend(srcG, dstG, maskG),
michael@0 550 SkAlphaBlend(srcB, dstB, maskB));
michael@0 551 }
michael@0 552 }
michael@0 553
michael@0 554 SkBlitMask::RowProc SkBlitMask::RowFactory(SkBitmap::Config config,
michael@0 555 SkMask::Format format,
michael@0 556 RowFlags flags) {
michael@0 557 // make this opt-in until chrome can rebaseline
michael@0 558 RowProc proc = PlatformRowProcs(config, format, flags);
michael@0 559 if (proc) {
michael@0 560 return proc;
michael@0 561 }
michael@0 562
michael@0 563 static const RowProc gProcs[] = {
michael@0 564 // need X coordinate to handle BW
michael@0 565 false ? (RowProc)BW_RowProc_Blend : NULL, // suppress unused warning
michael@0 566 false ? (RowProc)BW_RowProc_Opaque : NULL, // suppress unused warning
michael@0 567 (RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque,
michael@0 568 (RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque,
michael@0 569 (RowProc)LCD32_RowProc_Blend, (RowProc)LCD32_RowProc_Opaque,
michael@0 570 };
michael@0 571
michael@0 572 int index;
michael@0 573 switch (config) {
michael@0 574 case SkBitmap::kARGB_8888_Config:
michael@0 575 switch (format) {
michael@0 576 case SkMask::kBW_Format: index = 0; break;
michael@0 577 case SkMask::kA8_Format: index = 2; break;
michael@0 578 case SkMask::kLCD16_Format: index = 4; break;
michael@0 579 case SkMask::kLCD32_Format: index = 6; break;
michael@0 580 default:
michael@0 581 return NULL;
michael@0 582 }
michael@0 583 if (flags & kSrcIsOpaque_RowFlag) {
michael@0 584 index |= 1;
michael@0 585 }
michael@0 586 SkASSERT((size_t)index < SK_ARRAY_COUNT(gProcs));
michael@0 587 return gProcs[index];
michael@0 588 default:
michael@0 589 break;
michael@0 590 }
michael@0 591 return NULL;
michael@0 592 }

mercurial