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

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2006 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #include "SkCoreBlitters.h"
michael@0 11 #include "SkColorPriv.h"
michael@0 12 #include "SkShader.h"
michael@0 13 #include "SkXfermode.h"
michael@0 14
michael@0 15 SkA8_Blitter::SkA8_Blitter(const SkBitmap& device, const SkPaint& paint)
michael@0 16 : INHERITED(device) {
michael@0 17 fSrcA = paint.getAlpha();
michael@0 18 }
michael@0 19
michael@0 20 const SkBitmap* SkA8_Blitter::justAnOpaqueColor(uint32_t* value) {
michael@0 21 if (255 == fSrcA) {
michael@0 22 *value = 255;
michael@0 23 return &fDevice;
michael@0 24 }
michael@0 25 return NULL;
michael@0 26 }
michael@0 27
michael@0 28 void SkA8_Blitter::blitH(int x, int y, int width) {
michael@0 29 SkASSERT(x >= 0 && y >= 0 &&
michael@0 30 (unsigned)(x + width) <= (unsigned)fDevice.width());
michael@0 31
michael@0 32 if (fSrcA == 0) {
michael@0 33 return;
michael@0 34 }
michael@0 35
michael@0 36 uint8_t* device = fDevice.getAddr8(x, y);
michael@0 37
michael@0 38 if (fSrcA == 255) {
michael@0 39 memset(device, 0xFF, width);
michael@0 40 } else {
michael@0 41 unsigned scale = 256 - SkAlpha255To256(fSrcA);
michael@0 42 unsigned srcA = fSrcA;
michael@0 43
michael@0 44 for (int i = 0; i < width; i++) {
michael@0 45 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
michael@0 46 }
michael@0 47 }
michael@0 48 }
michael@0 49
michael@0 50 void SkA8_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
michael@0 51 const int16_t runs[]) {
michael@0 52 if (fSrcA == 0) {
michael@0 53 return;
michael@0 54 }
michael@0 55
michael@0 56 uint8_t* device = fDevice.getAddr8(x, y);
michael@0 57 unsigned srcA = fSrcA;
michael@0 58
michael@0 59 for (;;) {
michael@0 60 int count = runs[0];
michael@0 61 SkASSERT(count >= 0);
michael@0 62 if (count == 0) {
michael@0 63 return;
michael@0 64 }
michael@0 65 unsigned aa = antialias[0];
michael@0 66
michael@0 67 if (aa == 255 && srcA == 255) {
michael@0 68 memset(device, 0xFF, count);
michael@0 69 } else {
michael@0 70 unsigned sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
michael@0 71 unsigned scale = 256 - sa;
michael@0 72
michael@0 73 for (int i = 0; i < count; i++) {
michael@0 74 device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
michael@0 75 }
michael@0 76 }
michael@0 77 runs += count;
michael@0 78 antialias += count;
michael@0 79 device += count;
michael@0 80 }
michael@0 81 }
michael@0 82
michael@0 83 /////////////////////////////////////////////////////////////////////////////////////
michael@0 84
michael@0 85 #define solid_8_pixels(mask, dst) \
michael@0 86 do { \
michael@0 87 if (mask & 0x80) dst[0] = 0xFF; \
michael@0 88 if (mask & 0x40) dst[1] = 0xFF; \
michael@0 89 if (mask & 0x20) dst[2] = 0xFF; \
michael@0 90 if (mask & 0x10) dst[3] = 0xFF; \
michael@0 91 if (mask & 0x08) dst[4] = 0xFF; \
michael@0 92 if (mask & 0x04) dst[5] = 0xFF; \
michael@0 93 if (mask & 0x02) dst[6] = 0xFF; \
michael@0 94 if (mask & 0x01) dst[7] = 0xFF; \
michael@0 95 } while (0)
michael@0 96
michael@0 97 #define SK_BLITBWMASK_NAME SkA8_BlitBW
michael@0 98 #define SK_BLITBWMASK_ARGS
michael@0 99 #define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst)
michael@0 100 #define SK_BLITBWMASK_GETADDR getAddr8
michael@0 101 #define SK_BLITBWMASK_DEVTYPE uint8_t
michael@0 102 #include "SkBlitBWMaskTemplate.h"
michael@0 103
michael@0 104 static inline void blend_8_pixels(U8CPU bw, uint8_t dst[], U8CPU sa,
michael@0 105 unsigned dst_scale) {
michael@0 106 if (bw & 0x80) dst[0] = SkToU8(sa + SkAlphaMul(dst[0], dst_scale));
michael@0 107 if (bw & 0x40) dst[1] = SkToU8(sa + SkAlphaMul(dst[1], dst_scale));
michael@0 108 if (bw & 0x20) dst[2] = SkToU8(sa + SkAlphaMul(dst[2], dst_scale));
michael@0 109 if (bw & 0x10) dst[3] = SkToU8(sa + SkAlphaMul(dst[3], dst_scale));
michael@0 110 if (bw & 0x08) dst[4] = SkToU8(sa + SkAlphaMul(dst[4], dst_scale));
michael@0 111 if (bw & 0x04) dst[5] = SkToU8(sa + SkAlphaMul(dst[5], dst_scale));
michael@0 112 if (bw & 0x02) dst[6] = SkToU8(sa + SkAlphaMul(dst[6], dst_scale));
michael@0 113 if (bw & 0x01) dst[7] = SkToU8(sa + SkAlphaMul(dst[7], dst_scale));
michael@0 114 }
michael@0 115
michael@0 116 #define SK_BLITBWMASK_NAME SkA8_BlendBW
michael@0 117 #define SK_BLITBWMASK_ARGS , U8CPU sa, unsigned dst_scale
michael@0 118 #define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, sa, dst_scale)
michael@0 119 #define SK_BLITBWMASK_GETADDR getAddr8
michael@0 120 #define SK_BLITBWMASK_DEVTYPE uint8_t
michael@0 121 #include "SkBlitBWMaskTemplate.h"
michael@0 122
michael@0 123 void SkA8_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
michael@0 124 if (fSrcA == 0) {
michael@0 125 return;
michael@0 126 }
michael@0 127
michael@0 128 if (mask.fFormat == SkMask::kBW_Format) {
michael@0 129 if (fSrcA == 0xFF) {
michael@0 130 SkA8_BlitBW(fDevice, mask, clip);
michael@0 131 } else {
michael@0 132 SkA8_BlendBW(fDevice, mask, clip, fSrcA,
michael@0 133 SkAlpha255To256(255 - fSrcA));
michael@0 134 }
michael@0 135 return;
michael@0 136 }
michael@0 137
michael@0 138 int x = clip.fLeft;
michael@0 139 int y = clip.fTop;
michael@0 140 int width = clip.width();
michael@0 141 int height = clip.height();
michael@0 142 uint8_t* device = fDevice.getAddr8(x, y);
michael@0 143 const uint8_t* alpha = mask.getAddr8(x, y);
michael@0 144 unsigned srcA = fSrcA;
michael@0 145
michael@0 146 while (--height >= 0) {
michael@0 147 for (int i = width - 1; i >= 0; --i) {
michael@0 148 unsigned sa;
michael@0 149 // scale our src by the alpha value
michael@0 150 {
michael@0 151 int aa = alpha[i];
michael@0 152 if (aa == 0) {
michael@0 153 continue;
michael@0 154 }
michael@0 155 if (aa == 255) {
michael@0 156 if (srcA == 255) {
michael@0 157 device[i] = 0xFF;
michael@0 158 continue;
michael@0 159 }
michael@0 160 sa = srcA;
michael@0 161 } else {
michael@0 162 sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
michael@0 163 }
michael@0 164 }
michael@0 165
michael@0 166 int scale = 256 - SkAlpha255To256(sa);
michael@0 167 device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
michael@0 168 }
michael@0 169 device += fDevice.rowBytes();
michael@0 170 alpha += mask.fRowBytes;
michael@0 171 }
michael@0 172 }
michael@0 173
michael@0 174 ///////////////////////////////////////////////////////////////////////////////
michael@0 175
michael@0 176 void SkA8_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
michael@0 177 if (fSrcA == 0) {
michael@0 178 return;
michael@0 179 }
michael@0 180
michael@0 181 unsigned sa = SkAlphaMul(fSrcA, SkAlpha255To256(alpha));
michael@0 182 uint8_t* device = fDevice.getAddr8(x, y);
michael@0 183 size_t rowBytes = fDevice.rowBytes();
michael@0 184
michael@0 185 if (sa == 0xFF) {
michael@0 186 for (int i = 0; i < height; i++) {
michael@0 187 *device = SkToU8(sa);
michael@0 188 device += rowBytes;
michael@0 189 }
michael@0 190 } else {
michael@0 191 unsigned scale = 256 - SkAlpha255To256(sa);
michael@0 192
michael@0 193 for (int i = 0; i < height; i++) {
michael@0 194 *device = SkToU8(sa + SkAlphaMul(*device, scale));
michael@0 195 device += rowBytes;
michael@0 196 }
michael@0 197 }
michael@0 198 }
michael@0 199
michael@0 200 void SkA8_Blitter::blitRect(int x, int y, int width, int height) {
michael@0 201 SkASSERT(x >= 0 && y >= 0 &&
michael@0 202 (unsigned)(x + width) <= (unsigned)fDevice.width() &&
michael@0 203 (unsigned)(y + height) <= (unsigned)fDevice.height());
michael@0 204
michael@0 205 if (fSrcA == 0) {
michael@0 206 return;
michael@0 207 }
michael@0 208
michael@0 209 uint8_t* device = fDevice.getAddr8(x, y);
michael@0 210 unsigned srcA = fSrcA;
michael@0 211
michael@0 212 if (srcA == 255) {
michael@0 213 while (--height >= 0) {
michael@0 214 memset(device, 0xFF, width);
michael@0 215 device += fDevice.rowBytes();
michael@0 216 }
michael@0 217 } else {
michael@0 218 unsigned scale = 256 - SkAlpha255To256(srcA);
michael@0 219
michael@0 220 while (--height >= 0) {
michael@0 221 for (int i = 0; i < width; i++) {
michael@0 222 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
michael@0 223 }
michael@0 224 device += fDevice.rowBytes();
michael@0 225 }
michael@0 226 }
michael@0 227 }
michael@0 228
michael@0 229 ///////////////////////////////////////////////////////////////////////
michael@0 230
michael@0 231 SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkBitmap& device, const SkPaint& paint)
michael@0 232 : INHERITED(device, paint) {
michael@0 233 if ((fXfermode = paint.getXfermode()) != NULL) {
michael@0 234 fXfermode->ref();
michael@0 235 SkASSERT(fShader);
michael@0 236 }
michael@0 237
michael@0 238 int width = device.width();
michael@0 239 fBuffer = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor) * (width + (SkAlign4(width) >> 2)));
michael@0 240 fAAExpand = (uint8_t*)(fBuffer + width);
michael@0 241 }
michael@0 242
michael@0 243 SkA8_Shader_Blitter::~SkA8_Shader_Blitter() {
michael@0 244 if (fXfermode) SkSafeUnref(fXfermode);
michael@0 245 sk_free(fBuffer);
michael@0 246 }
michael@0 247
michael@0 248 void SkA8_Shader_Blitter::blitH(int x, int y, int width) {
michael@0 249 SkASSERT(x >= 0 && y >= 0 &&
michael@0 250 (unsigned)(x + width) <= (unsigned)fDevice.width());
michael@0 251
michael@0 252 uint8_t* device = fDevice.getAddr8(x, y);
michael@0 253
michael@0 254 if ((fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) && !fXfermode) {
michael@0 255 memset(device, 0xFF, width);
michael@0 256 } else {
michael@0 257 SkPMColor* span = fBuffer;
michael@0 258
michael@0 259 fShader->shadeSpan(x, y, span, width);
michael@0 260 if (fXfermode) {
michael@0 261 fXfermode->xferA8(device, span, width, NULL);
michael@0 262 } else {
michael@0 263 for (int i = width - 1; i >= 0; --i) {
michael@0 264 unsigned srcA = SkGetPackedA32(span[i]);
michael@0 265 unsigned scale = 256 - SkAlpha255To256(srcA);
michael@0 266
michael@0 267 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
michael@0 268 }
michael@0 269 }
michael@0 270 }
michael@0 271 }
michael@0 272
michael@0 273 static inline uint8_t aa_blend8(SkPMColor src, U8CPU da, int aa) {
michael@0 274 SkASSERT((unsigned)aa <= 255);
michael@0 275
michael@0 276 int src_scale = SkAlpha255To256(aa);
michael@0 277 int sa = SkGetPackedA32(src);
michael@0 278 int dst_scale = 256 - SkAlphaMul(sa, src_scale);
michael@0 279
michael@0 280 return SkToU8((sa * src_scale + da * dst_scale) >> 8);
michael@0 281 }
michael@0 282
michael@0 283 void SkA8_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
michael@0 284 const int16_t runs[]) {
michael@0 285 SkShader* shader = fShader;
michael@0 286 SkXfermode* mode = fXfermode;
michael@0 287 uint8_t* aaExpand = fAAExpand;
michael@0 288 SkPMColor* span = fBuffer;
michael@0 289 uint8_t* device = fDevice.getAddr8(x, y);
michael@0 290 int opaque = fShader->getFlags() & SkShader::kOpaqueAlpha_Flag;
michael@0 291
michael@0 292 for (;;) {
michael@0 293 int count = *runs;
michael@0 294 if (count == 0) {
michael@0 295 break;
michael@0 296 }
michael@0 297 int aa = *antialias;
michael@0 298 if (aa) {
michael@0 299 if (opaque && aa == 255 && mode == NULL) {
michael@0 300 memset(device, 0xFF, count);
michael@0 301 } else {
michael@0 302 shader->shadeSpan(x, y, span, count);
michael@0 303 if (mode) {
michael@0 304 memset(aaExpand, aa, count);
michael@0 305 mode->xferA8(device, span, count, aaExpand);
michael@0 306 } else {
michael@0 307 for (int i = count - 1; i >= 0; --i) {
michael@0 308 device[i] = aa_blend8(span[i], device[i], aa);
michael@0 309 }
michael@0 310 }
michael@0 311 }
michael@0 312 }
michael@0 313 device += count;
michael@0 314 runs += count;
michael@0 315 antialias += count;
michael@0 316 x += count;
michael@0 317 }
michael@0 318 }
michael@0 319
michael@0 320 void SkA8_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
michael@0 321 if (mask.fFormat == SkMask::kBW_Format) {
michael@0 322 this->INHERITED::blitMask(mask, clip);
michael@0 323 return;
michael@0 324 }
michael@0 325
michael@0 326 int x = clip.fLeft;
michael@0 327 int y = clip.fTop;
michael@0 328 int width = clip.width();
michael@0 329 int height = clip.height();
michael@0 330 uint8_t* device = fDevice.getAddr8(x, y);
michael@0 331 const uint8_t* alpha = mask.getAddr8(x, y);
michael@0 332
michael@0 333 SkPMColor* span = fBuffer;
michael@0 334
michael@0 335 while (--height >= 0) {
michael@0 336 fShader->shadeSpan(x, y, span, width);
michael@0 337 if (fXfermode) {
michael@0 338 fXfermode->xferA8(device, span, width, alpha);
michael@0 339 } else {
michael@0 340 for (int i = width - 1; i >= 0; --i) {
michael@0 341 device[i] = aa_blend8(span[i], device[i], alpha[i]);
michael@0 342 }
michael@0 343 }
michael@0 344
michael@0 345 y += 1;
michael@0 346 device += fDevice.rowBytes();
michael@0 347 alpha += mask.fRowBytes;
michael@0 348 }
michael@0 349 }
michael@0 350
michael@0 351 ///////////////////////////////////////////////////////////////////////////////
michael@0 352
michael@0 353 SkA8_Coverage_Blitter::SkA8_Coverage_Blitter(const SkBitmap& device,
michael@0 354 const SkPaint& paint) : SkRasterBlitter(device) {
michael@0 355 SkASSERT(NULL == paint.getShader());
michael@0 356 SkASSERT(NULL == paint.getXfermode());
michael@0 357 SkASSERT(NULL == paint.getColorFilter());
michael@0 358 }
michael@0 359
michael@0 360 void SkA8_Coverage_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
michael@0 361 const int16_t runs[]) {
michael@0 362 uint8_t* device = fDevice.getAddr8(x, y);
michael@0 363 SkDEBUGCODE(int totalCount = 0;)
michael@0 364
michael@0 365 for (;;) {
michael@0 366 int count = runs[0];
michael@0 367 SkASSERT(count >= 0);
michael@0 368 if (count == 0) {
michael@0 369 return;
michael@0 370 }
michael@0 371 if (antialias[0]) {
michael@0 372 memset(device, antialias[0], count);
michael@0 373 }
michael@0 374 runs += count;
michael@0 375 antialias += count;
michael@0 376 device += count;
michael@0 377
michael@0 378 SkDEBUGCODE(totalCount += count;)
michael@0 379 }
michael@0 380 SkASSERT(fDevice.width() == totalCount);
michael@0 381 }
michael@0 382
michael@0 383 void SkA8_Coverage_Blitter::blitH(int x, int y, int width) {
michael@0 384 memset(fDevice.getAddr8(x, y), 0xFF, width);
michael@0 385 }
michael@0 386
michael@0 387 void SkA8_Coverage_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
michael@0 388 if (0 == alpha) {
michael@0 389 return;
michael@0 390 }
michael@0 391
michael@0 392 uint8_t* dst = fDevice.getAddr8(x, y);
michael@0 393 const size_t dstRB = fDevice.rowBytes();
michael@0 394 while (--height >= 0) {
michael@0 395 *dst = alpha;
michael@0 396 dst += dstRB;
michael@0 397 }
michael@0 398 }
michael@0 399
michael@0 400 void SkA8_Coverage_Blitter::blitRect(int x, int y, int width, int height) {
michael@0 401 uint8_t* dst = fDevice.getAddr8(x, y);
michael@0 402 const size_t dstRB = fDevice.rowBytes();
michael@0 403 while (--height >= 0) {
michael@0 404 memset(dst, 0xFF, width);
michael@0 405 dst += dstRB;
michael@0 406 }
michael@0 407 }
michael@0 408
michael@0 409 void SkA8_Coverage_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
michael@0 410 SkASSERT(SkMask::kA8_Format == mask.fFormat);
michael@0 411
michael@0 412 int x = clip.fLeft;
michael@0 413 int y = clip.fTop;
michael@0 414 int width = clip.width();
michael@0 415 int height = clip.height();
michael@0 416
michael@0 417 uint8_t* dst = fDevice.getAddr8(x, y);
michael@0 418 const uint8_t* src = mask.getAddr8(x, y);
michael@0 419 const size_t srcRB = mask.fRowBytes;
michael@0 420 const size_t dstRB = fDevice.rowBytes();
michael@0 421
michael@0 422 while (--height >= 0) {
michael@0 423 memcpy(dst, src, width);
michael@0 424 dst += dstRB;
michael@0 425 src += srcRB;
michael@0 426 }
michael@0 427 }
michael@0 428
michael@0 429 const SkBitmap* SkA8_Coverage_Blitter::justAnOpaqueColor(uint32_t*) {
michael@0 430 return NULL;
michael@0 431 }

mercurial