| OLD | NEW |
| (Empty) |
| 1 /* libs/graphics/sgl/SkBlitter.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 "SkBlitter.h" | |
| 19 #include "SkAntiRun.h" | |
| 20 #include "SkColor.h" | |
| 21 #include "SkColorFilter.h" | |
| 22 #include "SkMask.h" | |
| 23 #include "SkMaskFilter.h" | |
| 24 #include "SkTemplatesPriv.h" | |
| 25 #include "SkUtils.h" | |
| 26 #include "SkXfermode.h" | |
| 27 | |
| 28 SkBlitter::~SkBlitter() | |
| 29 { | |
| 30 } | |
| 31 | |
| 32 const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) | |
| 33 { | |
| 34 return NULL; | |
| 35 } | |
| 36 | |
| 37 void SkBlitter::blitH(int x, int y, int width) | |
| 38 { | |
| 39 SkASSERT(!"unimplemented"); | |
| 40 } | |
| 41 | |
| 42 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t
runs[]) | |
| 43 { | |
| 44 SkASSERT(!"unimplemented"); | |
| 45 } | |
| 46 | |
| 47 void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) | |
| 48 { | |
| 49 if (alpha == 255) | |
| 50 this->blitRect(x, y, 1, height); | |
| 51 else | |
| 52 { | |
| 53 int16_t runs[2]; | |
| 54 runs[0] = 1; | |
| 55 runs[1] = 0; | |
| 56 | |
| 57 while (--height >= 0) | |
| 58 this->blitAntiH(x, y++, &alpha, runs); | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 void SkBlitter::blitRect(int x, int y, int width, int height) | |
| 63 { | |
| 64 while (--height >= 0) | |
| 65 this->blitH(x, y++, width); | |
| 66 } | |
| 67 | |
| 68 ////////////////////////////////////////////////////////////////////////////// | |
| 69 | |
| 70 static inline void bits_to_runs(SkBlitter* blitter, int x, int y, const uint8_t
bits[], | |
| 71 U8CPU left_mask, int rowBytes, U8CPU right_mask) | |
| 72 { | |
| 73 int inFill = 0; | |
| 74 int pos = 0; | |
| 75 | |
| 76 while (--rowBytes >= 0) | |
| 77 { | |
| 78 unsigned b = *bits++ & left_mask; | |
| 79 if (rowBytes == 0) | |
| 80 b &= right_mask; | |
| 81 | |
| 82 for (unsigned test = 0x80; test != 0; test >>= 1) | |
| 83 { | |
| 84 if (b & test) | |
| 85 { | |
| 86 if (!inFill) | |
| 87 { | |
| 88 pos = x; | |
| 89 inFill = true; | |
| 90 } | |
| 91 } | |
| 92 else | |
| 93 { | |
| 94 if (inFill) | |
| 95 { | |
| 96 blitter->blitH(pos, y, x - pos); | |
| 97 inFill = false; | |
| 98 } | |
| 99 } | |
| 100 x += 1; | |
| 101 } | |
| 102 left_mask = 0xFF; | |
| 103 } | |
| 104 | |
| 105 // final cleanup | |
| 106 if (inFill) | |
| 107 blitter->blitH(pos, y, x - pos); | |
| 108 } | |
| 109 | |
| 110 void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) | |
| 111 { | |
| 112 SkASSERT(mask.fBounds.contains(clip)); | |
| 113 | |
| 114 if (mask.fFormat == SkMask::kBW_Format) | |
| 115 { | |
| 116 int cx = clip.fLeft; | |
| 117 int cy = clip.fTop; | |
| 118 int maskLeft = mask.fBounds.fLeft; | |
| 119 int mask_rowBytes = mask.fRowBytes; | |
| 120 int height = clip.height(); | |
| 121 | |
| 122 const uint8_t* bits = mask.getAddr1(cx, cy); | |
| 123 | |
| 124 if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) | |
| 125 { | |
| 126 while (--height >= 0) | |
| 127 { | |
| 128 bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF); | |
| 129 bits += mask_rowBytes; | |
| 130 cy += 1; | |
| 131 } | |
| 132 } | |
| 133 else | |
| 134 { | |
| 135 int left_edge = cx - maskLeft; | |
| 136 SkASSERT(left_edge >= 0); | |
| 137 int rite_edge = clip.fRight - maskLeft; | |
| 138 SkASSERT(rite_edge > left_edge); | |
| 139 | |
| 140 int left_mask = 0xFF >> (left_edge & 7); | |
| 141 int rite_mask = 0xFF << (8 - (rite_edge & 7)); | |
| 142 int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3); | |
| 143 | |
| 144 // check for empty right mask, so we don't read off the end (or go s
lower than we need to) | |
| 145 if (rite_mask == 0) | |
| 146 { | |
| 147 SkASSERT(full_runs >= 0); | |
| 148 full_runs -= 1; | |
| 149 rite_mask = 0xFF; | |
| 150 } | |
| 151 if (left_mask == 0xFF) | |
| 152 full_runs -= 1; | |
| 153 | |
| 154 // back up manually so we can keep in sync with our byte-aligned src | |
| 155 // have cx reflect our actual starting x-coord | |
| 156 cx -= left_edge & 7; | |
| 157 | |
| 158 if (full_runs < 0) | |
| 159 { | |
| 160 SkASSERT((left_mask & rite_mask) != 0); | |
| 161 while (--height >= 0) | |
| 162 { | |
| 163 bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask); | |
| 164 bits += mask_rowBytes; | |
| 165 cy += 1; | |
| 166 } | |
| 167 } | |
| 168 else | |
| 169 { | |
| 170 while (--height >= 0) | |
| 171 { | |
| 172 bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, r
ite_mask); | |
| 173 bits += mask_rowBytes; | |
| 174 cy += 1; | |
| 175 } | |
| 176 } | |
| 177 } | |
| 178 } | |
| 179 else | |
| 180 { | |
| 181 int width = clip.width(); | |
| 182 SkAutoSTMalloc<64, int16_t> runStorage(width + 1); | |
| 183 int16_t* runs = runStorage.get(); | |
| 184 const uint8_t* aa = mask.getAddr(clip.fLeft, clip.fTop); | |
| 185 | |
| 186 sk_memset16((uint16_t*)runs, 1, width); | |
| 187 runs[width] = 0; | |
| 188 | |
| 189 int height = clip.height(); | |
| 190 int y = clip.fTop; | |
| 191 while (--height >= 0) | |
| 192 { | |
| 193 this->blitAntiH(clip.fLeft, y, aa, runs); | |
| 194 aa += mask.fRowBytes; | |
| 195 y += 1; | |
| 196 } | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 /////////////////////// these guys are not virtual, just a helpers | |
| 201 | |
| 202 void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) { | |
| 203 if (clip.quickReject(mask.fBounds)) { | |
| 204 return; | |
| 205 } | |
| 206 | |
| 207 SkRegion::Cliperator clipper(clip, mask.fBounds); | |
| 208 | |
| 209 while (!clipper.done()) { | |
| 210 const SkIRect& cr = clipper.rect(); | |
| 211 this->blitMask(mask, cr); | |
| 212 clipper.next(); | |
| 213 } | |
| 214 } | |
| 215 | |
| 216 void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) { | |
| 217 SkRegion::Cliperator clipper(clip, rect); | |
| 218 | |
| 219 while (!clipper.done()) { | |
| 220 const SkIRect& cr = clipper.rect(); | |
| 221 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); | |
| 222 clipper.next(); | |
| 223 } | |
| 224 } | |
| 225 | |
| 226 void SkBlitter::blitRegion(const SkRegion& clip) { | |
| 227 SkRegion::Iterator iter(clip); | |
| 228 | |
| 229 while (!iter.done()) { | |
| 230 const SkIRect& cr = iter.rect(); | |
| 231 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); | |
| 232 iter.next(); | |
| 233 } | |
| 234 } | |
| 235 | |
| 236 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 237 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 238 | |
| 239 void SkNullBlitter::blitH(int x, int y, int width) | |
| 240 { | |
| 241 } | |
| 242 | |
| 243 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int
16_t runs[]) | |
| 244 { | |
| 245 } | |
| 246 | |
| 247 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) | |
| 248 { | |
| 249 } | |
| 250 | |
| 251 void SkNullBlitter::blitRect(int x, int y, int width, int height) | |
| 252 { | |
| 253 } | |
| 254 | |
| 255 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) | |
| 256 { | |
| 257 } | |
| 258 | |
| 259 const SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) | |
| 260 { | |
| 261 return NULL; | |
| 262 } | |
| 263 | |
| 264 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 265 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 266 | |
| 267 static int compute_anti_width(const int16_t runs[]) | |
| 268 { | |
| 269 int width = 0; | |
| 270 | |
| 271 for (;;) | |
| 272 { | |
| 273 int count = runs[0]; | |
| 274 | |
| 275 SkASSERT(count >= 0); | |
| 276 if (count == 0) | |
| 277 break; | |
| 278 width += count; | |
| 279 runs += count; | |
| 280 | |
| 281 SkASSERT(width < 20000); | |
| 282 } | |
| 283 return width; | |
| 284 } | |
| 285 | |
| 286 static inline bool y_in_rect(int y, const SkIRect& rect) | |
| 287 { | |
| 288 return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); | |
| 289 } | |
| 290 | |
| 291 static inline bool x_in_rect(int x, const SkIRect& rect) | |
| 292 { | |
| 293 return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); | |
| 294 } | |
| 295 | |
| 296 void SkRectClipBlitter::blitH(int left, int y, int width) | |
| 297 { | |
| 298 SkASSERT(width > 0); | |
| 299 | |
| 300 if (!y_in_rect(y, fClipRect)) | |
| 301 return; | |
| 302 | |
| 303 int right = left + width; | |
| 304 | |
| 305 if (left < fClipRect.fLeft) | |
| 306 left = fClipRect.fLeft; | |
| 307 if (right > fClipRect.fRight) | |
| 308 right = fClipRect.fRight; | |
| 309 | |
| 310 width = right - left; | |
| 311 if (width > 0) | |
| 312 fBlitter->blitH(left, y, width); | |
| 313 } | |
| 314 | |
| 315 void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], const int
16_t runs[]) | |
| 316 { | |
| 317 if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) | |
| 318 return; | |
| 319 | |
| 320 int x0 = left; | |
| 321 int x1 = left + compute_anti_width(runs); | |
| 322 | |
| 323 if (x1 <= fClipRect.fLeft) | |
| 324 return; | |
| 325 | |
| 326 SkASSERT(x0 < x1); | |
| 327 if (x0 < fClipRect.fLeft) | |
| 328 { | |
| 329 int dx = fClipRect.fLeft - x0; | |
| 330 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx); | |
| 331 runs += dx; | |
| 332 aa += dx; | |
| 333 x0 = fClipRect.fLeft; | |
| 334 } | |
| 335 | |
| 336 SkASSERT(x0 < x1 && runs[x1 - x0] == 0); | |
| 337 if (x1 > fClipRect.fRight) | |
| 338 { | |
| 339 x1 = fClipRect.fRight; | |
| 340 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0); | |
| 341 ((int16_t*)runs)[x1 - x0] = 0; | |
| 342 } | |
| 343 | |
| 344 SkASSERT(x0 < x1 && runs[x1 - x0] == 0); | |
| 345 SkASSERT(compute_anti_width(runs) == x1 - x0); | |
| 346 | |
| 347 fBlitter->blitAntiH(x0, y, aa, runs); | |
| 348 } | |
| 349 | |
| 350 void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) | |
| 351 { | |
| 352 SkASSERT(height > 0); | |
| 353 | |
| 354 if (!x_in_rect(x, fClipRect)) | |
| 355 return; | |
| 356 | |
| 357 int y0 = y; | |
| 358 int y1 = y + height; | |
| 359 | |
| 360 if (y0 < fClipRect.fTop) | |
| 361 y0 = fClipRect.fTop; | |
| 362 if (y1 > fClipRect.fBottom) | |
| 363 y1 = fClipRect.fBottom; | |
| 364 | |
| 365 if (y0 < y1) | |
| 366 fBlitter->blitV(x, y0, y1 - y0, alpha); | |
| 367 } | |
| 368 | |
| 369 void SkRectClipBlitter::blitRect(int left, int y, int width, int height) | |
| 370 { | |
| 371 SkIRect r; | |
| 372 | |
| 373 r.set(left, y, left + width, y + height); | |
| 374 if (r.intersect(fClipRect)) | |
| 375 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); | |
| 376 } | |
| 377 | |
| 378 void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) | |
| 379 { | |
| 380 SkASSERT(mask.fBounds.contains(clip)); | |
| 381 | |
| 382 SkIRect r = clip; | |
| 383 | |
| 384 if (r.intersect(fClipRect)) | |
| 385 fBlitter->blitMask(mask, r); | |
| 386 } | |
| 387 | |
| 388 const SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) | |
| 389 { | |
| 390 return fBlitter->justAnOpaqueColor(value); | |
| 391 } | |
| 392 | |
| 393 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 394 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 395 | |
| 396 void SkRgnClipBlitter::blitH(int x, int y, int width) | |
| 397 { | |
| 398 SkRegion::Spanerator span(*fRgn, y, x, x + width); | |
| 399 int left, right; | |
| 400 | |
| 401 while (span.next(&left, &right)) | |
| 402 { | |
| 403 SkASSERT(left < right); | |
| 404 fBlitter->blitH(left, y, right - left); | |
| 405 } | |
| 406 } | |
| 407 | |
| 408 void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t
runs[]) | |
| 409 { | |
| 410 int width = compute_anti_width(runs); | |
| 411 SkRegion::Spanerator span(*fRgn, y, x, x + width); | |
| 412 int left, right; | |
| 413 SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();) | |
| 414 | |
| 415 int prevRite = x; | |
| 416 while (span.next(&left, &right)) | |
| 417 { | |
| 418 SkASSERT(x <= left); | |
| 419 SkASSERT(left < right); | |
| 420 SkASSERT(left >= bounds.fLeft && right <= bounds.fRight); | |
| 421 | |
| 422 SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left)
; | |
| 423 | |
| 424 // now zero before left | |
| 425 if (left > prevRite) | |
| 426 { | |
| 427 int index = prevRite - x; | |
| 428 ((uint8_t*)aa)[index] = 0; // skip runs after right | |
| 429 ((int16_t*)runs)[index] = SkToS16(left - prevRite); | |
| 430 } | |
| 431 | |
| 432 prevRite = right; | |
| 433 } | |
| 434 | |
| 435 if (prevRite > x) | |
| 436 { | |
| 437 ((int16_t*)runs)[prevRite - x] = 0; | |
| 438 | |
| 439 if (x < 0) { | |
| 440 int skip = runs[0]; | |
| 441 SkASSERT(skip >= -x); | |
| 442 aa += skip; | |
| 443 runs += skip; | |
| 444 x += skip; | |
| 445 } | |
| 446 fBlitter->blitAntiH(x, y, aa, runs); | |
| 447 } | |
| 448 } | |
| 449 | |
| 450 void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) | |
| 451 { | |
| 452 SkIRect bounds; | |
| 453 bounds.set(x, y, x + 1, y + height); | |
| 454 | |
| 455 SkRegion::Cliperator iter(*fRgn, bounds); | |
| 456 | |
| 457 while (!iter.done()) | |
| 458 { | |
| 459 const SkIRect& r = iter.rect(); | |
| 460 SkASSERT(bounds.contains(r)); | |
| 461 | |
| 462 fBlitter->blitV(x, r.fTop, r.height(), alpha); | |
| 463 iter.next(); | |
| 464 } | |
| 465 } | |
| 466 | |
| 467 void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) | |
| 468 { | |
| 469 SkIRect bounds; | |
| 470 bounds.set(x, y, x + width, y + height); | |
| 471 | |
| 472 SkRegion::Cliperator iter(*fRgn, bounds); | |
| 473 | |
| 474 while (!iter.done()) | |
| 475 { | |
| 476 const SkIRect& r = iter.rect(); | |
| 477 SkASSERT(bounds.contains(r)); | |
| 478 | |
| 479 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); | |
| 480 iter.next(); | |
| 481 } | |
| 482 } | |
| 483 | |
| 484 void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) | |
| 485 { | |
| 486 SkASSERT(mask.fBounds.contains(clip)); | |
| 487 | |
| 488 SkRegion::Cliperator iter(*fRgn, clip); | |
| 489 const SkIRect& r = iter.rect(); | |
| 490 SkBlitter* blitter = fBlitter; | |
| 491 | |
| 492 while (!iter.done()) | |
| 493 { | |
| 494 blitter->blitMask(mask, r); | |
| 495 iter.next(); | |
| 496 } | |
| 497 } | |
| 498 | |
| 499 const SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) | |
| 500 { | |
| 501 return fBlitter->justAnOpaqueColor(value); | |
| 502 } | |
| 503 | |
| 504 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 505 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 506 | |
| 507 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, con
st SkIRect* ir) | |
| 508 { | |
| 509 if (clip) | |
| 510 { | |
| 511 const SkIRect& clipR = clip->getBounds(); | |
| 512 | |
| 513 if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) | |
| 514 blitter = &fNullBlitter; | |
| 515 else if (clip->isRect()) | |
| 516 { | |
| 517 if (ir == NULL || !clipR.contains(*ir)) | |
| 518 { | |
| 519 fRectBlitter.init(blitter, clipR); | |
| 520 blitter = &fRectBlitter; | |
| 521 } | |
| 522 } | |
| 523 else | |
| 524 { | |
| 525 fRgnBlitter.init(blitter, clip); | |
| 526 blitter = &fRgnBlitter; | |
| 527 } | |
| 528 } | |
| 529 return blitter; | |
| 530 } | |
| 531 | |
| 532 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 533 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 534 | |
| 535 #include "SkColorShader.h" | |
| 536 #include "SkColorPriv.h" | |
| 537 | |
| 538 class Sk3DShader : public SkShader { | |
| 539 public: | |
| 540 Sk3DShader(SkShader* proxy) : fProxy(proxy) | |
| 541 { | |
| 542 proxy->safeRef(); | |
| 543 fMask = NULL; | |
| 544 } | |
| 545 virtual ~Sk3DShader() | |
| 546 { | |
| 547 fProxy->safeUnref(); | |
| 548 } | |
| 549 void setMask(const SkMask* mask) { fMask = mask; } | |
| 550 | |
| 551 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const
SkMatrix& matrix) | |
| 552 { | |
| 553 if (fProxy) | |
| 554 return fProxy->setContext(device, paint, matrix); | |
| 555 else | |
| 556 { | |
| 557 fPMColor = SkPreMultiplyColor(paint.getColor()); | |
| 558 return this->INHERITED::setContext(device, paint, matrix); | |
| 559 } | |
| 560 } | |
| 561 virtual void shadeSpan(int x, int y, SkPMColor span[], int count) | |
| 562 { | |
| 563 if (fProxy) | |
| 564 fProxy->shadeSpan(x, y, span, count); | |
| 565 | |
| 566 if (fMask == NULL) | |
| 567 { | |
| 568 if (fProxy == NULL) | |
| 569 sk_memset32(span, fPMColor, count); | |
| 570 return; | |
| 571 } | |
| 572 | |
| 573 SkASSERT(fMask->fBounds.contains(x, y)); | |
| 574 SkASSERT(fMask->fBounds.contains(x + count - 1, y)); | |
| 575 | |
| 576 size_t size = fMask->computeImageSize(); | |
| 577 const uint8_t* alpha = fMask->getAddr(x, y); | |
| 578 const uint8_t* mulp = alpha + size; | |
| 579 const uint8_t* addp = mulp + size; | |
| 580 | |
| 581 if (fProxy) | |
| 582 { | |
| 583 for (int i = 0; i < count; i++) | |
| 584 { | |
| 585 if (alpha[i]) | |
| 586 { | |
| 587 SkPMColor c = span[i]; | |
| 588 if (c) | |
| 589 { | |
| 590 unsigned a = SkGetPackedA32(c); | |
| 591 unsigned r = SkGetPackedR32(c); | |
| 592 unsigned g = SkGetPackedG32(c); | |
| 593 unsigned b = SkGetPackedB32(c); | |
| 594 | |
| 595 unsigned mul = SkAlpha255To256(mulp[i]); | |
| 596 unsigned add = addp[i]; | |
| 597 | |
| 598 r = SkFastMin32(SkAlphaMul(r, mul) + add, a); | |
| 599 g = SkFastMin32(SkAlphaMul(g, mul) + add, a); | |
| 600 b = SkFastMin32(SkAlphaMul(b, mul) + add, a); | |
| 601 | |
| 602 span[i] = SkPackARGB32(a, r, g, b); | |
| 603 } | |
| 604 } | |
| 605 else | |
| 606 span[i] = 0; | |
| 607 } | |
| 608 } | |
| 609 else // color | |
| 610 { | |
| 611 unsigned a = SkGetPackedA32(fPMColor); | |
| 612 unsigned r = SkGetPackedR32(fPMColor); | |
| 613 unsigned g = SkGetPackedG32(fPMColor); | |
| 614 unsigned b = SkGetPackedB32(fPMColor); | |
| 615 for (int i = 0; i < count; i++) | |
| 616 { | |
| 617 if (alpha[i]) | |
| 618 { | |
| 619 unsigned mul = SkAlpha255To256(mulp[i]); | |
| 620 unsigned add = addp[i]; | |
| 621 | |
| 622 span[i] = SkPackARGB32( a, | |
| 623 SkFastMin32(SkAlphaMul(r, mul) + add
, a), | |
| 624 SkFastMin32(SkAlphaMul(g, mul) + add
, a), | |
| 625 SkFastMin32(SkAlphaMul(b, mul) + add
, a)); | |
| 626 } | |
| 627 else | |
| 628 span[i] = 0; | |
| 629 } | |
| 630 } | |
| 631 } | |
| 632 | |
| 633 virtual void beginSession() | |
| 634 { | |
| 635 this->INHERITED::beginSession(); | |
| 636 if (fProxy) | |
| 637 fProxy->beginSession(); | |
| 638 } | |
| 639 | |
| 640 virtual void endSession() | |
| 641 { | |
| 642 if (fProxy) | |
| 643 fProxy->endSession(); | |
| 644 this->INHERITED::endSession(); | |
| 645 } | |
| 646 | |
| 647 protected: | |
| 648 Sk3DShader(SkFlattenableReadBuffer& buffer) : | |
| 649 INHERITED(buffer) | |
| 650 { | |
| 651 fProxy = static_cast<SkShader*>(buffer.readFlattenable()); | |
| 652 fPMColor = buffer.readU32(); | |
| 653 fMask = NULL; | |
| 654 } | |
| 655 | |
| 656 virtual void flatten(SkFlattenableWriteBuffer& buffer) | |
| 657 { | |
| 658 this->INHERITED::flatten(buffer); | |
| 659 buffer.writeFlattenable(fProxy); | |
| 660 buffer.write32(fPMColor); | |
| 661 } | |
| 662 | |
| 663 virtual Factory getFactory() | |
| 664 { | |
| 665 return CreateProc; | |
| 666 } | |
| 667 | |
| 668 private: | |
| 669 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) | |
| 670 { | |
| 671 return SkNEW_ARGS(Sk3DShader, (buffer)); | |
| 672 } | |
| 673 | |
| 674 SkShader* fProxy; | |
| 675 SkPMColor fPMColor; | |
| 676 const SkMask* fMask; | |
| 677 | |
| 678 typedef SkShader INHERITED; | |
| 679 }; | |
| 680 | |
| 681 class Sk3DBlitter : public SkBlitter { | |
| 682 public: | |
| 683 Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*)) | |
| 684 : fProxy(proxy), f3DShader(shader), fKillProc(killProc) | |
| 685 { | |
| 686 shader->ref(); | |
| 687 } | |
| 688 virtual ~Sk3DBlitter() | |
| 689 { | |
| 690 f3DShader->unref(); | |
| 691 fKillProc(fProxy); | |
| 692 } | |
| 693 | |
| 694 virtual void blitH(int x, int y, int width) | |
| 695 { | |
| 696 fProxy->blitH(x, y, width); | |
| 697 } | |
| 698 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_
t runs[]) | |
| 699 { | |
| 700 fProxy->blitAntiH(x, y, antialias, runs); | |
| 701 } | |
| 702 virtual void blitV(int x, int y, int height, SkAlpha alpha) | |
| 703 { | |
| 704 fProxy->blitV(x, y, height, alpha); | |
| 705 } | |
| 706 virtual void blitRect(int x, int y, int width, int height) | |
| 707 { | |
| 708 fProxy->blitRect(x, y, width, height); | |
| 709 } | |
| 710 virtual void blitMask(const SkMask& mask, const SkIRect& clip) | |
| 711 { | |
| 712 if (mask.fFormat == SkMask::k3D_Format) | |
| 713 { | |
| 714 f3DShader->setMask(&mask); | |
| 715 | |
| 716 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; | |
| 717 fProxy->blitMask(mask, clip); | |
| 718 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; | |
| 719 | |
| 720 f3DShader->setMask(NULL); | |
| 721 } | |
| 722 else | |
| 723 fProxy->blitMask(mask, clip); | |
| 724 } | |
| 725 private: | |
| 726 SkBlitter* fProxy; | |
| 727 Sk3DShader* f3DShader; | |
| 728 void (*fKillProc)(void*); | |
| 729 }; | |
| 730 | |
| 731 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 732 ////////////////////////////////////////////////////////////////////////////////
/////// | |
| 733 | |
| 734 #include "SkCoreBlitters.h" | |
| 735 | |
| 736 class SkAutoRestoreShader { | |
| 737 public: | |
| 738 SkAutoRestoreShader(const SkPaint& p) : fPaint((SkPaint*)&p) | |
| 739 { | |
| 740 fShader = fPaint->getShader(); | |
| 741 fShader->safeRef(); | |
| 742 } | |
| 743 ~SkAutoRestoreShader() | |
| 744 { | |
| 745 fPaint->setShader(fShader); | |
| 746 fShader->safeUnref(); | |
| 747 } | |
| 748 private: | |
| 749 SkPaint* fPaint; | |
| 750 SkShader* fShader; | |
| 751 }; | |
| 752 | |
| 753 class SkAutoCallProc { | |
| 754 public: | |
| 755 typedef void (*Proc)(void*); | |
| 756 SkAutoCallProc(void* obj, Proc proc) | |
| 757 : fObj(obj), fProc(proc) | |
| 758 { | |
| 759 } | |
| 760 ~SkAutoCallProc() | |
| 761 { | |
| 762 if (fObj && fProc) | |
| 763 fProc(fObj); | |
| 764 } | |
| 765 void* get() const { return fObj; } | |
| 766 void* detach() | |
| 767 { | |
| 768 void* obj = fObj; | |
| 769 fObj = NULL; | |
| 770 return obj; | |
| 771 } | |
| 772 private: | |
| 773 void* fObj; | |
| 774 Proc fProc; | |
| 775 }; | |
| 776 | |
| 777 static void destroy_blitter(void* blitter) | |
| 778 { | |
| 779 ((SkBlitter*)blitter)->~SkBlitter(); | |
| 780 } | |
| 781 | |
| 782 static void delete_blitter(void* blitter) | |
| 783 { | |
| 784 SkDELETE((SkBlitter*)blitter); | |
| 785 } | |
| 786 | |
| 787 SkBlitter* SkBlitter::Choose(const SkBitmap& device, | |
| 788 const SkMatrix& matrix, | |
| 789 const SkPaint& paint, | |
| 790 void* storage, size_t storageSize) | |
| 791 { | |
| 792 SkASSERT(storageSize == 0 || storage != NULL); | |
| 793 | |
| 794 SkBlitter* blitter = NULL; | |
| 795 | |
| 796 // which check, in case we're being called by a client with a dummy device | |
| 797 // (e.g. they have a bounder that always aborts the draw) | |
| 798 if (SkBitmap::kNo_Config == device.getConfig()) | |
| 799 { | |
| 800 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); | |
| 801 return blitter; | |
| 802 } | |
| 803 | |
| 804 SkAutoRestoreShader restore(paint); | |
| 805 SkShader* shader = paint.getShader(); | |
| 806 | |
| 807 Sk3DShader* shader3D = NULL; | |
| 808 if (paint.getMaskFilter() != NULL && paint.getMaskFilter()->getFormat() == S
kMask::k3D_Format) | |
| 809 { | |
| 810 shader3D = SkNEW_ARGS(Sk3DShader, (shader)); | |
| 811 ((SkPaint*)&paint)->setShader(shader3D)->unref(); | |
| 812 shader = shader3D; | |
| 813 } | |
| 814 | |
| 815 SkXfermode* mode = paint.getXfermode(); | |
| 816 if (NULL == shader && (NULL != mode || paint.getColorFilter() != NULL)) | |
| 817 { | |
| 818 // xfermodes require shaders for our current set of blitters | |
| 819 shader = SkNEW(SkColorShader); | |
| 820 ((SkPaint*)&paint)->setShader(shader)->unref(); | |
| 821 } | |
| 822 | |
| 823 if (paint.getColorFilter() != NULL) | |
| 824 { | |
| 825 SkASSERT(shader); | |
| 826 shader = SkNEW_ARGS(SkFilterShader, (shader, paint.getColorFilter())); | |
| 827 ((SkPaint*)&paint)->setShader(shader)->unref(); | |
| 828 } | |
| 829 | |
| 830 bool doDither = paint.isDither(); | |
| 831 | |
| 832 if (shader) | |
| 833 { | |
| 834 if (!shader->setContext(device, paint, matrix)) | |
| 835 return SkNEW(SkNullBlitter); | |
| 836 | |
| 837 // disable dither if our shader is natively 16bit (no need to upsample) | |
| 838 if (shader->getFlags() & SkShader::kIntrinsicly16_Flag) | |
| 839 doDither = false; | |
| 840 } | |
| 841 | |
| 842 switch (device.getConfig()) { | |
| 843 case SkBitmap::kA1_Config: | |
| 844 SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter, storage, storageSize, (devi
ce, paint)); | |
| 845 break; | |
| 846 | |
| 847 case SkBitmap::kA8_Config: | |
| 848 if (shader) | |
| 849 SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter, storage, storage
Size, (device, paint)); | |
| 850 else | |
| 851 SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter, storage, storageSize, (
device, paint)); | |
| 852 break; | |
| 853 | |
| 854 case SkBitmap::kARGB_4444_Config: | |
| 855 blitter = SkBlitter_ChooseD4444(device, paint, storage, storageSize); | |
| 856 break; | |
| 857 | |
| 858 case SkBitmap::kRGB_565_Config: | |
| 859 if (shader) | |
| 860 { | |
| 861 if (mode) | |
| 862 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter,
storage, storageSize, (device, paint)); | |
| 863 else if (SkShader::CanCallShadeSpan16(shader->getFlags()) && !doDith
er) | |
| 864 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter, storage
, storageSize, (device, paint)); | |
| 865 else | |
| 866 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter, storage,
storageSize, (device, paint)); | |
| 867 } | |
| 868 else if (paint.getColor() == SK_ColorBLACK) | |
| 869 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage, stora
geSize, (device, paint)); | |
| 870 else | |
| 871 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage, storageSize
, (device, paint)); | |
| 872 break; | |
| 873 | |
| 874 case SkBitmap::kARGB_8888_Config: | |
| 875 if (shader) | |
| 876 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter, storage, sto
rageSize, (device, paint)); | |
| 877 else if (paint.getColor() == SK_ColorBLACK) | |
| 878 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter, storage, stor
ageSize, (device, paint)); | |
| 879 else if (paint.getAlpha() == 0xFF) | |
| 880 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter, storage, sto
rageSize, (device, paint)); | |
| 881 else | |
| 882 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter, storage, storageSiz
e, (device, paint)); | |
| 883 break; | |
| 884 | |
| 885 default: | |
| 886 SkASSERT(!"unsupported device config"); | |
| 887 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); | |
| 888 } | |
| 889 | |
| 890 if (shader3D) | |
| 891 { | |
| 892 void (*proc)(void*) = ((void*)storage == (void*)blitter) ? destroy_blitt
er : delete_blitter; | |
| 893 SkAutoCallProc tmp(blitter, proc); | |
| 894 | |
| 895 blitter = SkNEW_ARGS(Sk3DBlitter, (blitter, shader3D, proc)); | |
| 896 (void)tmp.detach(); | |
| 897 } | |
| 898 return blitter; | |
| 899 } | |
| 900 | |
| 901 ////////////////////////////////////////////////////////////////////////////////
////////////////////// | |
| 902 | |
| 903 const uint16_t gMask_0F0F = 0xF0F; | |
| 904 const uint32_t gMask_00FF00FF = 0xFF00FF; | |
| 905 | |
| 906 ////////////////////////////////////////////////////////////////////////////////
////////////////////// | |
| 907 | |
| 908 SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint) | |
| 909 : INHERITED(device) | |
| 910 { | |
| 911 fShader = paint.getShader(); | |
| 912 SkASSERT(fShader); | |
| 913 | |
| 914 fShader->ref(); | |
| 915 fShader->beginSession(); | |
| 916 } | |
| 917 | |
| 918 SkShaderBlitter::~SkShaderBlitter() | |
| 919 { | |
| 920 fShader->endSession(); | |
| 921 fShader->unref(); | |
| 922 } | |
| 923 | |
| OLD | NEW |