gfx/skia/trunk/src/core/SkBlitter_ARGB32.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 /*
michael@0 2 * Copyright 2006 The Android Open Source Project
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #include "SkCoreBlitters.h"
michael@0 9 #include "SkColorPriv.h"
michael@0 10 #include "SkShader.h"
michael@0 11 #include "SkUtils.h"
michael@0 12 #include "SkXfermode.h"
michael@0 13 #include "SkBlitMask.h"
michael@0 14
michael@0 15 ///////////////////////////////////////////////////////////////////////////////
michael@0 16
michael@0 17 static void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask,
michael@0 18 const SkIRect& clip, SkPMColor srcColor) {
michael@0 19 U8CPU alpha = SkGetPackedA32(srcColor);
michael@0 20 unsigned flags = SkBlitRow::kSrcPixelAlpha_Flag32;
michael@0 21 if (alpha != 255) {
michael@0 22 flags |= SkBlitRow::kGlobalAlpha_Flag32;
michael@0 23 }
michael@0 24 SkBlitRow::Proc32 proc = SkBlitRow::Factory32(flags);
michael@0 25
michael@0 26 int x = clip.fLeft;
michael@0 27 int y = clip.fTop;
michael@0 28 int width = clip.width();
michael@0 29 int height = clip.height();
michael@0 30
michael@0 31 SkPMColor* dstRow = device.getAddr32(x, y);
michael@0 32 const SkPMColor* srcRow = reinterpret_cast<const SkPMColor*>(mask.getAddr8(x, y));
michael@0 33
michael@0 34 do {
michael@0 35 proc(dstRow, srcRow, width, alpha);
michael@0 36 dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes());
michael@0 37 srcRow = (const SkPMColor*)((const char*)srcRow + mask.fRowBytes);
michael@0 38 } while (--height != 0);
michael@0 39 }
michael@0 40
michael@0 41 //////////////////////////////////////////////////////////////////////////////////////
michael@0 42
michael@0 43 SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
michael@0 44 : INHERITED(device) {
michael@0 45 SkColor color = paint.getColor();
michael@0 46 fColor = color;
michael@0 47
michael@0 48 fSrcA = SkColorGetA(color);
michael@0 49 unsigned scale = SkAlpha255To256(fSrcA);
michael@0 50 fSrcR = SkAlphaMul(SkColorGetR(color), scale);
michael@0 51 fSrcG = SkAlphaMul(SkColorGetG(color), scale);
michael@0 52 fSrcB = SkAlphaMul(SkColorGetB(color), scale);
michael@0 53
michael@0 54 fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB);
michael@0 55 fColor32Proc = SkBlitRow::ColorProcFactory();
michael@0 56 fColorRect32Proc = SkBlitRow::ColorRectProcFactory();
michael@0 57 }
michael@0 58
michael@0 59 const SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) {
michael@0 60 if (255 == fSrcA) {
michael@0 61 *value = fPMColor;
michael@0 62 return &fDevice;
michael@0 63 }
michael@0 64 return NULL;
michael@0 65 }
michael@0 66
michael@0 67 #if defined _WIN32 && _MSC_VER >= 1300 // disable warning : local variable used without having been initialized
michael@0 68 #pragma warning ( push )
michael@0 69 #pragma warning ( disable : 4701 )
michael@0 70 #endif
michael@0 71
michael@0 72 void SkARGB32_Blitter::blitH(int x, int y, int width) {
michael@0 73 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
michael@0 74
michael@0 75 uint32_t* device = fDevice.getAddr32(x, y);
michael@0 76 fColor32Proc(device, device, width, fPMColor);
michael@0 77 }
michael@0 78
michael@0 79 void SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
michael@0 80 const int16_t runs[]) {
michael@0 81 if (fSrcA == 0) {
michael@0 82 return;
michael@0 83 }
michael@0 84
michael@0 85 uint32_t color = fPMColor;
michael@0 86 uint32_t* device = fDevice.getAddr32(x, y);
michael@0 87 unsigned opaqueMask = fSrcA; // if fSrcA is 0xFF, then we will catch the fast opaque case
michael@0 88
michael@0 89 for (;;) {
michael@0 90 int count = runs[0];
michael@0 91 SkASSERT(count >= 0);
michael@0 92 if (count <= 0) {
michael@0 93 return;
michael@0 94 }
michael@0 95 unsigned aa = antialias[0];
michael@0 96 if (aa) {
michael@0 97 if ((opaqueMask & aa) == 255) {
michael@0 98 sk_memset32(device, color, count);
michael@0 99 } else {
michael@0 100 uint32_t sc = SkAlphaMulQ(color, SkAlpha255To256(aa));
michael@0 101 fColor32Proc(device, device, count, sc);
michael@0 102 }
michael@0 103 }
michael@0 104 runs += count;
michael@0 105 antialias += count;
michael@0 106 device += count;
michael@0 107 }
michael@0 108 }
michael@0 109
michael@0 110 //////////////////////////////////////////////////////////////////////////////////////
michael@0 111
michael@0 112 #define solid_8_pixels(mask, dst, color) \
michael@0 113 do { \
michael@0 114 if (mask & 0x80) dst[0] = color; \
michael@0 115 if (mask & 0x40) dst[1] = color; \
michael@0 116 if (mask & 0x20) dst[2] = color; \
michael@0 117 if (mask & 0x10) dst[3] = color; \
michael@0 118 if (mask & 0x08) dst[4] = color; \
michael@0 119 if (mask & 0x04) dst[5] = color; \
michael@0 120 if (mask & 0x02) dst[6] = color; \
michael@0 121 if (mask & 0x01) dst[7] = color; \
michael@0 122 } while (0)
michael@0 123
michael@0 124 #define SK_BLITBWMASK_NAME SkARGB32_BlitBW
michael@0 125 #define SK_BLITBWMASK_ARGS , SkPMColor color
michael@0 126 #define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst, color)
michael@0 127 #define SK_BLITBWMASK_GETADDR getAddr32
michael@0 128 #define SK_BLITBWMASK_DEVTYPE uint32_t
michael@0 129 #include "SkBlitBWMaskTemplate.h"
michael@0 130
michael@0 131 #define blend_8_pixels(mask, dst, sc, dst_scale) \
michael@0 132 do { \
michael@0 133 if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ(dst[0], dst_scale); } \
michael@0 134 if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ(dst[1], dst_scale); } \
michael@0 135 if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ(dst[2], dst_scale); } \
michael@0 136 if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ(dst[3], dst_scale); } \
michael@0 137 if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ(dst[4], dst_scale); } \
michael@0 138 if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ(dst[5], dst_scale); } \
michael@0 139 if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ(dst[6], dst_scale); } \
michael@0 140 if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ(dst[7], dst_scale); } \
michael@0 141 } while (0)
michael@0 142
michael@0 143 #define SK_BLITBWMASK_NAME SkARGB32_BlendBW
michael@0 144 #define SK_BLITBWMASK_ARGS , uint32_t sc, unsigned dst_scale
michael@0 145 #define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, sc, dst_scale)
michael@0 146 #define SK_BLITBWMASK_GETADDR getAddr32
michael@0 147 #define SK_BLITBWMASK_DEVTYPE uint32_t
michael@0 148 #include "SkBlitBWMaskTemplate.h"
michael@0 149
michael@0 150 void SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
michael@0 151 SkASSERT(mask.fBounds.contains(clip));
michael@0 152 SkASSERT(fSrcA != 0xFF);
michael@0 153
michael@0 154 if (fSrcA == 0) {
michael@0 155 return;
michael@0 156 }
michael@0 157
michael@0 158 if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
michael@0 159 return;
michael@0 160 }
michael@0 161
michael@0 162 if (mask.fFormat == SkMask::kBW_Format) {
michael@0 163 SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA));
michael@0 164 } else if (SkMask::kARGB32_Format == mask.fFormat) {
michael@0 165 SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
michael@0 166 }
michael@0 167 }
michael@0 168
michael@0 169 void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
michael@0 170 const SkIRect& clip) {
michael@0 171 SkASSERT(mask.fBounds.contains(clip));
michael@0 172
michael@0 173 if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
michael@0 174 return;
michael@0 175 }
michael@0 176
michael@0 177 if (mask.fFormat == SkMask::kBW_Format) {
michael@0 178 SkARGB32_BlitBW(fDevice, mask, clip, fPMColor);
michael@0 179 } else if (SkMask::kARGB32_Format == mask.fFormat) {
michael@0 180 SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
michael@0 181 }
michael@0 182 }
michael@0 183
michael@0 184 ///////////////////////////////////////////////////////////////////////////////
michael@0 185
michael@0 186 void SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
michael@0 187 if (alpha == 0 || fSrcA == 0) {
michael@0 188 return;
michael@0 189 }
michael@0 190
michael@0 191 uint32_t* device = fDevice.getAddr32(x, y);
michael@0 192 uint32_t color = fPMColor;
michael@0 193
michael@0 194 if (alpha != 255) {
michael@0 195 color = SkAlphaMulQ(color, SkAlpha255To256(alpha));
michael@0 196 }
michael@0 197
michael@0 198 unsigned dst_scale = 255 - SkGetPackedA32(color);
michael@0 199 size_t rowBytes = fDevice.rowBytes();
michael@0 200 while (--height >= 0) {
michael@0 201 device[0] = color + SkAlphaMulQ(device[0], dst_scale);
michael@0 202 device = (uint32_t*)((char*)device + rowBytes);
michael@0 203 }
michael@0 204 }
michael@0 205
michael@0 206 void SkARGB32_Blitter::blitRect(int x, int y, int width, int height) {
michael@0 207 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height());
michael@0 208
michael@0 209 if (fSrcA == 0) {
michael@0 210 return;
michael@0 211 }
michael@0 212
michael@0 213 uint32_t* device = fDevice.getAddr32(x, y);
michael@0 214 uint32_t color = fPMColor;
michael@0 215 size_t rowBytes = fDevice.rowBytes();
michael@0 216
michael@0 217 if (255 == SkGetPackedA32(color)) {
michael@0 218 fColorRect32Proc(device, width, height, rowBytes, color);
michael@0 219 } else {
michael@0 220 while (--height >= 0) {
michael@0 221 fColor32Proc(device, device, width, color);
michael@0 222 device = (uint32_t*)((char*)device + rowBytes);
michael@0 223 }
michael@0 224 }
michael@0 225 }
michael@0 226
michael@0 227 #if defined _WIN32 && _MSC_VER >= 1300
michael@0 228 #pragma warning ( pop )
michael@0 229 #endif
michael@0 230
michael@0 231 ///////////////////////////////////////////////////////////////////////
michael@0 232
michael@0 233 void SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
michael@0 234 const int16_t runs[]) {
michael@0 235 uint32_t* device = fDevice.getAddr32(x, y);
michael@0 236 SkPMColor black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT);
michael@0 237
michael@0 238 for (;;) {
michael@0 239 int count = runs[0];
michael@0 240 SkASSERT(count >= 0);
michael@0 241 if (count <= 0) {
michael@0 242 return;
michael@0 243 }
michael@0 244 unsigned aa = antialias[0];
michael@0 245 if (aa) {
michael@0 246 if (aa == 255) {
michael@0 247 sk_memset32(device, black, count);
michael@0 248 } else {
michael@0 249 SkPMColor src = aa << SK_A32_SHIFT;
michael@0 250 unsigned dst_scale = 256 - aa;
michael@0 251 int n = count;
michael@0 252 do {
michael@0 253 --n;
michael@0 254 device[n] = src + SkAlphaMulQ(device[n], dst_scale);
michael@0 255 } while (n > 0);
michael@0 256 }
michael@0 257 }
michael@0 258 runs += count;
michael@0 259 antialias += count;
michael@0 260 device += count;
michael@0 261 }
michael@0 262 }
michael@0 263
michael@0 264 ///////////////////////////////////////////////////////////////////////////////
michael@0 265
michael@0 266 // Special version of SkBlitRow::Factory32 that knows we're in kSrc_Mode,
michael@0 267 // instead of kSrcOver_Mode
michael@0 268 static void blend_srcmode(SkPMColor* SK_RESTRICT device,
michael@0 269 const SkPMColor* SK_RESTRICT span,
michael@0 270 int count, U8CPU aa) {
michael@0 271 int aa256 = SkAlpha255To256(aa);
michael@0 272 for (int i = 0; i < count; ++i) {
michael@0 273 device[i] = SkFourByteInterp256(span[i], device[i], aa256);
michael@0 274 }
michael@0 275 }
michael@0 276
michael@0 277 SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkBitmap& device,
michael@0 278 const SkPaint& paint) : INHERITED(device, paint) {
michael@0 279 fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
michael@0 280
michael@0 281 fXfermode = paint.getXfermode();
michael@0 282 SkSafeRef(fXfermode);
michael@0 283
michael@0 284 int flags = 0;
michael@0 285 if (!(fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
michael@0 286 flags |= SkBlitRow::kSrcPixelAlpha_Flag32;
michael@0 287 }
michael@0 288 // we call this on the output from the shader
michael@0 289 fProc32 = SkBlitRow::Factory32(flags);
michael@0 290 // we call this on the output from the shader + alpha from the aa buffer
michael@0 291 fProc32Blend = SkBlitRow::Factory32(flags | SkBlitRow::kGlobalAlpha_Flag32);
michael@0 292
michael@0 293 fShadeDirectlyIntoDevice = false;
michael@0 294 if (fXfermode == NULL) {
michael@0 295 if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) {
michael@0 296 fShadeDirectlyIntoDevice = true;
michael@0 297 }
michael@0 298 } else {
michael@0 299 SkXfermode::Mode mode;
michael@0 300 if (fXfermode->asMode(&mode)) {
michael@0 301 if (SkXfermode::kSrc_Mode == mode) {
michael@0 302 fShadeDirectlyIntoDevice = true;
michael@0 303 fProc32Blend = blend_srcmode;
michael@0 304 }
michael@0 305 }
michael@0 306 }
michael@0 307
michael@0 308 fConstInY = SkToBool(fShader->getFlags() & SkShader::kConstInY32_Flag);
michael@0 309 }
michael@0 310
michael@0 311 SkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() {
michael@0 312 SkSafeUnref(fXfermode);
michael@0 313 sk_free(fBuffer);
michael@0 314 }
michael@0 315
michael@0 316 void SkARGB32_Shader_Blitter::blitH(int x, int y, int width) {
michael@0 317 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
michael@0 318
michael@0 319 uint32_t* device = fDevice.getAddr32(x, y);
michael@0 320
michael@0 321 if (fShadeDirectlyIntoDevice) {
michael@0 322 fShader->shadeSpan(x, y, device, width);
michael@0 323 } else {
michael@0 324 SkPMColor* span = fBuffer;
michael@0 325 fShader->shadeSpan(x, y, span, width);
michael@0 326 if (fXfermode) {
michael@0 327 fXfermode->xfer32(device, span, width, NULL);
michael@0 328 } else {
michael@0 329 fProc32(device, span, width, 255);
michael@0 330 }
michael@0 331 }
michael@0 332 }
michael@0 333
michael@0 334 void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) {
michael@0 335 SkASSERT(x >= 0 && y >= 0 &&
michael@0 336 x + width <= fDevice.width() && y + height <= fDevice.height());
michael@0 337
michael@0 338 uint32_t* device = fDevice.getAddr32(x, y);
michael@0 339 size_t deviceRB = fDevice.rowBytes();
michael@0 340 SkShader* shader = fShader;
michael@0 341 SkPMColor* span = fBuffer;
michael@0 342
michael@0 343 if (fConstInY) {
michael@0 344 if (fShadeDirectlyIntoDevice) {
michael@0 345 // shade the first row directly into the device
michael@0 346 fShader->shadeSpan(x, y, device, width);
michael@0 347 span = device;
michael@0 348 while (--height > 0) {
michael@0 349 device = (uint32_t*)((char*)device + deviceRB);
michael@0 350 memcpy(device, span, width << 2);
michael@0 351 }
michael@0 352 } else {
michael@0 353 fShader->shadeSpan(x, y, span, width);
michael@0 354 SkXfermode* xfer = fXfermode;
michael@0 355 if (xfer) {
michael@0 356 do {
michael@0 357 xfer->xfer32(device, span, width, NULL);
michael@0 358 y += 1;
michael@0 359 device = (uint32_t*)((char*)device + deviceRB);
michael@0 360 } while (--height > 0);
michael@0 361 } else {
michael@0 362 SkBlitRow::Proc32 proc = fProc32;
michael@0 363 do {
michael@0 364 proc(device, span, width, 255);
michael@0 365 y += 1;
michael@0 366 device = (uint32_t*)((char*)device + deviceRB);
michael@0 367 } while (--height > 0);
michael@0 368 }
michael@0 369 }
michael@0 370 return;
michael@0 371 }
michael@0 372
michael@0 373 if (fShadeDirectlyIntoDevice) {
michael@0 374 void* ctx;
michael@0 375 SkShader::ShadeProc shadeProc = fShader->asAShadeProc(&ctx);
michael@0 376 if (shadeProc) {
michael@0 377 do {
michael@0 378 shadeProc(ctx, x, y, device, width);
michael@0 379 y += 1;
michael@0 380 device = (uint32_t*)((char*)device + deviceRB);
michael@0 381 } while (--height > 0);
michael@0 382 } else {
michael@0 383 do {
michael@0 384 shader->shadeSpan(x, y, device, width);
michael@0 385 y += 1;
michael@0 386 device = (uint32_t*)((char*)device + deviceRB);
michael@0 387 } while (--height > 0);
michael@0 388 }
michael@0 389 } else {
michael@0 390 SkXfermode* xfer = fXfermode;
michael@0 391 if (xfer) {
michael@0 392 do {
michael@0 393 shader->shadeSpan(x, y, span, width);
michael@0 394 xfer->xfer32(device, span, width, NULL);
michael@0 395 y += 1;
michael@0 396 device = (uint32_t*)((char*)device + deviceRB);
michael@0 397 } while (--height > 0);
michael@0 398 } else {
michael@0 399 SkBlitRow::Proc32 proc = fProc32;
michael@0 400 do {
michael@0 401 shader->shadeSpan(x, y, span, width);
michael@0 402 proc(device, span, width, 255);
michael@0 403 y += 1;
michael@0 404 device = (uint32_t*)((char*)device + deviceRB);
michael@0 405 } while (--height > 0);
michael@0 406 }
michael@0 407 }
michael@0 408 }
michael@0 409
michael@0 410 void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
michael@0 411 const int16_t runs[]) {
michael@0 412 SkPMColor* span = fBuffer;
michael@0 413 uint32_t* device = fDevice.getAddr32(x, y);
michael@0 414 SkShader* shader = fShader;
michael@0 415
michael@0 416 if (fXfermode && !fShadeDirectlyIntoDevice) {
michael@0 417 for (;;) {
michael@0 418 SkXfermode* xfer = fXfermode;
michael@0 419
michael@0 420 int count = *runs;
michael@0 421 if (count <= 0)
michael@0 422 break;
michael@0 423 int aa = *antialias;
michael@0 424 if (aa) {
michael@0 425 shader->shadeSpan(x, y, span, count);
michael@0 426 if (aa == 255) {
michael@0 427 xfer->xfer32(device, span, count, NULL);
michael@0 428 } else {
michael@0 429 // count is almost always 1
michael@0 430 for (int i = count - 1; i >= 0; --i) {
michael@0 431 xfer->xfer32(&device[i], &span[i], 1, antialias);
michael@0 432 }
michael@0 433 }
michael@0 434 }
michael@0 435 device += count;
michael@0 436 runs += count;
michael@0 437 antialias += count;
michael@0 438 x += count;
michael@0 439 }
michael@0 440 } else if (fShadeDirectlyIntoDevice ||
michael@0 441 (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
michael@0 442 for (;;) {
michael@0 443 int count = *runs;
michael@0 444 if (count <= 0) {
michael@0 445 break;
michael@0 446 }
michael@0 447 int aa = *antialias;
michael@0 448 if (aa) {
michael@0 449 if (aa == 255) {
michael@0 450 // cool, have the shader draw right into the device
michael@0 451 shader->shadeSpan(x, y, device, count);
michael@0 452 } else {
michael@0 453 shader->shadeSpan(x, y, span, count);
michael@0 454 fProc32Blend(device, span, count, aa);
michael@0 455 }
michael@0 456 }
michael@0 457 device += count;
michael@0 458 runs += count;
michael@0 459 antialias += count;
michael@0 460 x += count;
michael@0 461 }
michael@0 462 } else {
michael@0 463 for (;;) {
michael@0 464 int count = *runs;
michael@0 465 if (count <= 0) {
michael@0 466 break;
michael@0 467 }
michael@0 468 int aa = *antialias;
michael@0 469 if (aa) {
michael@0 470 fShader->shadeSpan(x, y, span, count);
michael@0 471 if (aa == 255) {
michael@0 472 fProc32(device, span, count, 255);
michael@0 473 } else {
michael@0 474 fProc32Blend(device, span, count, aa);
michael@0 475 }
michael@0 476 }
michael@0 477 device += count;
michael@0 478 runs += count;
michael@0 479 antialias += count;
michael@0 480 x += count;
michael@0 481 }
michael@0 482 }
michael@0 483 }
michael@0 484
michael@0 485 void SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
michael@0 486 // we only handle kA8 with an xfermode
michael@0 487 if (fXfermode && (SkMask::kA8_Format != mask.fFormat)) {
michael@0 488 this->INHERITED::blitMask(mask, clip);
michael@0 489 return;
michael@0 490 }
michael@0 491
michael@0 492 SkASSERT(mask.fBounds.contains(clip));
michael@0 493
michael@0 494 SkBlitMask::RowProc proc = NULL;
michael@0 495 if (!fXfermode) {
michael@0 496 unsigned flags = 0;
michael@0 497 if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) {
michael@0 498 flags |= SkBlitMask::kSrcIsOpaque_RowFlag;
michael@0 499 }
michael@0 500 proc = SkBlitMask::RowFactory(SkBitmap::kARGB_8888_Config, mask.fFormat,
michael@0 501 (SkBlitMask::RowFlags)flags);
michael@0 502 if (NULL == proc) {
michael@0 503 this->INHERITED::blitMask(mask, clip);
michael@0 504 return;
michael@0 505 }
michael@0 506 }
michael@0 507
michael@0 508 const int x = clip.fLeft;
michael@0 509 const int width = clip.width();
michael@0 510 int y = clip.fTop;
michael@0 511 int height = clip.height();
michael@0 512
michael@0 513 char* dstRow = (char*)fDevice.getAddr32(x, y);
michael@0 514 const size_t dstRB = fDevice.rowBytes();
michael@0 515 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y);
michael@0 516 const size_t maskRB = mask.fRowBytes;
michael@0 517
michael@0 518 SkShader* shader = fShader;
michael@0 519 SkPMColor* span = fBuffer;
michael@0 520
michael@0 521 if (fXfermode) {
michael@0 522 SkASSERT(SkMask::kA8_Format == mask.fFormat);
michael@0 523 SkXfermode* xfer = fXfermode;
michael@0 524 do {
michael@0 525 shader->shadeSpan(x, y, span, width);
michael@0 526 xfer->xfer32((SkPMColor*)dstRow, span, width, maskRow);
michael@0 527 dstRow += dstRB;
michael@0 528 maskRow += maskRB;
michael@0 529 y += 1;
michael@0 530 } while (--height > 0);
michael@0 531 } else {
michael@0 532 do {
michael@0 533 shader->shadeSpan(x, y, span, width);
michael@0 534 proc(dstRow, maskRow, span, width);
michael@0 535 dstRow += dstRB;
michael@0 536 maskRow += maskRB;
michael@0 537 y += 1;
michael@0 538 } while (--height > 0);
michael@0 539 }
michael@0 540 }
michael@0 541
michael@0 542 void SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
michael@0 543 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height());
michael@0 544
michael@0 545 uint32_t* device = fDevice.getAddr32(x, y);
michael@0 546 size_t deviceRB = fDevice.rowBytes();
michael@0 547 SkShader* shader = fShader;
michael@0 548
michael@0 549 if (fConstInY) {
michael@0 550 SkPMColor c;
michael@0 551 fShader->shadeSpan(x, y, &c, 1);
michael@0 552
michael@0 553 if (fShadeDirectlyIntoDevice) {
michael@0 554 if (255 == alpha) {
michael@0 555 do {
michael@0 556 *device = c;
michael@0 557 device = (uint32_t*)((char*)device + deviceRB);
michael@0 558 } while (--height > 0);
michael@0 559 } else {
michael@0 560 do {
michael@0 561 *device = SkFourByteInterp(c, *device, alpha);
michael@0 562 device = (uint32_t*)((char*)device + deviceRB);
michael@0 563 } while (--height > 0);
michael@0 564 }
michael@0 565 } else {
michael@0 566 SkXfermode* xfer = fXfermode;
michael@0 567 if (xfer) {
michael@0 568 do {
michael@0 569 xfer->xfer32(device, &c, 1, &alpha);
michael@0 570 device = (uint32_t*)((char*)device + deviceRB);
michael@0 571 } while (--height > 0);
michael@0 572 } else {
michael@0 573 SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend;
michael@0 574 do {
michael@0 575 proc(device, &c, 1, alpha);
michael@0 576 device = (uint32_t*)((char*)device + deviceRB);
michael@0 577 } while (--height > 0);
michael@0 578 }
michael@0 579 }
michael@0 580 return;
michael@0 581 }
michael@0 582
michael@0 583 if (fShadeDirectlyIntoDevice) {
michael@0 584 void* ctx;
michael@0 585 SkShader::ShadeProc shadeProc = fShader->asAShadeProc(&ctx);
michael@0 586 if (255 == alpha) {
michael@0 587 if (shadeProc) {
michael@0 588 do {
michael@0 589 shadeProc(ctx, x, y, device, 1);
michael@0 590 y += 1;
michael@0 591 device = (uint32_t*)((char*)device + deviceRB);
michael@0 592 } while (--height > 0);
michael@0 593 } else {
michael@0 594 do {
michael@0 595 shader->shadeSpan(x, y, device, 1);
michael@0 596 y += 1;
michael@0 597 device = (uint32_t*)((char*)device + deviceRB);
michael@0 598 } while (--height > 0);
michael@0 599 }
michael@0 600 } else { // alpha < 255
michael@0 601 SkPMColor c;
michael@0 602 if (shadeProc) {
michael@0 603 do {
michael@0 604 shadeProc(ctx, x, y, &c, 1);
michael@0 605 *device = SkFourByteInterp(c, *device, alpha);
michael@0 606 y += 1;
michael@0 607 device = (uint32_t*)((char*)device + deviceRB);
michael@0 608 } while (--height > 0);
michael@0 609 } else {
michael@0 610 do {
michael@0 611 shader->shadeSpan(x, y, &c, 1);
michael@0 612 *device = SkFourByteInterp(c, *device, alpha);
michael@0 613 y += 1;
michael@0 614 device = (uint32_t*)((char*)device + deviceRB);
michael@0 615 } while (--height > 0);
michael@0 616 }
michael@0 617 }
michael@0 618 } else {
michael@0 619 SkPMColor* span = fBuffer;
michael@0 620 SkXfermode* xfer = fXfermode;
michael@0 621 if (xfer) {
michael@0 622 do {
michael@0 623 shader->shadeSpan(x, y, span, 1);
michael@0 624 xfer->xfer32(device, span, 1, &alpha);
michael@0 625 y += 1;
michael@0 626 device = (uint32_t*)((char*)device + deviceRB);
michael@0 627 } while (--height > 0);
michael@0 628 } else {
michael@0 629 SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend;
michael@0 630 do {
michael@0 631 shader->shadeSpan(x, y, span, 1);
michael@0 632 proc(device, span, 1, alpha);
michael@0 633 y += 1;
michael@0 634 device = (uint32_t*)((char*)device + deviceRB);
michael@0 635 } while (--height > 0);
michael@0 636 }
michael@0 637 }
michael@0 638 }

mercurial