OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkImageFilter.h" | 8 #include "SkImageFilter.h" |
9 #include "SkImageFilterCacheKey.h" | 9 #include "SkImageFilterCacheKey.h" |
10 | 10 |
11 #include "SkBitmap.h" | 11 #include "SkBitmap.h" |
12 #include "SkBitmapDevice.h" | 12 #include "SkBitmapDevice.h" |
13 #include "SkChecksum.h" | 13 #include "SkChecksum.h" |
14 #include "SkDevice.h" | 14 #include "SkDevice.h" |
15 #include "SkLocalMatrixImageFilter.h" | 15 #include "SkLocalMatrixImageFilter.h" |
16 #include "SkMatrixImageFilter.h" | 16 #include "SkMatrixImageFilter.h" |
17 #include "SkOncePtr.h" | 17 #include "SkOncePtr.h" |
18 #include "SkReadBuffer.h" | 18 #include "SkReadBuffer.h" |
19 #include "SkRect.h" | 19 #include "SkRect.h" |
20 #include "SkSpecialImage.h" | 20 #include "SkSpecialImage.h" |
| 21 #include "SkSpecialSurface.h" |
21 #include "SkTDynamicHash.h" | 22 #include "SkTDynamicHash.h" |
22 #include "SkTInternalLList.h" | 23 #include "SkTInternalLList.h" |
23 #include "SkValidationUtils.h" | 24 #include "SkValidationUtils.h" |
24 #include "SkWriteBuffer.h" | 25 #include "SkWriteBuffer.h" |
25 #if SK_SUPPORT_GPU | 26 #if SK_SUPPORT_GPU |
26 #include "GrContext.h" | 27 #include "GrContext.h" |
27 #include "GrDrawContext.h" | 28 #include "GrDrawContext.h" |
28 #include "SkGrPixelRef.h" | 29 #include "SkGrPixelRef.h" |
29 #include "SkGr.h" | 30 #include "SkGr.h" |
30 #endif | 31 #endif |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 SkImageFilter* input = this->getInput(i); | 207 SkImageFilter* input = this->getInput(i); |
207 buffer.writeBool(input != nullptr); | 208 buffer.writeBool(input != nullptr); |
208 if (input != nullptr) { | 209 if (input != nullptr) { |
209 buffer.writeFlattenable(input); | 210 buffer.writeFlattenable(input); |
210 } | 211 } |
211 } | 212 } |
212 buffer.writeRect(fCropRect.rect()); | 213 buffer.writeRect(fCropRect.rect()); |
213 buffer.writeUInt(fCropRect.flags()); | 214 buffer.writeUInt(fCropRect.flags()); |
214 } | 215 } |
215 | 216 |
| 217 SkSpecialImage* SkImageFilter::filterImage(SkSpecialImage* src, const Context& c
ontext, |
| 218 SkIPoint* offset) const { |
| 219 SkASSERT(src && offset); |
| 220 |
| 221 uint32_t srcGenID = fUsesSrcInput ? src->uniqueID() : 0; |
| 222 const SkIRect srcSubset = fUsesSrcInput ? src->subset() : SkIRect::MakeWH(0,
0); |
| 223 Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), srcGenID, src
Subset); |
| 224 if (context.cache()) { |
| 225 SkSpecialImage* result = context.cache()->get(key, offset); |
| 226 if (result) { |
| 227 return SkRef(result); |
| 228 } |
| 229 } |
| 230 |
| 231 SkSpecialImage* result = this->onFilterImage(src, context, offset); |
| 232 if (result && context.cache()) { |
| 233 context.cache()->set(key, result, *offset); |
| 234 } |
| 235 |
| 236 return result; |
| 237 } |
| 238 |
216 bool SkImageFilter::filterImageDeprecated(Proxy* proxy, const SkBitmap& src, | 239 bool SkImageFilter::filterImageDeprecated(Proxy* proxy, const SkBitmap& src, |
217 const Context& context, | 240 const Context& context, |
218 SkBitmap* result, SkIPoint* offset) co
nst { | 241 SkBitmap* result, SkIPoint* offset) co
nst { |
219 SkASSERT(result); | 242 SkASSERT(result); |
220 SkASSERT(offset); | 243 SkASSERT(offset); |
221 uint32_t srcGenID = fUsesSrcInput ? src.getGenerationID() : 0; | 244 uint32_t srcGenID = fUsesSrcInput ? src.getGenerationID() : 0; |
222 Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), | 245 Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), |
223 srcGenID, SkIRect::MakeWH(0, 0)); | 246 srcGenID, SkIRect::MakeWH(0, 0)); |
224 if (context.cache()) { | 247 if (context.cache()) { |
225 if (context.cache()->get(key, result, offset)) { | 248 if (context.cache()->get(key, result, offset)) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 } | 323 } |
301 } | 324 } |
302 return true; | 325 return true; |
303 } | 326 } |
304 | 327 |
305 bool SkImageFilter::onFilterImageDeprecated(Proxy*, const SkBitmap&, const Conte
xt&, | 328 bool SkImageFilter::onFilterImageDeprecated(Proxy*, const SkBitmap&, const Conte
xt&, |
306 SkBitmap*, SkIPoint*) const { | 329 SkBitmap*, SkIPoint*) const { |
307 return false; | 330 return false; |
308 } | 331 } |
309 | 332 |
| 333 SkSpecialImage* SkImageFilter::onFilterImage(SkSpecialImage* src, const Context&
ctx, |
| 334 SkIPoint* offset) const { |
| 335 SkBitmap srcBM, resultBM; |
| 336 |
| 337 if (!src->internal_getBM(&srcBM)) { |
| 338 return nullptr; |
| 339 } |
| 340 |
| 341 if (!this->filterImageDeprecated(src->internal_getProxy(), srcBM, ctx, &resu
ltBM, offset)) { |
| 342 return nullptr; |
| 343 } |
| 344 |
| 345 return SkSpecialImage::internal_fromBM(src->internal_getProxy(), resultBM); |
| 346 } |
| 347 |
310 bool SkImageFilter::canFilterImageGPU() const { | 348 bool SkImageFilter::canFilterImageGPU() const { |
311 return this->asFragmentProcessor(nullptr, nullptr, SkMatrix::I(), SkIRect())
; | 349 return this->asFragmentProcessor(nullptr, nullptr, SkMatrix::I(), SkIRect())
; |
312 } | 350 } |
313 | 351 |
314 bool SkImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src,
const Context& ctx, | 352 bool SkImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src,
const Context& ctx, |
315 SkBitmap* result, SkIPoint* offset)
const { | 353 SkBitmap* result, SkIPoint* offset)
const { |
316 #if SK_SUPPORT_GPU | 354 #if SK_SUPPORT_GPU |
317 SkBitmap input = src; | 355 SkBitmap input = src; |
318 SkASSERT(fInputCount == 1); | 356 SkASSERT(fInputCount == 1); |
319 SkIPoint srcOffset = SkIPoint::Make(0, 0); | 357 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 } | 450 } |
413 SkCanvas canvas(device); | 451 SkCanvas canvas(device); |
414 canvas.clear(0x00000000); | 452 canvas.clear(0x00000000); |
415 canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bo
unds->y()); | 453 canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bo
unds->y()); |
416 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); | 454 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); |
417 *dst = device->accessBitmap(false); | 455 *dst = device->accessBitmap(false); |
418 return true; | 456 return true; |
419 } | 457 } |
420 } | 458 } |
421 | 459 |
| 460 // Return a larger (newWidth x newHeight) copy of 'src' with black padding |
| 461 // around it. |
| 462 static SkSpecialImage* pad_image(SkSpecialImage* src, |
| 463 int newWidth, int newHeight, int offX, int offY
) { |
| 464 |
| 465 SkImageInfo info = SkImageInfo::MakeN32Premul(newWidth, newHeight); |
| 466 SkAutoTUnref<SkSpecialSurface> surf(src->newSurface(info)); |
| 467 if (!surf) { |
| 468 return nullptr; |
| 469 } |
| 470 |
| 471 SkCanvas* canvas = surf->getCanvas(); |
| 472 SkASSERT(canvas); |
| 473 |
| 474 canvas->clear(0x0); |
| 475 |
| 476 src->draw(canvas, offX, offY, nullptr); |
| 477 |
| 478 return surf->newImageSnapshot(); |
| 479 } |
| 480 |
| 481 SkSpecialImage* SkImageFilter::applyCropRect(const Context& ctx, |
| 482 SkSpecialImage* src, |
| 483 SkIPoint* srcOffset, |
| 484 SkIRect* bounds) const { |
| 485 SkIRect srcBounds; |
| 486 srcBounds = SkIRect::MakeXYWH(srcOffset->fX, srcOffset->fY, src->width(), sr
c->height()); |
| 487 |
| 488 SkIRect dstBounds; |
| 489 this->onFilterNodeBounds(srcBounds, ctx.ctm(), &dstBounds, kForward_MapDirec
tion); |
| 490 fCropRect.applyTo(dstBounds, ctx.ctm(), bounds); |
| 491 if (!bounds->intersect(ctx.clipBounds())) { |
| 492 return nullptr; |
| 493 } |
| 494 |
| 495 if (srcBounds.contains(*bounds)) { |
| 496 return SkRef(src); |
| 497 } else { |
| 498 SkSpecialImage* img = pad_image(src, |
| 499 bounds->width(), bounds->height(), |
| 500 srcOffset->x() - bounds->x(), |
| 501 srcOffset->y() - bounds->y()); |
| 502 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); |
| 503 return img; |
| 504 } |
| 505 } |
| 506 |
422 bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, | 507 bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, |
423 SkIRect* dst, MapDirection direction) const { | 508 SkIRect* dst, MapDirection direction) const { |
424 if (fInputCount < 1) { | 509 if (fInputCount < 1) { |
425 *dst = src; | 510 *dst = src; |
426 return true; | 511 return true; |
427 } | 512 } |
428 | 513 |
429 SkIRect totalBounds; | 514 SkIRect totalBounds; |
430 for (int i = 0; i < fInputCount; ++i) { | 515 for (int i = 0; i < fInputCount; ++i) { |
431 SkImageFilter* filter = this->getInput(i); | 516 SkImageFilter* filter = this->getInput(i); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 return SkMatrixImageFilter::Create(matrix, filterQuality, input); | 555 return SkMatrixImageFilter::Create(matrix, filterQuality, input); |
471 } | 556 } |
472 | 557 |
473 SkImageFilter* SkImageFilter::newWithLocalMatrix(const SkMatrix& matrix) const { | 558 SkImageFilter* SkImageFilter::newWithLocalMatrix(const SkMatrix& matrix) const { |
474 // SkLocalMatrixImageFilter takes SkImage* in its factory, but logically tha
t parameter | 559 // SkLocalMatrixImageFilter takes SkImage* in its factory, but logically tha
t parameter |
475 // is *always* treated as a const ptr. Hence the const-cast here. | 560 // is *always* treated as a const ptr. Hence the const-cast here. |
476 // | 561 // |
477 return SkLocalMatrixImageFilter::Create(matrix, const_cast<SkImageFilter*>(t
his)); | 562 return SkLocalMatrixImageFilter::Create(matrix, const_cast<SkImageFilter*>(t
his)); |
478 } | 563 } |
479 | 564 |
| 565 SkSpecialImage* SkImageFilter::filterInput(int index, |
| 566 SkSpecialImage* src, |
| 567 const Context& ctx, |
| 568 SkIPoint* offset) const { |
| 569 SkImageFilter* input = this->getInput(index); |
| 570 if (!input) { |
| 571 return SkRef(src); |
| 572 } |
| 573 |
| 574 return input->filterImage(src, this->mapContext(ctx), offset); |
| 575 } |
| 576 |
480 #if SK_SUPPORT_GPU | 577 #if SK_SUPPORT_GPU |
481 | 578 |
482 bool SkImageFilter::filterInputGPUDeprecated(int index, SkImageFilter::Proxy* pr
oxy, | 579 bool SkImageFilter::filterInputGPUDeprecated(int index, SkImageFilter::Proxy* pr
oxy, |
483 const SkBitmap& src, const Context&
ctx, | 580 const SkBitmap& src, const Context&
ctx, |
484 SkBitmap* result, SkIPoint* offset)
const { | 581 SkBitmap* result, SkIPoint* offset)
const { |
485 SkImageFilter* input = this->getInput(index); | 582 SkImageFilter* input = this->getInput(index); |
486 if (!input) { | 583 if (!input) { |
487 return true; | 584 return true; |
488 } | 585 } |
489 // Ensure that GrContext calls under filterImage and filterImageGPU below wi
ll see an identity | 586 // Ensure that GrContext calls under filterImage and filterImageGPU below wi
ll see an identity |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 } | 774 } |
678 return dev; | 775 return dev; |
679 } | 776 } |
680 | 777 |
681 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, | 778 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, |
682 const SkImageFilter::Context& ctx, | 779 const SkImageFilter::Context& ctx, |
683 SkBitmap* result, SkIPoint* offset) { | 780 SkBitmap* result, SkIPoint* offset) { |
684 return fDevice->filterImage(filter, src, ctx, result, offset); | 781 return fDevice->filterImage(filter, src, ctx, result, offset); |
685 } | 782 } |
686 | 783 |
OLD | NEW |