1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkBlitter.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,973 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkBlitter.h" 1.14 +#include "SkAntiRun.h" 1.15 +#include "SkColor.h" 1.16 +#include "SkColorFilter.h" 1.17 +#include "SkCoreBlitters.h" 1.18 +#include "SkFilterShader.h" 1.19 +#include "SkReadBuffer.h" 1.20 +#include "SkWriteBuffer.h" 1.21 +#include "SkMask.h" 1.22 +#include "SkMaskFilter.h" 1.23 +#include "SkString.h" 1.24 +#include "SkTLazy.h" 1.25 +#include "SkUtils.h" 1.26 +#include "SkXfermode.h" 1.27 + 1.28 +SkBlitter::~SkBlitter() {} 1.29 + 1.30 +bool SkBlitter::isNullBlitter() const { return false; } 1.31 + 1.32 +const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { 1.33 + return NULL; 1.34 +} 1.35 + 1.36 +void SkBlitter::blitH(int x, int y, int width) { 1.37 + SkDEBUGFAIL("unimplemented"); 1.38 +} 1.39 + 1.40 +void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 1.41 + const int16_t runs[]) { 1.42 + SkDEBUGFAIL("unimplemented"); 1.43 +} 1.44 + 1.45 +void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 1.46 + if (alpha == 255) { 1.47 + this->blitRect(x, y, 1, height); 1.48 + } else { 1.49 + int16_t runs[2]; 1.50 + runs[0] = 1; 1.51 + runs[1] = 0; 1.52 + 1.53 + while (--height >= 0) { 1.54 + this->blitAntiH(x, y++, &alpha, runs); 1.55 + } 1.56 + } 1.57 +} 1.58 + 1.59 +void SkBlitter::blitRect(int x, int y, int width, int height) { 1.60 + SkASSERT(width > 0); 1.61 + while (--height >= 0) { 1.62 + this->blitH(x, y++, width); 1.63 + } 1.64 +} 1.65 + 1.66 +/// Default implementation doesn't check for any easy optimizations 1.67 +/// such as alpha == 0 or 255; also uses blitV(), which some subclasses 1.68 +/// may not support. 1.69 +void SkBlitter::blitAntiRect(int x, int y, int width, int height, 1.70 + SkAlpha leftAlpha, SkAlpha rightAlpha) { 1.71 + this->blitV(x++, y, height, leftAlpha); 1.72 + if (width > 0) { 1.73 + this->blitRect(x, y, width, height); 1.74 + x += width; 1.75 + } 1.76 + this->blitV(x, y, height, rightAlpha); 1.77 +} 1.78 + 1.79 +////////////////////////////////////////////////////////////////////////////// 1.80 + 1.81 +static inline void bits_to_runs(SkBlitter* blitter, int x, int y, 1.82 + const uint8_t bits[], 1.83 + U8CPU left_mask, int rowBytes, 1.84 + U8CPU right_mask) { 1.85 + int inFill = 0; 1.86 + int pos = 0; 1.87 + 1.88 + while (--rowBytes >= 0) { 1.89 + unsigned b = *bits++ & left_mask; 1.90 + if (rowBytes == 0) { 1.91 + b &= right_mask; 1.92 + } 1.93 + 1.94 + for (unsigned test = 0x80; test != 0; test >>= 1) { 1.95 + if (b & test) { 1.96 + if (!inFill) { 1.97 + pos = x; 1.98 + inFill = true; 1.99 + } 1.100 + } else { 1.101 + if (inFill) { 1.102 + blitter->blitH(pos, y, x - pos); 1.103 + inFill = false; 1.104 + } 1.105 + } 1.106 + x += 1; 1.107 + } 1.108 + left_mask = 0xFF; 1.109 + } 1.110 + 1.111 + // final cleanup 1.112 + if (inFill) { 1.113 + blitter->blitH(pos, y, x - pos); 1.114 + } 1.115 +} 1.116 + 1.117 +void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 1.118 + SkASSERT(mask.fBounds.contains(clip)); 1.119 + 1.120 + if (mask.fFormat == SkMask::kBW_Format) { 1.121 + int cx = clip.fLeft; 1.122 + int cy = clip.fTop; 1.123 + int maskLeft = mask.fBounds.fLeft; 1.124 + int mask_rowBytes = mask.fRowBytes; 1.125 + int height = clip.height(); 1.126 + 1.127 + const uint8_t* bits = mask.getAddr1(cx, cy); 1.128 + 1.129 + if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) { 1.130 + while (--height >= 0) { 1.131 + bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF); 1.132 + bits += mask_rowBytes; 1.133 + cy += 1; 1.134 + } 1.135 + } else { 1.136 + int left_edge = cx - maskLeft; 1.137 + SkASSERT(left_edge >= 0); 1.138 + int rite_edge = clip.fRight - maskLeft; 1.139 + SkASSERT(rite_edge > left_edge); 1.140 + 1.141 + int left_mask = 0xFF >> (left_edge & 7); 1.142 + int rite_mask = 0xFF << (8 - (rite_edge & 7)); 1.143 + int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3); 1.144 + 1.145 + // check for empty right mask, so we don't read off the end (or go slower than we need to) 1.146 + if (rite_mask == 0) { 1.147 + SkASSERT(full_runs >= 0); 1.148 + full_runs -= 1; 1.149 + rite_mask = 0xFF; 1.150 + } 1.151 + if (left_mask == 0xFF) { 1.152 + full_runs -= 1; 1.153 + } 1.154 + 1.155 + // back up manually so we can keep in sync with our byte-aligned src 1.156 + // have cx reflect our actual starting x-coord 1.157 + cx -= left_edge & 7; 1.158 + 1.159 + if (full_runs < 0) { 1.160 + SkASSERT((left_mask & rite_mask) != 0); 1.161 + while (--height >= 0) { 1.162 + bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask); 1.163 + bits += mask_rowBytes; 1.164 + cy += 1; 1.165 + } 1.166 + } else { 1.167 + while (--height >= 0) { 1.168 + bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask); 1.169 + bits += mask_rowBytes; 1.170 + cy += 1; 1.171 + } 1.172 + } 1.173 + } 1.174 + } else { 1.175 + int width = clip.width(); 1.176 + SkAutoSTMalloc<64, int16_t> runStorage(width + 1); 1.177 + int16_t* runs = runStorage.get(); 1.178 + const uint8_t* aa = mask.getAddr8(clip.fLeft, clip.fTop); 1.179 + 1.180 + sk_memset16((uint16_t*)runs, 1, width); 1.181 + runs[width] = 0; 1.182 + 1.183 + int height = clip.height(); 1.184 + int y = clip.fTop; 1.185 + while (--height >= 0) { 1.186 + this->blitAntiH(clip.fLeft, y, aa, runs); 1.187 + aa += mask.fRowBytes; 1.188 + y += 1; 1.189 + } 1.190 + } 1.191 +} 1.192 + 1.193 +/////////////////////// these guys are not virtual, just a helpers 1.194 + 1.195 +void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) { 1.196 + if (clip.quickReject(mask.fBounds)) { 1.197 + return; 1.198 + } 1.199 + 1.200 + SkRegion::Cliperator clipper(clip, mask.fBounds); 1.201 + 1.202 + while (!clipper.done()) { 1.203 + const SkIRect& cr = clipper.rect(); 1.204 + this->blitMask(mask, cr); 1.205 + clipper.next(); 1.206 + } 1.207 +} 1.208 + 1.209 +void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) { 1.210 + SkRegion::Cliperator clipper(clip, rect); 1.211 + 1.212 + while (!clipper.done()) { 1.213 + const SkIRect& cr = clipper.rect(); 1.214 + this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 1.215 + clipper.next(); 1.216 + } 1.217 +} 1.218 + 1.219 +void SkBlitter::blitRegion(const SkRegion& clip) { 1.220 + SkRegion::Iterator iter(clip); 1.221 + 1.222 + while (!iter.done()) { 1.223 + const SkIRect& cr = iter.rect(); 1.224 + this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 1.225 + iter.next(); 1.226 + } 1.227 +} 1.228 + 1.229 +/////////////////////////////////////////////////////////////////////////////// 1.230 + 1.231 +void SkNullBlitter::blitH(int x, int y, int width) {} 1.232 + 1.233 +void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 1.234 + const int16_t runs[]) {} 1.235 + 1.236 +void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {} 1.237 + 1.238 +void SkNullBlitter::blitRect(int x, int y, int width, int height) {} 1.239 + 1.240 +void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {} 1.241 + 1.242 +const SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { 1.243 + return NULL; 1.244 +} 1.245 + 1.246 +bool SkNullBlitter::isNullBlitter() const { return true; } 1.247 + 1.248 +/////////////////////////////////////////////////////////////////////////////// 1.249 + 1.250 +static int compute_anti_width(const int16_t runs[]) { 1.251 + int width = 0; 1.252 + 1.253 + for (;;) { 1.254 + int count = runs[0]; 1.255 + 1.256 + SkASSERT(count >= 0); 1.257 + if (count == 0) { 1.258 + break; 1.259 + } 1.260 + width += count; 1.261 + runs += count; 1.262 + } 1.263 + return width; 1.264 +} 1.265 + 1.266 +static inline bool y_in_rect(int y, const SkIRect& rect) { 1.267 + return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); 1.268 +} 1.269 + 1.270 +static inline bool x_in_rect(int x, const SkIRect& rect) { 1.271 + return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); 1.272 +} 1.273 + 1.274 +void SkRectClipBlitter::blitH(int left, int y, int width) { 1.275 + SkASSERT(width > 0); 1.276 + 1.277 + if (!y_in_rect(y, fClipRect)) { 1.278 + return; 1.279 + } 1.280 + 1.281 + int right = left + width; 1.282 + 1.283 + if (left < fClipRect.fLeft) { 1.284 + left = fClipRect.fLeft; 1.285 + } 1.286 + if (right > fClipRect.fRight) { 1.287 + right = fClipRect.fRight; 1.288 + } 1.289 + 1.290 + width = right - left; 1.291 + if (width > 0) { 1.292 + fBlitter->blitH(left, y, width); 1.293 + } 1.294 +} 1.295 + 1.296 +void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], 1.297 + const int16_t runs[]) { 1.298 + if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) { 1.299 + return; 1.300 + } 1.301 + 1.302 + int x0 = left; 1.303 + int x1 = left + compute_anti_width(runs); 1.304 + 1.305 + if (x1 <= fClipRect.fLeft) { 1.306 + return; 1.307 + } 1.308 + 1.309 + SkASSERT(x0 < x1); 1.310 + if (x0 < fClipRect.fLeft) { 1.311 + int dx = fClipRect.fLeft - x0; 1.312 + SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx); 1.313 + runs += dx; 1.314 + aa += dx; 1.315 + x0 = fClipRect.fLeft; 1.316 + } 1.317 + 1.318 + SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 1.319 + if (x1 > fClipRect.fRight) { 1.320 + x1 = fClipRect.fRight; 1.321 + SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0); 1.322 + ((int16_t*)runs)[x1 - x0] = 0; 1.323 + } 1.324 + 1.325 + SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 1.326 + SkASSERT(compute_anti_width(runs) == x1 - x0); 1.327 + 1.328 + fBlitter->blitAntiH(x0, y, aa, runs); 1.329 +} 1.330 + 1.331 +void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 1.332 + SkASSERT(height > 0); 1.333 + 1.334 + if (!x_in_rect(x, fClipRect)) { 1.335 + return; 1.336 + } 1.337 + 1.338 + int y0 = y; 1.339 + int y1 = y + height; 1.340 + 1.341 + if (y0 < fClipRect.fTop) { 1.342 + y0 = fClipRect.fTop; 1.343 + } 1.344 + if (y1 > fClipRect.fBottom) { 1.345 + y1 = fClipRect.fBottom; 1.346 + } 1.347 + 1.348 + if (y0 < y1) { 1.349 + fBlitter->blitV(x, y0, y1 - y0, alpha); 1.350 + } 1.351 +} 1.352 + 1.353 +void SkRectClipBlitter::blitRect(int left, int y, int width, int height) { 1.354 + SkIRect r; 1.355 + 1.356 + r.set(left, y, left + width, y + height); 1.357 + if (r.intersect(fClipRect)) { 1.358 + fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 1.359 + } 1.360 +} 1.361 + 1.362 +void SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height, 1.363 + SkAlpha leftAlpha, SkAlpha rightAlpha) { 1.364 + SkIRect r; 1.365 + 1.366 + // The *true* width of the rectangle blitted is width+2: 1.367 + r.set(left, y, left + width + 2, y + height); 1.368 + if (r.intersect(fClipRect)) { 1.369 + if (r.fLeft != left) { 1.370 + SkASSERT(r.fLeft > left); 1.371 + leftAlpha = 255; 1.372 + } 1.373 + if (r.fRight != left + width + 2) { 1.374 + SkASSERT(r.fRight < left + width + 2); 1.375 + rightAlpha = 255; 1.376 + } 1.377 + if (255 == leftAlpha && 255 == rightAlpha) { 1.378 + fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 1.379 + } else if (1 == r.width()) { 1.380 + if (r.fLeft == left) { 1.381 + fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha); 1.382 + } else { 1.383 + SkASSERT(r.fLeft == left + width + 1); 1.384 + fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha); 1.385 + } 1.386 + } else { 1.387 + fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 1.388 + leftAlpha, rightAlpha); 1.389 + } 1.390 + } 1.391 +} 1.392 + 1.393 +void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 1.394 + SkASSERT(mask.fBounds.contains(clip)); 1.395 + 1.396 + SkIRect r = clip; 1.397 + 1.398 + if (r.intersect(fClipRect)) { 1.399 + fBlitter->blitMask(mask, r); 1.400 + } 1.401 +} 1.402 + 1.403 +const SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) { 1.404 + return fBlitter->justAnOpaqueColor(value); 1.405 +} 1.406 + 1.407 +/////////////////////////////////////////////////////////////////////////////// 1.408 + 1.409 +void SkRgnClipBlitter::blitH(int x, int y, int width) { 1.410 + SkRegion::Spanerator span(*fRgn, y, x, x + width); 1.411 + int left, right; 1.412 + 1.413 + while (span.next(&left, &right)) { 1.414 + SkASSERT(left < right); 1.415 + fBlitter->blitH(left, y, right - left); 1.416 + } 1.417 +} 1.418 + 1.419 +void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], 1.420 + const int16_t runs[]) { 1.421 + int width = compute_anti_width(runs); 1.422 + SkRegion::Spanerator span(*fRgn, y, x, x + width); 1.423 + int left, right; 1.424 + SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();) 1.425 + 1.426 + int prevRite = x; 1.427 + while (span.next(&left, &right)) { 1.428 + SkASSERT(x <= left); 1.429 + SkASSERT(left < right); 1.430 + SkASSERT(left >= bounds.fLeft && right <= bounds.fRight); 1.431 + 1.432 + SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left); 1.433 + 1.434 + // now zero before left 1.435 + if (left > prevRite) { 1.436 + int index = prevRite - x; 1.437 + ((uint8_t*)aa)[index] = 0; // skip runs after right 1.438 + ((int16_t*)runs)[index] = SkToS16(left - prevRite); 1.439 + } 1.440 + 1.441 + prevRite = right; 1.442 + } 1.443 + 1.444 + if (prevRite > x) { 1.445 + ((int16_t*)runs)[prevRite - x] = 0; 1.446 + 1.447 + if (x < 0) { 1.448 + int skip = runs[0]; 1.449 + SkASSERT(skip >= -x); 1.450 + aa += skip; 1.451 + runs += skip; 1.452 + x += skip; 1.453 + } 1.454 + fBlitter->blitAntiH(x, y, aa, runs); 1.455 + } 1.456 +} 1.457 + 1.458 +void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 1.459 + SkIRect bounds; 1.460 + bounds.set(x, y, x + 1, y + height); 1.461 + 1.462 + SkRegion::Cliperator iter(*fRgn, bounds); 1.463 + 1.464 + while (!iter.done()) { 1.465 + const SkIRect& r = iter.rect(); 1.466 + SkASSERT(bounds.contains(r)); 1.467 + 1.468 + fBlitter->blitV(x, r.fTop, r.height(), alpha); 1.469 + iter.next(); 1.470 + } 1.471 +} 1.472 + 1.473 +void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) { 1.474 + SkIRect bounds; 1.475 + bounds.set(x, y, x + width, y + height); 1.476 + 1.477 + SkRegion::Cliperator iter(*fRgn, bounds); 1.478 + 1.479 + while (!iter.done()) { 1.480 + const SkIRect& r = iter.rect(); 1.481 + SkASSERT(bounds.contains(r)); 1.482 + 1.483 + fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 1.484 + iter.next(); 1.485 + } 1.486 +} 1.487 + 1.488 +void SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height, 1.489 + SkAlpha leftAlpha, SkAlpha rightAlpha) { 1.490 + // The *true* width of the rectangle to blit is width + 2 1.491 + SkIRect bounds; 1.492 + bounds.set(x, y, x + width + 2, y + height); 1.493 + 1.494 + SkRegion::Cliperator iter(*fRgn, bounds); 1.495 + 1.496 + while (!iter.done()) { 1.497 + const SkIRect& r = iter.rect(); 1.498 + SkASSERT(bounds.contains(r)); 1.499 + SkASSERT(r.fLeft >= x); 1.500 + SkASSERT(r.fRight <= x + width + 2); 1.501 + 1.502 + SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255; 1.503 + SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ? 1.504 + rightAlpha : 255; 1.505 + 1.506 + if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) { 1.507 + fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 1.508 + } else if (1 == r.width()) { 1.509 + if (r.fLeft == x) { 1.510 + fBlitter->blitV(r.fLeft, r.fTop, r.height(), 1.511 + effectiveLeftAlpha); 1.512 + } else { 1.513 + SkASSERT(r.fLeft == x + width + 1); 1.514 + fBlitter->blitV(r.fLeft, r.fTop, r.height(), 1.515 + effectiveRightAlpha); 1.516 + } 1.517 + } else { 1.518 + fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 1.519 + effectiveLeftAlpha, effectiveRightAlpha); 1.520 + } 1.521 + iter.next(); 1.522 + } 1.523 +} 1.524 + 1.525 + 1.526 +void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 1.527 + SkASSERT(mask.fBounds.contains(clip)); 1.528 + 1.529 + SkRegion::Cliperator iter(*fRgn, clip); 1.530 + const SkIRect& r = iter.rect(); 1.531 + SkBlitter* blitter = fBlitter; 1.532 + 1.533 + while (!iter.done()) { 1.534 + blitter->blitMask(mask, r); 1.535 + iter.next(); 1.536 + } 1.537 +} 1.538 + 1.539 +const SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) { 1.540 + return fBlitter->justAnOpaqueColor(value); 1.541 +} 1.542 + 1.543 +/////////////////////////////////////////////////////////////////////////////// 1.544 + 1.545 +SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, 1.546 + const SkIRect* ir) { 1.547 + if (clip) { 1.548 + const SkIRect& clipR = clip->getBounds(); 1.549 + 1.550 + if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) { 1.551 + blitter = &fNullBlitter; 1.552 + } else if (clip->isRect()) { 1.553 + if (ir == NULL || !clipR.contains(*ir)) { 1.554 + fRectBlitter.init(blitter, clipR); 1.555 + blitter = &fRectBlitter; 1.556 + } 1.557 + } else { 1.558 + fRgnBlitter.init(blitter, clip); 1.559 + blitter = &fRgnBlitter; 1.560 + } 1.561 + } 1.562 + return blitter; 1.563 +} 1.564 + 1.565 +/////////////////////////////////////////////////////////////////////////////// 1.566 + 1.567 +#include "SkColorShader.h" 1.568 +#include "SkColorPriv.h" 1.569 + 1.570 +class Sk3DShader : public SkShader { 1.571 +public: 1.572 + Sk3DShader(SkShader* proxy) : fProxy(proxy) { 1.573 + SkSafeRef(proxy); 1.574 + fMask = NULL; 1.575 + } 1.576 + 1.577 + virtual ~Sk3DShader() { 1.578 + SkSafeUnref(fProxy); 1.579 + } 1.580 + 1.581 + void setMask(const SkMask* mask) { fMask = mask; } 1.582 + 1.583 + virtual bool setContext(const SkBitmap& device, const SkPaint& paint, 1.584 + const SkMatrix& matrix) SK_OVERRIDE { 1.585 + if (!this->INHERITED::setContext(device, paint, matrix)) { 1.586 + return false; 1.587 + } 1.588 + if (fProxy) { 1.589 + if (!fProxy->setContext(device, paint, matrix)) { 1.590 + // must keep our set/end context calls balanced 1.591 + this->INHERITED::endContext(); 1.592 + return false; 1.593 + } 1.594 + } else { 1.595 + fPMColor = SkPreMultiplyColor(paint.getColor()); 1.596 + } 1.597 + return true; 1.598 + } 1.599 + 1.600 + virtual void endContext() SK_OVERRIDE { 1.601 + if (fProxy) { 1.602 + fProxy->endContext(); 1.603 + } 1.604 + this->INHERITED::endContext(); 1.605 + } 1.606 + 1.607 + virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE { 1.608 + if (fProxy) { 1.609 + fProxy->shadeSpan(x, y, span, count); 1.610 + } 1.611 + 1.612 + if (fMask == NULL) { 1.613 + if (fProxy == NULL) { 1.614 + sk_memset32(span, fPMColor, count); 1.615 + } 1.616 + return; 1.617 + } 1.618 + 1.619 + SkASSERT(fMask->fBounds.contains(x, y)); 1.620 + SkASSERT(fMask->fBounds.contains(x + count - 1, y)); 1.621 + 1.622 + size_t size = fMask->computeImageSize(); 1.623 + const uint8_t* alpha = fMask->getAddr8(x, y); 1.624 + const uint8_t* mulp = alpha + size; 1.625 + const uint8_t* addp = mulp + size; 1.626 + 1.627 + if (fProxy) { 1.628 + for (int i = 0; i < count; i++) { 1.629 + if (alpha[i]) { 1.630 + SkPMColor c = span[i]; 1.631 + if (c) { 1.632 + unsigned a = SkGetPackedA32(c); 1.633 + unsigned r = SkGetPackedR32(c); 1.634 + unsigned g = SkGetPackedG32(c); 1.635 + unsigned b = SkGetPackedB32(c); 1.636 + 1.637 + unsigned mul = SkAlpha255To256(mulp[i]); 1.638 + unsigned add = addp[i]; 1.639 + 1.640 + r = SkFastMin32(SkAlphaMul(r, mul) + add, a); 1.641 + g = SkFastMin32(SkAlphaMul(g, mul) + add, a); 1.642 + b = SkFastMin32(SkAlphaMul(b, mul) + add, a); 1.643 + 1.644 + span[i] = SkPackARGB32(a, r, g, b); 1.645 + } 1.646 + } else { 1.647 + span[i] = 0; 1.648 + } 1.649 + } 1.650 + } else { // color 1.651 + unsigned a = SkGetPackedA32(fPMColor); 1.652 + unsigned r = SkGetPackedR32(fPMColor); 1.653 + unsigned g = SkGetPackedG32(fPMColor); 1.654 + unsigned b = SkGetPackedB32(fPMColor); 1.655 + for (int i = 0; i < count; i++) { 1.656 + if (alpha[i]) { 1.657 + unsigned mul = SkAlpha255To256(mulp[i]); 1.658 + unsigned add = addp[i]; 1.659 + 1.660 + span[i] = SkPackARGB32( a, 1.661 + SkFastMin32(SkAlphaMul(r, mul) + add, a), 1.662 + SkFastMin32(SkAlphaMul(g, mul) + add, a), 1.663 + SkFastMin32(SkAlphaMul(b, mul) + add, a)); 1.664 + } else { 1.665 + span[i] = 0; 1.666 + } 1.667 + } 1.668 + } 1.669 + } 1.670 + 1.671 +#ifndef SK_IGNORE_TO_STRING 1.672 + virtual void toString(SkString* str) const SK_OVERRIDE { 1.673 + str->append("Sk3DShader: ("); 1.674 + 1.675 + if (NULL != fProxy) { 1.676 + str->append("Proxy: "); 1.677 + fProxy->toString(str); 1.678 + } 1.679 + 1.680 + this->INHERITED::toString(str); 1.681 + 1.682 + str->append(")"); 1.683 + } 1.684 +#endif 1.685 + 1.686 + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader) 1.687 + 1.688 +protected: 1.689 + Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) { 1.690 + fProxy = buffer.readShader(); 1.691 + fPMColor = buffer.readColor(); 1.692 + fMask = NULL; 1.693 + } 1.694 + 1.695 + virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE { 1.696 + this->INHERITED::flatten(buffer); 1.697 + buffer.writeFlattenable(fProxy); 1.698 + buffer.writeColor(fPMColor); 1.699 + } 1.700 + 1.701 +private: 1.702 + SkShader* fProxy; 1.703 + SkPMColor fPMColor; 1.704 + const SkMask* fMask; 1.705 + 1.706 + typedef SkShader INHERITED; 1.707 +}; 1.708 + 1.709 +class Sk3DBlitter : public SkBlitter { 1.710 +public: 1.711 + Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader) 1.712 + : fProxy(proxy) 1.713 + , f3DShader(SkRef(shader)) 1.714 + {} 1.715 + 1.716 + virtual void blitH(int x, int y, int width) { 1.717 + fProxy->blitH(x, y, width); 1.718 + } 1.719 + 1.720 + virtual void blitAntiH(int x, int y, const SkAlpha antialias[], 1.721 + const int16_t runs[]) { 1.722 + fProxy->blitAntiH(x, y, antialias, runs); 1.723 + } 1.724 + 1.725 + virtual void blitV(int x, int y, int height, SkAlpha alpha) { 1.726 + fProxy->blitV(x, y, height, alpha); 1.727 + } 1.728 + 1.729 + virtual void blitRect(int x, int y, int width, int height) { 1.730 + fProxy->blitRect(x, y, width, height); 1.731 + } 1.732 + 1.733 + virtual void blitMask(const SkMask& mask, const SkIRect& clip) { 1.734 + if (mask.fFormat == SkMask::k3D_Format) { 1.735 + f3DShader->setMask(&mask); 1.736 + 1.737 + ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; 1.738 + fProxy->blitMask(mask, clip); 1.739 + ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; 1.740 + 1.741 + f3DShader->setMask(NULL); 1.742 + } else { 1.743 + fProxy->blitMask(mask, clip); 1.744 + } 1.745 + } 1.746 + 1.747 +private: 1.748 + // fProxy is unowned. It will be deleted by SkSmallAllocator. 1.749 + SkBlitter* fProxy; 1.750 + SkAutoTUnref<Sk3DShader> f3DShader; 1.751 +}; 1.752 + 1.753 +/////////////////////////////////////////////////////////////////////////////// 1.754 + 1.755 +#include "SkCoreBlitters.h" 1.756 + 1.757 +static bool just_solid_color(const SkPaint& paint) { 1.758 + if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) { 1.759 + SkShader* shader = paint.getShader(); 1.760 + if (NULL == shader || 1.761 + (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) { 1.762 + return true; 1.763 + } 1.764 + } 1.765 + return false; 1.766 +} 1.767 + 1.768 +/** By analyzing the paint (with an xfermode), we may decide we can take 1.769 + special action. This enum lists our possible actions 1.770 + */ 1.771 +enum XferInterp { 1.772 + kNormal_XferInterp, // no special interpretation, draw normally 1.773 + kSrcOver_XferInterp, // draw as if in srcover mode 1.774 + kSkipDrawing_XferInterp // draw nothing 1.775 +}; 1.776 + 1.777 +static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer, 1.778 + SkColorType deviceCT) { 1.779 + SkXfermode::Mode mode; 1.780 + 1.781 + if (SkXfermode::AsMode(xfer, &mode)) { 1.782 + switch (mode) { 1.783 + case SkXfermode::kSrc_Mode: 1.784 + if (just_solid_color(paint)) { 1.785 + return kSrcOver_XferInterp; 1.786 + } 1.787 + break; 1.788 + case SkXfermode::kDst_Mode: 1.789 + return kSkipDrawing_XferInterp; 1.790 + case SkXfermode::kSrcOver_Mode: 1.791 + return kSrcOver_XferInterp; 1.792 + case SkXfermode::kDstOver_Mode: 1.793 + if (kRGB_565_SkColorType == deviceCT) { 1.794 + return kSkipDrawing_XferInterp; 1.795 + } 1.796 + break; 1.797 + case SkXfermode::kSrcIn_Mode: 1.798 + if (kRGB_565_SkColorType == deviceCT && 1.799 + just_solid_color(paint)) { 1.800 + return kSrcOver_XferInterp; 1.801 + } 1.802 + break; 1.803 + case SkXfermode::kDstIn_Mode: 1.804 + if (just_solid_color(paint)) { 1.805 + return kSkipDrawing_XferInterp; 1.806 + } 1.807 + break; 1.808 + default: 1.809 + break; 1.810 + } 1.811 + } 1.812 + return kNormal_XferInterp; 1.813 +} 1.814 + 1.815 +SkBlitter* SkBlitter::Choose(const SkBitmap& device, 1.816 + const SkMatrix& matrix, 1.817 + const SkPaint& origPaint, 1.818 + SkTBlitterAllocator* allocator, 1.819 + bool drawCoverage) { 1.820 + SkASSERT(allocator != NULL); 1.821 + 1.822 + SkBlitter* blitter = NULL; 1.823 + 1.824 + // which check, in case we're being called by a client with a dummy device 1.825 + // (e.g. they have a bounder that always aborts the draw) 1.826 + if (kUnknown_SkColorType == device.colorType() || 1.827 + (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) { 1.828 + blitter = allocator->createT<SkNullBlitter>(); 1.829 + return blitter; 1.830 + } 1.831 + 1.832 + SkShader* shader = origPaint.getShader(); 1.833 + SkColorFilter* cf = origPaint.getColorFilter(); 1.834 + SkXfermode* mode = origPaint.getXfermode(); 1.835 + Sk3DShader* shader3D = NULL; 1.836 + 1.837 + SkTCopyOnFirstWrite<SkPaint> paint(origPaint); 1.838 + 1.839 + if (origPaint.getMaskFilter() != NULL && 1.840 + origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { 1.841 + shader3D = SkNEW_ARGS(Sk3DShader, (shader)); 1.842 + // we know we haven't initialized lazyPaint yet, so just do it 1.843 + paint.writable()->setShader(shader3D)->unref(); 1.844 + shader = shader3D; 1.845 + } 1.846 + 1.847 + if (NULL != mode) { 1.848 + switch (interpret_xfermode(*paint, mode, device.colorType())) { 1.849 + case kSrcOver_XferInterp: 1.850 + mode = NULL; 1.851 + paint.writable()->setXfermode(NULL); 1.852 + break; 1.853 + case kSkipDrawing_XferInterp:{ 1.854 + blitter = allocator->createT<SkNullBlitter>(); 1.855 + return blitter; 1.856 + } 1.857 + default: 1.858 + break; 1.859 + } 1.860 + } 1.861 + 1.862 + /* 1.863 + * If the xfermode is CLEAR, then we can completely ignore the installed 1.864 + * color/shader/colorfilter, and just pretend we're SRC + color==0. This 1.865 + * will fall into our optimizations for SRC mode. 1.866 + */ 1.867 + if (SkXfermode::IsMode(mode, SkXfermode::kClear_Mode)) { 1.868 + SkPaint* p = paint.writable(); 1.869 + shader = p->setShader(NULL); 1.870 + cf = p->setColorFilter(NULL); 1.871 + mode = p->setXfermodeMode(SkXfermode::kSrc_Mode); 1.872 + p->setColor(0); 1.873 + } 1.874 + 1.875 + if (NULL == shader) { 1.876 + if (mode) { 1.877 + // xfermodes (and filters) require shaders for our current blitters 1.878 + shader = SkNEW(SkColorShader); 1.879 + paint.writable()->setShader(shader)->unref(); 1.880 + } else if (cf) { 1.881 + // if no shader && no xfermode, we just apply the colorfilter to 1.882 + // our color and move on. 1.883 + SkPaint* writablePaint = paint.writable(); 1.884 + writablePaint->setColor(cf->filterColor(paint->getColor())); 1.885 + writablePaint->setColorFilter(NULL); 1.886 + cf = NULL; 1.887 + } 1.888 + } 1.889 + 1.890 + if (cf) { 1.891 + SkASSERT(shader); 1.892 + shader = SkNEW_ARGS(SkFilterShader, (shader, cf)); 1.893 + paint.writable()->setShader(shader)->unref(); 1.894 + // blitters should ignore the presence/absence of a filter, since 1.895 + // if there is one, the shader will take care of it. 1.896 + } 1.897 + 1.898 + /* 1.899 + * We need to have balanced calls to the shader: 1.900 + * setContext 1.901 + * endContext 1.902 + * We make the first call here, in case it fails we can abort the draw. 1.903 + * The endContext() call is made by the blitter (assuming setContext did 1.904 + * not fail) in its destructor. 1.905 + */ 1.906 + if (shader && !shader->setContext(device, *paint, matrix)) { 1.907 + blitter = allocator->createT<SkNullBlitter>(); 1.908 + return blitter; 1.909 + } 1.910 + 1.911 + 1.912 + switch (device.colorType()) { 1.913 + case kAlpha_8_SkColorType: 1.914 + if (drawCoverage) { 1.915 + SkASSERT(NULL == shader); 1.916 + SkASSERT(NULL == paint->getXfermode()); 1.917 + blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *paint); 1.918 + } else if (shader) { 1.919 + blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint); 1.920 + } else { 1.921 + blitter = allocator->createT<SkA8_Blitter>(device, *paint); 1.922 + } 1.923 + break; 1.924 + 1.925 + case kRGB_565_SkColorType: 1.926 + blitter = SkBlitter_ChooseD565(device, *paint, allocator); 1.927 + break; 1.928 + 1.929 + case kPMColor_SkColorType: 1.930 + if (shader) { 1.931 + blitter = allocator->createT<SkARGB32_Shader_Blitter>(device, *paint); 1.932 + } else if (paint->getColor() == SK_ColorBLACK) { 1.933 + blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *paint); 1.934 + } else if (paint->getAlpha() == 0xFF) { 1.935 + blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *paint); 1.936 + } else { 1.937 + blitter = allocator->createT<SkARGB32_Blitter>(device, *paint); 1.938 + } 1.939 + break; 1.940 + 1.941 + default: 1.942 + SkDEBUGFAIL("unsupported device config"); 1.943 + blitter = allocator->createT<SkNullBlitter>(); 1.944 + break; 1.945 + } 1.946 + 1.947 + if (shader3D) { 1.948 + SkBlitter* innerBlitter = blitter; 1.949 + // innerBlitter was allocated by allocator, which will delete it. 1.950 + blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shader3D); 1.951 + } 1.952 + return blitter; 1.953 +} 1.954 + 1.955 +/////////////////////////////////////////////////////////////////////////////// 1.956 + 1.957 +const uint16_t gMask_0F0F = 0xF0F; 1.958 +const uint32_t gMask_00FF00FF = 0xFF00FF; 1.959 + 1.960 +/////////////////////////////////////////////////////////////////////////////// 1.961 + 1.962 +SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint) 1.963 + : INHERITED(device) { 1.964 + fShader = paint.getShader(); 1.965 + SkASSERT(fShader); 1.966 + SkASSERT(fShader->setContextHasBeenCalled()); 1.967 + 1.968 + fShader->ref(); 1.969 + fShaderFlags = fShader->getFlags(); 1.970 +} 1.971 + 1.972 +SkShaderBlitter::~SkShaderBlitter() { 1.973 + SkASSERT(fShader->setContextHasBeenCalled()); 1.974 + fShader->endContext(); 1.975 + fShader->unref(); 1.976 +}