| OLD | NEW |
| (Empty) |
| 1 /* libs/graphics/sgl/SkBlitter_RGB16.cpp | |
| 2 ** | |
| 3 ** Copyright 2006, The Android Open Source Project | |
| 4 ** | |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 ** you may not use this file except in compliance with the License. | |
| 7 ** You may obtain a copy of the License at | |
| 8 ** | |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 ** | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 */ | |
| 17 | |
| 18 #include "SkBlitRow.h" | |
| 19 #include "SkCoreBlitters.h" | |
| 20 #include "SkColorPriv.h" | |
| 21 #include "SkDither.h" | |
| 22 #include "SkShader.h" | |
| 23 #include "SkUtils.h" | |
| 24 #include "SkXfermode.h" | |
| 25 | |
| 26 void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, | |
| 27 int count) { | |
| 28 if (count > 0) { | |
| 29 // see if we need to write one short before we can cast to an 4byte ptr | |
| 30 // (we do this subtract rather than (unsigned)dst so we don't get warnin
gs | |
| 31 // on 64bit machines) | |
| 32 if (((char*)dst - (char*)0) & 2) { | |
| 33 *dst++ = value; | |
| 34 count -= 1; | |
| 35 SkTSwap(value, other); | |
| 36 } | |
| 37 | |
| 38 // fast way to set [value,other] pairs | |
| 39 #ifdef SK_CPU_BENDIAN | |
| 40 sk_memset32((uint32_t*)dst, (value << 16) | other, count >> 1); | |
| 41 #else | |
| 42 sk_memset32((uint32_t*)dst, (other << 16) | value, count >> 1); | |
| 43 #endif | |
| 44 | |
| 45 if (count & 1) { | |
| 46 dst[count - 1] = value; | |
| 47 } | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 /////////////////////////////////////////////////////////////////////////////// | |
| 52 | |
| 53 SkRGB16_Black_Blitter::SkRGB16_Black_Blitter(const SkBitmap& device, const SkPai
nt& paint) | |
| 54 : SkRGB16_Blitter(device, paint) { | |
| 55 SkASSERT(paint.getShader() == NULL); | |
| 56 SkASSERT(paint.getColorFilter() == NULL); | |
| 57 SkASSERT(paint.getXfermode() == NULL); | |
| 58 SkASSERT(paint.getColor() == SK_ColorBLACK); | |
| 59 } | |
| 60 | |
| 61 #if 1 | |
| 62 #define black_8_pixels(mask, dst) \ | |
| 63 do { \ | |
| 64 if (mask & 0x80) dst[0] = 0; \ | |
| 65 if (mask & 0x40) dst[1] = 0; \ | |
| 66 if (mask & 0x20) dst[2] = 0; \ | |
| 67 if (mask & 0x10) dst[3] = 0; \ | |
| 68 if (mask & 0x08) dst[4] = 0; \ | |
| 69 if (mask & 0x04) dst[5] = 0; \ | |
| 70 if (mask & 0x02) dst[6] = 0; \ | |
| 71 if (mask & 0x01) dst[7] = 0; \ | |
| 72 } while (0) | |
| 73 #else | |
| 74 static inline black_8_pixels(U8CPU mask, uint16_t dst[]) | |
| 75 { | |
| 76 if (mask & 0x80) dst[0] = 0; | |
| 77 if (mask & 0x40) dst[1] = 0; | |
| 78 if (mask & 0x20) dst[2] = 0; | |
| 79 if (mask & 0x10) dst[3] = 0; | |
| 80 if (mask & 0x08) dst[4] = 0; | |
| 81 if (mask & 0x04) dst[5] = 0; | |
| 82 if (mask & 0x02) dst[6] = 0; | |
| 83 if (mask & 0x01) dst[7] = 0; | |
| 84 } | |
| 85 #endif | |
| 86 | |
| 87 #define SK_BLITBWMASK_NAME SkRGB16_Black_BlitBW | |
| 88 #define SK_BLITBWMASK_ARGS | |
| 89 #define SK_BLITBWMASK_BLIT8(mask, dst) black_8_pixels(mask, dst) | |
| 90 #define SK_BLITBWMASK_GETADDR getAddr16 | |
| 91 #define SK_BLITBWMASK_DEVTYPE uint16_t | |
| 92 #include "SkBlitBWMaskTemplate.h" | |
| 93 | |
| 94 void SkRGB16_Black_Blitter::blitMask(const SkMask& SK_RESTRICT mask, | |
| 95 const SkIRect& SK_RESTRICT clip) | |
| 96 SK_RESTRICT { | |
| 97 if (mask.fFormat == SkMask::kBW_Format) { | |
| 98 SkRGB16_Black_BlitBW(fDevice, mask, clip); | |
| 99 } else { | |
| 100 uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); | |
| 101 const uint8_t* SK_RESTRICT alpha = mask.getAddr(clip.fLeft, clip.fTop); | |
| 102 unsigned width = clip.width(); | |
| 103 unsigned height = clip.height(); | |
| 104 unsigned deviceRB = fDevice.rowBytes() - (width << 1); | |
| 105 unsigned maskRB = mask.fRowBytes - width; | |
| 106 | |
| 107 SkASSERT((int)height > 0); | |
| 108 SkASSERT((int)width > 0); | |
| 109 SkASSERT((int)deviceRB >= 0); | |
| 110 SkASSERT((int)maskRB >= 0); | |
| 111 | |
| 112 do { | |
| 113 unsigned w = width; | |
| 114 do { | |
| 115 unsigned aa = *alpha++; | |
| 116 *device = SkAlphaMulRGB16(*device, SkAlpha255To256(255 - aa)); | |
| 117 device += 1; | |
| 118 } while (--w != 0); | |
| 119 device = (uint16_t*)((char*)device + deviceRB); | |
| 120 alpha += maskRB; | |
| 121 } while (--height != 0); | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 void SkRGB16_Black_Blitter::blitAntiH(int x, int y, | |
| 126 const SkAlpha* SK_RESTRICT antialias, | |
| 127 const int16_t* SK_RESTRICT runs) | |
| 128 SK_RESTRICT { | |
| 129 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | |
| 130 | |
| 131 for (;;) { | |
| 132 int count = runs[0]; | |
| 133 SkASSERT(count >= 0); | |
| 134 if (count <= 0) { | |
| 135 return; | |
| 136 } | |
| 137 runs += count; | |
| 138 | |
| 139 unsigned aa = antialias[0]; | |
| 140 antialias += count; | |
| 141 if (aa) { | |
| 142 if (aa == 255) { | |
| 143 memset(device, 0, count << 1); | |
| 144 } else { | |
| 145 aa = SkAlpha255To256(255 - aa); | |
| 146 do { | |
| 147 *device = SkAlphaMulRGB16(*device, aa); | |
| 148 device += 1; | |
| 149 } while (--count != 0); | |
| 150 continue; | |
| 151 } | |
| 152 } | |
| 153 device += count; | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 ////////////////////////////////////////////////////////////////////////////////
////////////////// | |
| 158 ////////////////////////////////////////////////////////////////////////////////
////////////////// | |
| 159 | |
| 160 SkRGB16_Blitter::SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint) | |
| 161 : INHERITED(device) { | |
| 162 SkColor color = paint.getColor(); | |
| 163 | |
| 164 fSrcColor32 = SkPreMultiplyColor(color); | |
| 165 fScale = SkAlpha255To256(SkColorGetA(color)); | |
| 166 | |
| 167 int r = SkColorGetR(color); | |
| 168 int g = SkColorGetG(color); | |
| 169 int b = SkColorGetB(color); | |
| 170 | |
| 171 fRawColor16 = fRawDither16 = SkPack888ToRGB16(r, g, b); | |
| 172 // if we're dithered, use fRawDither16 to hold that. | |
| 173 if ((fDoDither = paint.isDither()) != false) { | |
| 174 fRawDither16 = SkDitherPack888ToRGB16(r, g, b); | |
| 175 } | |
| 176 | |
| 177 fColor16 = SkPackRGB16( SkAlphaMul(r, fScale) >> (8 - SK_R16_BITS), | |
| 178 SkAlphaMul(g, fScale) >> (8 - SK_G16_BITS), | |
| 179 SkAlphaMul(b, fScale) >> (8 - SK_B16_BITS)); | |
| 180 } | |
| 181 | |
| 182 const SkBitmap* SkRGB16_Blitter::justAnOpaqueColor(uint32_t* value) { | |
| 183 if (!fDoDither && 256 == fScale) { | |
| 184 *value = fRawColor16; | |
| 185 return &fDevice; | |
| 186 } | |
| 187 return NULL; | |
| 188 } | |
| 189 | |
| 190 void SkRGB16_Blitter::blitH(int x, int y, int width) SK_RESTRICT { | |
| 191 SkASSERT(width > 0); | |
| 192 SkASSERT(x + width <= fDevice.width()); | |
| 193 | |
| 194 if (fScale == 0) { | |
| 195 return; | |
| 196 } | |
| 197 | |
| 198 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | |
| 199 uint16_t srcColor = fColor16; | |
| 200 | |
| 201 if (256 == fScale) { | |
| 202 SkASSERT(fRawColor16 == srcColor); | |
| 203 if (fDoDither) { | |
| 204 uint16_t ditherColor = fRawDither16; | |
| 205 if ((x ^ y) & 1) { | |
| 206 SkTSwap(ditherColor, srcColor); | |
| 207 } | |
| 208 sk_dither_memset16(device, srcColor, ditherColor, width); | |
| 209 } else { | |
| 210 sk_memset16(device, srcColor, width); | |
| 211 } | |
| 212 } else { | |
| 213 // TODO: respect fDoDither | |
| 214 SkPMColor src32 = fSrcColor32; | |
| 215 do { | |
| 216 *device = SkSrcOver32To16(src32, *device); | |
| 217 device += 1; | |
| 218 } while (--width != 0); | |
| 219 } | |
| 220 } | |
| 221 | |
| 222 // return 1 or 0 from a bool | |
| 223 static int Bool2Int(bool value) { | |
| 224 return !!value; | |
| 225 } | |
| 226 | |
| 227 void SkRGB16_Blitter::blitAntiH(int x, int y, | |
| 228 const SkAlpha* SK_RESTRICT antialias, | |
| 229 const int16_t* SK_RESTRICT runs) SK_RESTRICT { | |
| 230 if (fScale == 0) { | |
| 231 return; | |
| 232 } | |
| 233 | |
| 234 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | |
| 235 uint16_t srcColor = fRawColor16; | |
| 236 unsigned scale = fScale; | |
| 237 int ditherInt = Bool2Int(fDoDither); | |
| 238 | |
| 239 if (256 == scale) { | |
| 240 uint16_t ditherColor = fRawDither16; | |
| 241 // if we have no dithering, this will always fail | |
| 242 if ((x ^ y) & ditherInt) { | |
| 243 SkTSwap(ditherColor, srcColor); | |
| 244 } | |
| 245 for (;;) { | |
| 246 int count = runs[0]; | |
| 247 SkASSERT(count >= 0); | |
| 248 if (count <= 0) { | |
| 249 return; | |
| 250 } | |
| 251 runs += count; | |
| 252 | |
| 253 unsigned aa = antialias[0]; | |
| 254 antialias += count; | |
| 255 if (aa) { | |
| 256 if (aa == 255) { | |
| 257 if (ditherInt) { | |
| 258 sk_dither_memset16(device, srcColor, | |
| 259 ditherColor, count); | |
| 260 } else { | |
| 261 sk_memset16(device, srcColor, count); | |
| 262 } | |
| 263 } else { | |
| 264 // TODO: respect fDoDither | |
| 265 unsigned scale5 = SkAlpha255To256(aa) >> 3; | |
| 266 uint32_t src32 = SkExpand_rgb_16(srcColor) * scale5; | |
| 267 scale5 = 32 - scale5; // now we can use it on the device | |
| 268 int n = count; | |
| 269 do { | |
| 270 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; | |
| 271 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); | |
| 272 } while (--n != 0); | |
| 273 goto DONE; | |
| 274 } | |
| 275 } | |
| 276 device += count; | |
| 277 | |
| 278 DONE: | |
| 279 // if we have no dithering, this will always fail | |
| 280 if (count & ditherInt) { | |
| 281 SkTSwap(ditherColor, srcColor); | |
| 282 } | |
| 283 } | |
| 284 } else { | |
| 285 // TODO: respect fDoDither | |
| 286 for (;;) { | |
| 287 int count = runs[0]; | |
| 288 SkASSERT(count >= 0); | |
| 289 if (count <= 0) { | |
| 290 return; | |
| 291 } | |
| 292 runs += count; | |
| 293 | |
| 294 unsigned aa = antialias[0]; | |
| 295 antialias += count; | |
| 296 if (aa) { | |
| 297 unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3); | |
| 298 uint32_t src32 = SkExpand_rgb_16(srcColor) * scale5; | |
| 299 scale5 = 32 - scale5; | |
| 300 do { | |
| 301 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; | |
| 302 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); | |
| 303 } while (--count != 0); | |
| 304 continue; | |
| 305 } | |
| 306 device += count; | |
| 307 } | |
| 308 } | |
| 309 } | |
| 310 | |
| 311 ////////////////////////////////////////////////////////////////////////////////
////// | |
| 312 | |
| 313 #define solid_8_pixels(mask, dst, color) \ | |
| 314 do { \ | |
| 315 if (mask & 0x80) dst[0] = color; \ | |
| 316 if (mask & 0x40) dst[1] = color; \ | |
| 317 if (mask & 0x20) dst[2] = color; \ | |
| 318 if (mask & 0x10) dst[3] = color; \ | |
| 319 if (mask & 0x08) dst[4] = color; \ | |
| 320 if (mask & 0x04) dst[5] = color; \ | |
| 321 if (mask & 0x02) dst[6] = color; \ | |
| 322 if (mask & 0x01) dst[7] = color; \ | |
| 323 } while (0) | |
| 324 | |
| 325 #define SK_BLITBWMASK_NAME SkRGB16_BlitBW | |
| 326 #define SK_BLITBWMASK_ARGS , uint16_t color | |
| 327 #define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst, color) | |
| 328 #define SK_BLITBWMASK_GETADDR getAddr16 | |
| 329 #define SK_BLITBWMASK_DEVTYPE uint16_t | |
| 330 #include "SkBlitBWMaskTemplate.h" | |
| 331 | |
| 332 static inline void blend_8_pixels(U8CPU bw, uint16_t dst[], unsigned dst_scale, | |
| 333 U16CPU srcColor) { | |
| 334 if (bw & 0x80) dst[0] = srcColor + SkAlphaMulRGB16(dst[0], dst_scale); | |
| 335 if (bw & 0x40) dst[1] = srcColor + SkAlphaMulRGB16(dst[1], dst_scale); | |
| 336 if (bw & 0x20) dst[2] = srcColor + SkAlphaMulRGB16(dst[2], dst_scale); | |
| 337 if (bw & 0x10) dst[3] = srcColor + SkAlphaMulRGB16(dst[3], dst_scale); | |
| 338 if (bw & 0x08) dst[4] = srcColor + SkAlphaMulRGB16(dst[4], dst_scale); | |
| 339 if (bw & 0x04) dst[5] = srcColor + SkAlphaMulRGB16(dst[5], dst_scale); | |
| 340 if (bw & 0x02) dst[6] = srcColor + SkAlphaMulRGB16(dst[6], dst_scale); | |
| 341 if (bw & 0x01) dst[7] = srcColor + SkAlphaMulRGB16(dst[7], dst_scale); | |
| 342 } | |
| 343 | |
| 344 #define SK_BLITBWMASK_NAME SkRGB16_BlendBW | |
| 345 #define SK_BLITBWMASK_ARGS , unsigned dst_scale, U16CPU src_col
or | |
| 346 #define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, dst_scale,
src_color) | |
| 347 #define SK_BLITBWMASK_GETADDR getAddr16 | |
| 348 #define SK_BLITBWMASK_DEVTYPE uint16_t | |
| 349 #include "SkBlitBWMaskTemplate.h" | |
| 350 | |
| 351 static U16CPU blend_compact(uint32_t src32, uint32_t dst32, unsigned scale5) { | |
| 352 return SkCompact_rgb_16(dst32 + ((src32 - dst32) * scale5 >> 5)); | |
| 353 } | |
| 354 | |
| 355 void SkRGB16_Blitter::blitMask(const SkMask& SK_RESTRICT mask, | |
| 356 const SkIRect& SK_RESTRICT clip) SK_RESTRICT { | |
| 357 if (fScale == 0) { | |
| 358 return; | |
| 359 } | |
| 360 if (mask.fFormat == SkMask::kBW_Format) { | |
| 361 if (fScale == 256) { | |
| 362 SkRGB16_BlitBW(fDevice, mask, clip, fColor16); | |
| 363 } else { | |
| 364 SkRGB16_BlendBW(fDevice, mask, clip, 256 - fScale, fColor16); | |
| 365 } | |
| 366 return; | |
| 367 } | |
| 368 | |
| 369 uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); | |
| 370 const uint8_t* SK_RESTRICT alpha = mask.getAddr(clip.fLeft, clip.fTop); | |
| 371 int width = clip.width(); | |
| 372 int height = clip.height(); | |
| 373 unsigned deviceRB = fDevice.rowBytes() - (width << 1); | |
| 374 unsigned maskRB = mask.fRowBytes - width; | |
| 375 uint32_t color32 = SkExpand_rgb_16(fRawColor16); | |
| 376 | |
| 377 if (256 == fScale) { | |
| 378 do { | |
| 379 int w = width; | |
| 380 do { | |
| 381 *device = blend_compact(color32, SkExpand_rgb_16(*device), | |
| 382 SkAlpha255To256(*alpha++) >> 3); | |
| 383 device += 1; | |
| 384 } while (--w != 0); | |
| 385 device = (uint16_t*)((char*)device + deviceRB); | |
| 386 alpha += maskRB; | |
| 387 } while (--height != 0); | |
| 388 } else { // scale < 256 | |
| 389 unsigned scale256 = fScale; | |
| 390 do { | |
| 391 int w = width; | |
| 392 do { | |
| 393 unsigned aa = *alpha++; | |
| 394 unsigned scale = SkAlpha255To256(aa) * scale256 >> (8 + 3); | |
| 395 uint32_t src32 = color32 * scale; | |
| 396 uint32_t dst32 = SkExpand_rgb_16(*device) * (32 - scale); | |
| 397 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); | |
| 398 } while (--w != 0); | |
| 399 device = (uint16_t*)((char*)device + deviceRB); | |
| 400 alpha += maskRB; | |
| 401 } while (--height != 0); | |
| 402 } | |
| 403 } | |
| 404 | |
| 405 void SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { | |
| 406 if (fScale == 0) { | |
| 407 return; | |
| 408 } | |
| 409 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | |
| 410 uint16_t color16 = fRawColor16; | |
| 411 unsigned deviceRB = fDevice.rowBytes(); | |
| 412 | |
| 413 if (alpha + fScale == (255 + 256)) { | |
| 414 if (fDoDither) { | |
| 415 uint16_t ditherColor = fRawDither16; | |
| 416 if ((x ^ y) & 1) { | |
| 417 SkTSwap(ditherColor, color16); | |
| 418 } | |
| 419 do { | |
| 420 device[0] = color16; | |
| 421 device = (uint16_t*)((char*)device + deviceRB); | |
| 422 SkTSwap(ditherColor, color16); | |
| 423 } while (--height != 0); | |
| 424 } else { | |
| 425 do { | |
| 426 device[0] = color16; | |
| 427 device = (uint16_t*)((char*)device + deviceRB); | |
| 428 } while (--height != 0); | |
| 429 } | |
| 430 } else { | |
| 431 // TODO: respect fDoDither | |
| 432 unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3); | |
| 433 uint32_t src32 = SkExpand_rgb_16(color16) * scale5; | |
| 434 scale5 = 32 - scale5; | |
| 435 do { | |
| 436 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; | |
| 437 *device = SkCompact_rgb_16((src32 + dst32) >> 5); | |
| 438 device = (uint16_t*)((char*)device + deviceRB); | |
| 439 } while (--height != 0); | |
| 440 } | |
| 441 } | |
| 442 | |
| 443 void SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { | |
| 444 SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); | |
| 445 | |
| 446 if (fScale == 0) { | |
| 447 return; | |
| 448 } | |
| 449 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | |
| 450 unsigned deviceRB = fDevice.rowBytes(); | |
| 451 uint16_t color16 = fColor16; | |
| 452 | |
| 453 if (256 == fScale) { | |
| 454 if (fDoDither) { | |
| 455 uint16_t ditherColor = fRawDither16; | |
| 456 if ((x ^ y) & 1) { | |
| 457 SkTSwap(ditherColor, color16); | |
| 458 } | |
| 459 while (--height >= 0) { | |
| 460 sk_dither_memset16(device, color16, ditherColor, width); | |
| 461 SkTSwap(ditherColor, color16); | |
| 462 device = (uint16_t*)((char*)device + deviceRB); | |
| 463 } | |
| 464 } else { // no dither | |
| 465 while (--height >= 0) { | |
| 466 sk_memset16(device, color16, width); | |
| 467 device = (uint16_t*)((char*)device + deviceRB); | |
| 468 } | |
| 469 } | |
| 470 } else { | |
| 471 SkPMColor src32 = fSrcColor32; | |
| 472 while (--height >= 0) { | |
| 473 for (int i = width - 1; i >= 0; --i) { | |
| 474 device[i] = SkSrcOver32To16(src32, device[i]); | |
| 475 } | |
| 476 device = (uint16_t*)((char*)device + deviceRB); | |
| 477 } | |
| 478 } | |
| 479 } | |
| 480 | |
| 481 /////////////////////////////////////////////////////////////////////////////// | |
| 482 | |
| 483 SkRGB16_Shader16_Blitter::SkRGB16_Shader16_Blitter(const SkBitmap& device, | |
| 484 const SkPaint& paint) | |
| 485 : SkRGB16_Shader_Blitter(device, paint) { | |
| 486 SkASSERT(SkShader::CanCallShadeSpan16(fShader->getFlags())); | |
| 487 } | |
| 488 | |
| 489 void SkRGB16_Shader16_Blitter::blitH(int x, int y, int width) SK_RESTRICT { | |
| 490 SkASSERT(x + width <= fDevice.width()); | |
| 491 | |
| 492 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | |
| 493 SkShader* shader = fShader; | |
| 494 | |
| 495 int alpha = shader->getSpan16Alpha(); | |
| 496 if (0xFF == alpha) { | |
| 497 shader->shadeSpan16(x, y, device, width); | |
| 498 } else { | |
| 499 uint16_t* span16 = (uint16_t*)fBuffer; | |
| 500 shader->shadeSpan16(x, y, span16, width); | |
| 501 SkBlendRGB16(span16, device, SkAlpha255To256(alpha), width); | |
| 502 } | |
| 503 } | |
| 504 | |
| 505 void SkRGB16_Shader16_Blitter::blitAntiH(int x, int y, | |
| 506 const SkAlpha* SK_RESTRICT antialias, | |
| 507 const int16_t* SK_RESTRICT runs) | |
| 508 SK_RESTRICT { | |
| 509 SkShader* shader = fShader; | |
| 510 SkPMColor* SK_RESTRICT span = fBuffer; | |
| 511 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | |
| 512 | |
| 513 int alpha = shader->getSpan16Alpha(); | |
| 514 uint16_t* span16 = (uint16_t*)span; | |
| 515 | |
| 516 if (0xFF == alpha) { | |
| 517 for (;;) { | |
| 518 int count = *runs; | |
| 519 if (count <= 0) { | |
| 520 break; | |
| 521 } | |
| 522 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer | |
| 523 | |
| 524 int aa = *antialias; | |
| 525 if (aa == 255) { | |
| 526 // go direct to the device! | |
| 527 shader->shadeSpan16(x, y, device, count); | |
| 528 } else if (aa) { | |
| 529 shader->shadeSpan16(x, y, span16, count); | |
| 530 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); | |
| 531 } | |
| 532 device += count; | |
| 533 runs += count; | |
| 534 antialias += count; | |
| 535 x += count; | |
| 536 } | |
| 537 } else { // span alpha is < 255 | |
| 538 alpha = SkAlpha255To256(alpha); | |
| 539 for (;;) { | |
| 540 int count = *runs; | |
| 541 if (count <= 0) { | |
| 542 break; | |
| 543 } | |
| 544 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer | |
| 545 | |
| 546 int aa = SkAlphaMul(*antialias, alpha); | |
| 547 if (aa) { | |
| 548 shader->shadeSpan16(x, y, span16, count); | |
| 549 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); | |
| 550 } | |
| 551 | |
| 552 device += count; | |
| 553 runs += count; | |
| 554 antialias += count; | |
| 555 x += count; | |
| 556 } | |
| 557 } | |
| 558 } | |
| 559 | |
| 560 /////////////////////////////////////////////////////////////////////////////// | |
| 561 | |
| 562 SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkBitmap& device, | |
| 563 const SkPaint& paint) | |
| 564 : INHERITED(device, paint) { | |
| 565 SkASSERT(paint.getXfermode() == NULL); | |
| 566 | |
| 567 fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); | |
| 568 | |
| 569 // compute SkBlitRow::Procs | |
| 570 unsigned flags = 0; | |
| 571 | |
| 572 uint32_t shaderFlags = fShader->getFlags(); | |
| 573 // shaders take care of global alpha, so we never set it in SkBlitRow | |
| 574 if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { | |
| 575 flags |= SkBlitRow::kSrcPixelAlpha_Flag; | |
| 576 } | |
| 577 // don't dither if the shader is really 16bit | |
| 578 if (paint.isDither() && !(shaderFlags & SkShader::kIntrinsicly16_Flag)) { | |
| 579 flags |= SkBlitRow::kDither_Flag; | |
| 580 } | |
| 581 // used when we know our global alpha is 0xFF | |
| 582 fOpaqueProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config); | |
| 583 // used when we know our global alpha is < 0xFF | |
| 584 fAlphaProc = SkBlitRow::Factory(flags | SkBlitRow::kGlobalAlpha_Flag, | |
| 585 SkBitmap::kRGB_565_Config); | |
| 586 } | |
| 587 | |
| 588 SkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() { | |
| 589 sk_free(fBuffer); | |
| 590 } | |
| 591 | |
| 592 void SkRGB16_Shader_Blitter::blitH(int x, int y, int width) { | |
| 593 SkASSERT(x + width <= fDevice.width()); | |
| 594 | |
| 595 fShader->shadeSpan(x, y, fBuffer, width); | |
| 596 // shaders take care of global alpha, so we pass 0xFF (should be ignored) | |
| 597 fOpaqueProc(fDevice.getAddr16(x, y), fBuffer, width, 0xFF, x, y); | |
| 598 } | |
| 599 | |
| 600 static inline int count_nonzero_span(const int16_t runs[], const SkAlpha aa[]) { | |
| 601 int count = 0; | |
| 602 for (;;) { | |
| 603 int n = *runs; | |
| 604 if (n == 0 || *aa == 0) { | |
| 605 break; | |
| 606 } | |
| 607 runs += n; | |
| 608 aa += n; | |
| 609 count += n; | |
| 610 } | |
| 611 return count; | |
| 612 } | |
| 613 | |
| 614 void SkRGB16_Shader_Blitter::blitAntiH(int x, int y, | |
| 615 const SkAlpha* SK_RESTRICT antialias, | |
| 616 const int16_t* SK_RESTRICT runs) | |
| 617 SK_RESTRICT { | |
| 618 SkShader* shader = fShader; | |
| 619 SkPMColor* SK_RESTRICT span = fBuffer; | |
| 620 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | |
| 621 | |
| 622 for (;;) { | |
| 623 int count = *runs; | |
| 624 if (count <= 0) { | |
| 625 break; | |
| 626 } | |
| 627 int aa = *antialias; | |
| 628 if (0 == aa) { | |
| 629 device += count; | |
| 630 runs += count; | |
| 631 antialias += count; | |
| 632 x += count; | |
| 633 continue; | |
| 634 } | |
| 635 | |
| 636 int nonZeroCount = count + count_nonzero_span(runs + count, antialias +
count); | |
| 637 | |
| 638 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer | |
| 639 shader->shadeSpan(x, y, span, nonZeroCount); | |
| 640 | |
| 641 SkPMColor* localSpan = span; | |
| 642 for (;;) { | |
| 643 SkBlitRow::Proc proc = (aa == 0xFF) ? fOpaqueProc : fAlphaProc; | |
| 644 proc(device, localSpan, count, aa, x, y); | |
| 645 | |
| 646 x += count; | |
| 647 device += count; | |
| 648 runs += count; | |
| 649 antialias += count; | |
| 650 nonZeroCount -= count; | |
| 651 if (nonZeroCount == 0) { | |
| 652 break; | |
| 653 } | |
| 654 localSpan += count; | |
| 655 SkASSERT(nonZeroCount > 0); | |
| 656 count = *runs; | |
| 657 SkASSERT(count > 0); | |
| 658 aa = *antialias; | |
| 659 } | |
| 660 } | |
| 661 } | |
| 662 | |
| 663 /////////////////////////////////////////////////////////////////////// | |
| 664 | |
| 665 SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( | |
| 666 const SkBitmap& device, const SkPaint& paint) | |
| 667 : INHERITED(device, paint) { | |
| 668 fXfermode = paint.getXfermode(); | |
| 669 SkASSERT(fXfermode); | |
| 670 fXfermode->ref(); | |
| 671 | |
| 672 int width = device.width(); | |
| 673 fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * siz
eof(SkPMColor)); | |
| 674 fAAExpand = (uint8_t*)(fBuffer + width); | |
| 675 } | |
| 676 | |
| 677 SkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() { | |
| 678 fXfermode->unref(); | |
| 679 sk_free(fBuffer); | |
| 680 } | |
| 681 | |
| 682 void SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) { | |
| 683 SkASSERT(x + width <= fDevice.width()); | |
| 684 | |
| 685 uint16_t* device = fDevice.getAddr16(x, y); | |
| 686 SkPMColor* span = fBuffer; | |
| 687 | |
| 688 fShader->shadeSpan(x, y, span, width); | |
| 689 fXfermode->xfer16(device, span, width, NULL); | |
| 690 } | |
| 691 | |
| 692 void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, | |
| 693 const SkAlpha* SK_RESTRICT antialias, | |
| 694 const int16_t* SK_RESTRICT runs) SK_RESTRICT { | |
| 695 SkShader* shader = fShader; | |
| 696 SkXfermode* mode = fXfermode; | |
| 697 SkPMColor* SK_RESTRICT span = fBuffer; | |
| 698 uint8_t* SK_RESTRICT aaExpand = fAAExpand; | |
| 699 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); | |
| 700 | |
| 701 for (;;) { | |
| 702 int count = *runs; | |
| 703 if (count <= 0) { | |
| 704 break; | |
| 705 } | |
| 706 int aa = *antialias; | |
| 707 if (0 == aa) { | |
| 708 device += count; | |
| 709 runs += count; | |
| 710 antialias += count; | |
| 711 x += count; | |
| 712 continue; | |
| 713 } | |
| 714 | |
| 715 int nonZeroCount = count + count_nonzero_span(runs + count, | |
| 716 antialias + count); | |
| 717 | |
| 718 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer | |
| 719 shader->shadeSpan(x, y, span, nonZeroCount); | |
| 720 | |
| 721 x += nonZeroCount; | |
| 722 SkPMColor* localSpan = span; | |
| 723 for (;;) { | |
| 724 if (aa == 0xFF) { | |
| 725 mode->xfer16(device, localSpan, count, NULL); | |
| 726 } else { | |
| 727 SkASSERT(aa); | |
| 728 memset(aaExpand, aa, count); | |
| 729 mode->xfer16(device, localSpan, count, aaExpand); | |
| 730 } | |
| 731 device += count; | |
| 732 runs += count; | |
| 733 antialias += count; | |
| 734 nonZeroCount -= count; | |
| 735 if (nonZeroCount == 0) { | |
| 736 break; | |
| 737 } | |
| 738 localSpan += count; | |
| 739 SkASSERT(nonZeroCount > 0); | |
| 740 count = *runs; | |
| 741 SkASSERT(count > 0); | |
| 742 aa = *antialias; | |
| 743 } | |
| 744 } | |
| 745 } | |
| 746 | |
| 747 //////////////////////// | |
| 748 | |
| 749 #if 0 | |
| 750 static inline uint16_t aa_blendS32D16(SkPMColor src, U16CPU dst, int aa | |
| 751 #ifdef DITHER_SHADER | |
| 752 , int dither | |
| 753 #endif | |
| 754 ) | |
| 755 { | |
| 756 SkASSERT((unsigned)aa <= 255); | |
| 757 | |
| 758 int src_scale = SkAlpha255To256(aa); | |
| 759 int sa = SkGetPackedA32(src); | |
| 760 int dst_scale = SkAlpha255To256(255 - SkAlphaMul(sa, src_scale)); | |
| 761 | |
| 762 #ifdef DITHER_SHADER | |
| 763 int sr = SkGetPackedR32(src); | |
| 764 int sg = SkGetPackedG32(src); | |
| 765 int sb = SkGetPackedB32(src); | |
| 766 sr = SkDITHER_R32To16(sr, dither); | |
| 767 sg = SkDITHER_G32To16(sg, dither); | |
| 768 sb = SkDITHER_B32To16(sb, dither); | |
| 769 #else | |
| 770 int sr = SkPacked32ToR16(src); | |
| 771 int sg = SkPacked32ToG16(src); | |
| 772 int sb = SkPacked32ToB16(src); | |
| 773 #endif | |
| 774 | |
| 775 int dr = (sr * src_scale + SkGetPackedR16(dst) * dst_scale) >> 8; | |
| 776 int dg = (sg * src_scale + SkGetPackedG16(dst) * dst_scale) >> 8; | |
| 777 int db = (sb * src_scale + SkGetPackedB16(dst) * dst_scale) >> 8; | |
| 778 | |
| 779 return SkPackRGB16(dr, dg, db); | |
| 780 } | |
| 781 #endif | |
| 782 | |
| OLD | NEW |