| 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 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 SkImageFilter* input = this->getInput(i); | 207 SkImageFilter* input = this->getInput(i); |
| 208 buffer.writeBool(input != nullptr); | 208 buffer.writeBool(input != nullptr); |
| 209 if (input != nullptr) { | 209 if (input != nullptr) { |
| 210 buffer.writeFlattenable(input); | 210 buffer.writeFlattenable(input); |
| 211 } | 211 } |
| 212 } | 212 } |
| 213 buffer.writeRect(fCropRect.rect()); | 213 buffer.writeRect(fCropRect.rect()); |
| 214 buffer.writeUInt(fCropRect.flags()); | 214 buffer.writeUInt(fCropRect.flags()); |
| 215 } | 215 } |
| 216 | 216 |
| 217 SkSpecialImage* SkImageFilter::filterImage(SkSpecialImage* src, const Context& c
ontext, | 217 sk_sp<SkSpecialImage> SkImageFilter::filterImage(SkSpecialImage* src, const Cont
ext& context, |
| 218 SkIPoint* offset) const { | 218 SkIPoint* offset) const { |
| 219 SkASSERT(src && offset); | 219 SkASSERT(src && offset); |
| 220 | 220 |
| 221 uint32_t srcGenID = fUsesSrcInput ? src->uniqueID() : 0; | 221 uint32_t srcGenID = fUsesSrcInput ? src->uniqueID() : 0; |
| 222 const SkIRect srcSubset = fUsesSrcInput ? src->subset() : SkIRect::MakeWH(0,
0); | 222 const SkIRect srcSubset = fUsesSrcInput ? src->subset() : SkIRect::MakeWH(0,
0); |
| 223 Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), srcGenID, src
Subset); | 223 Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), srcGenID, src
Subset); |
| 224 if (context.cache()) { | 224 if (context.cache()) { |
| 225 SkSpecialImage* result = context.cache()->get(key, offset); | 225 SkSpecialImage* result = context.cache()->get(key, offset); |
| 226 if (result) { | 226 if (result) { |
| 227 return SkRef(result); | 227 return sk_sp<SkSpecialImage>(SkRef(result)); |
| 228 } | 228 } |
| 229 } | 229 } |
| 230 | 230 |
| 231 SkSpecialImage* result = this->onFilterImage(src, context, offset); | 231 sk_sp<SkSpecialImage> result(this->onFilterImage(src, context, offset)); |
| 232 if (result && context.cache()) { | 232 if (result && context.cache()) { |
| 233 context.cache()->set(key, result, *offset); | 233 context.cache()->set(key, result.get(), *offset); |
| 234 SkAutoMutexAcquire mutex(fMutex); | 234 SkAutoMutexAcquire mutex(fMutex); |
| 235 fCacheKeys.push_back(key); | 235 fCacheKeys.push_back(key); |
| 236 } | 236 } |
| 237 | 237 |
| 238 return result; | 238 return result; |
| 239 } | 239 } |
| 240 | 240 |
| 241 bool SkImageFilter::filterImageDeprecated(Proxy* proxy, const SkBitmap& src, | 241 bool SkImageFilter::filterImageDeprecated(Proxy* proxy, const SkBitmap& src, |
| 242 const Context& context, | 242 const Context& context, |
| 243 SkBitmap* result, SkIPoint* offset) co
nst { | 243 SkBitmap* result, SkIPoint* offset) co
nst { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 273 SkImageFilter* input = this->getInput(index); | 273 SkImageFilter* input = this->getInput(index); |
| 274 if (!input) { | 274 if (!input) { |
| 275 return true; | 275 return true; |
| 276 } | 276 } |
| 277 | 277 |
| 278 sk_sp<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src)
); | 278 sk_sp<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src)
); |
| 279 if (!specialSrc) { | 279 if (!specialSrc) { |
| 280 return false; | 280 return false; |
| 281 } | 281 } |
| 282 | 282 |
| 283 SkAutoTUnref<SkSpecialImage> tmp(input->onFilterImage(specialSrc.get(), | 283 sk_sp<SkSpecialImage> tmp(input->onFilterImage(specialSrc.get(), |
| 284 this->mapContext(ctx), | 284 this->mapContext(ctx), |
| 285 offset)); | 285 offset)); |
| 286 if (!tmp) { | 286 if (!tmp) { |
| 287 return false; | 287 return false; |
| 288 } | 288 } |
| 289 | 289 |
| 290 return tmp->internal_getBM(result); | 290 return tmp->internal_getBM(result); |
| 291 } | 291 } |
| 292 | 292 |
| 293 SkIRect SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, | 293 SkIRect SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, |
| 294 MapDirection direction) const { | 294 MapDirection direction) const { |
| 295 if (kReverse_MapDirection == direction) { | 295 if (kReverse_MapDirection == direction) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 SkBitmap*, SkIPoint*) const { | 334 SkBitmap*, SkIPoint*) const { |
| 335 // Only classes that now use the new SkSpecialImage-based path will not have | 335 // Only classes that now use the new SkSpecialImage-based path will not have |
| 336 // onFilterImageDeprecated methods. For those classes we should never be | 336 // onFilterImageDeprecated methods. For those classes we should never be |
| 337 // calling this method. | 337 // calling this method. |
| 338 SkASSERT(0); | 338 SkASSERT(0); |
| 339 return false; | 339 return false; |
| 340 } | 340 } |
| 341 | 341 |
| 342 // SkImageFilter-derived classes that do not yet have their own onFilterImage | 342 // SkImageFilter-derived classes that do not yet have their own onFilterImage |
| 343 // implementation convert back to calling the deprecated filterImage method | 343 // implementation convert back to calling the deprecated filterImage method |
| 344 SkSpecialImage* SkImageFilter::onFilterImage(SkSpecialImage* src, const Context&
ctx, | 344 sk_sp<SkSpecialImage> SkImageFilter::onFilterImage(SkSpecialImage* src, const Co
ntext& ctx, |
| 345 SkIPoint* offset) const { | 345 SkIPoint* offset) const { |
| 346 SkBitmap srcBM, resultBM; | 346 SkBitmap srcBM, resultBM; |
| 347 | 347 |
| 348 if (!src->internal_getBM(&srcBM)) { | 348 if (!src->internal_getBM(&srcBM)) { |
| 349 return nullptr; | 349 return nullptr; |
| 350 } | 350 } |
| 351 | 351 |
| 352 // This is the only valid call to the old filterImage path | 352 // This is the only valid call to the old filterImage path |
| 353 if (!this->filterImageDeprecated(src->internal_getProxy(), srcBM, ctx, &resu
ltBM, offset)) { | 353 if (!this->filterImageDeprecated(src->internal_getProxy(), srcBM, ctx, &resu
ltBM, offset)) { |
| 354 return nullptr; | 354 return nullptr; |
| 355 } | 355 } |
| 356 | 356 |
| 357 return SkSpecialImage::internal_fromBM(src->internal_getProxy(), resultBM).r
elease(); | 357 return SkSpecialImage::internal_fromBM(src->internal_getProxy(), resultBM); |
| 358 } | 358 } |
| 359 | 359 |
| 360 bool SkImageFilter::canFilterImageGPU() const { | 360 bool SkImageFilter::canFilterImageGPU() const { |
| 361 return this->asFragmentProcessor(nullptr, nullptr, SkMatrix::I(), SkIRect())
; | 361 return this->asFragmentProcessor(nullptr, nullptr, SkMatrix::I(), SkIRect())
; |
| 362 } | 362 } |
| 363 | 363 |
| 364 bool SkImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src,
const Context& ctx, | 364 bool SkImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src,
const Context& ctx, |
| 365 SkBitmap* result, SkIPoint* offset)
const { | 365 SkBitmap* result, SkIPoint* offset)
const { |
| 366 #if SK_SUPPORT_GPU | 366 #if SK_SUPPORT_GPU |
| 367 SkBitmap input = src; | 367 SkBitmap input = src; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 SkCanvas* canvas = surf->getCanvas(); | 482 SkCanvas* canvas = surf->getCanvas(); |
| 483 SkASSERT(canvas); | 483 SkASSERT(canvas); |
| 484 | 484 |
| 485 canvas->clear(0x0); | 485 canvas->clear(0x0); |
| 486 | 486 |
| 487 src->draw(canvas, offX, offY, nullptr); | 487 src->draw(canvas, offX, offY, nullptr); |
| 488 | 488 |
| 489 return surf->makeImageSnapshot(); | 489 return surf->makeImageSnapshot(); |
| 490 } | 490 } |
| 491 | 491 |
| 492 SkSpecialImage* SkImageFilter::applyCropRect(const Context& ctx, | 492 sk_sp<SkSpecialImage> SkImageFilter::applyCropRect(const Context& ctx, |
| 493 SkSpecialImage* src, | 493 SkSpecialImage* src, |
| 494 SkIPoint* srcOffset, | 494 SkIPoint* srcOffset, |
| 495 SkIRect* bounds) const { | 495 SkIRect* bounds) const { |
| 496 SkIRect srcBounds; | 496 SkIRect srcBounds; |
| 497 srcBounds = SkIRect::MakeXYWH(srcOffset->fX, srcOffset->fY, src->width(), sr
c->height()); | 497 srcBounds = SkIRect::MakeXYWH(srcOffset->fX, srcOffset->fY, src->width(), sr
c->height()); |
| 498 | 498 |
| 499 SkIRect dstBounds = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_
MapDirection); | 499 SkIRect dstBounds = this->onFilterNodeBounds(srcBounds, ctx.ctm(), kForward_
MapDirection); |
| 500 fCropRect.applyTo(dstBounds, ctx.ctm(), bounds); | 500 fCropRect.applyTo(dstBounds, ctx.ctm(), bounds); |
| 501 if (!bounds->intersect(ctx.clipBounds())) { | 501 if (!bounds->intersect(ctx.clipBounds())) { |
| 502 return nullptr; | 502 return nullptr; |
| 503 } | 503 } |
| 504 | 504 |
| 505 if (srcBounds.contains(*bounds)) { | 505 if (srcBounds.contains(*bounds)) { |
| 506 return SkRef(src); | 506 return sk_sp<SkSpecialImage>(SkRef(src)); |
| 507 } else { | 507 } else { |
| 508 sk_sp<SkSpecialImage> img(pad_image(src, | 508 sk_sp<SkSpecialImage> img(pad_image(src, |
| 509 bounds->width(), bounds->height(), | 509 bounds->width(), bounds->height(), |
| 510 srcOffset->x() - bounds->x(), | 510 srcOffset->x() - bounds->x(), |
| 511 srcOffset->y() - bounds->y())); | 511 srcOffset->y() - bounds->y())); |
| 512 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); | 512 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); |
| 513 return img.release(); | 513 return img; |
| 514 } | 514 } |
| 515 } | 515 } |
| 516 | 516 |
| 517 SkIRect SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, | 517 SkIRect SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, |
| 518 MapDirection direction) const { | 518 MapDirection direction) const { |
| 519 if (fInputCount < 1) { | 519 if (fInputCount < 1) { |
| 520 return src; | 520 return src; |
| 521 } | 521 } |
| 522 | 522 |
| 523 SkIRect totalBounds; | 523 SkIRect totalBounds; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 return SkMatrixImageFilter::Create(matrix, filterQuality, input); | 556 return SkMatrixImageFilter::Create(matrix, filterQuality, input); |
| 557 } | 557 } |
| 558 | 558 |
| 559 SkImageFilter* SkImageFilter::newWithLocalMatrix(const SkMatrix& matrix) const { | 559 SkImageFilter* SkImageFilter::newWithLocalMatrix(const SkMatrix& matrix) const { |
| 560 // SkLocalMatrixImageFilter takes SkImage* in its factory, but logically tha
t parameter | 560 // SkLocalMatrixImageFilter takes SkImage* in its factory, but logically tha
t parameter |
| 561 // is *always* treated as a const ptr. Hence the const-cast here. | 561 // is *always* treated as a const ptr. Hence the const-cast here. |
| 562 // | 562 // |
| 563 return SkLocalMatrixImageFilter::Create(matrix, const_cast<SkImageFilter*>(t
his)); | 563 return SkLocalMatrixImageFilter::Create(matrix, const_cast<SkImageFilter*>(t
his)); |
| 564 } | 564 } |
| 565 | 565 |
| 566 SkSpecialImage* SkImageFilter::filterInput(int index, | 566 sk_sp<SkSpecialImage> SkImageFilter::filterInput(int index, |
| 567 SkSpecialImage* src, | 567 SkSpecialImage* src, |
| 568 const Context& ctx, | 568 const Context& ctx, |
| 569 SkIPoint* offset) const { | 569 SkIPoint* offset) const { |
| 570 SkImageFilter* input = this->getInput(index); | 570 SkImageFilter* input = this->getInput(index); |
| 571 if (!input) { | 571 if (!input) { |
| 572 return SkRef(src); | 572 return sk_sp<SkSpecialImage>(SkRef(src)); |
| 573 } | 573 } |
| 574 | 574 |
| 575 SkAutoTUnref<SkSpecialImage> result(input->filterImage(src, this->mapContext
(ctx), offset)); | 575 sk_sp<SkSpecialImage> result(input->filterImage(src, this->mapContext(ctx),
offset)); |
| 576 | 576 |
| 577 #if SK_SUPPORT_GPU | 577 #if SK_SUPPORT_GPU |
| 578 if (src->peekTexture() && result && !result->peekTexture()) { | 578 if (src->peekTexture() && result && !result->peekTexture()) { |
| 579 // Keep the result on the GPU - this is still required for some | 579 // Keep the result on the GPU - this is still required for some |
| 580 // image filters that don't support GPU in all cases | 580 // image filters that don't support GPU in all cases |
| 581 GrContext* context = src->peekTexture()->getContext(); | 581 GrContext* context = src->peekTexture()->getContext(); |
| 582 return result->makeTextureImage(src->internal_getProxy(), context).relea
se(); | 582 return result->makeTextureImage(src->internal_getProxy(), context); |
| 583 } | 583 } |
| 584 #endif | 584 #endif |
| 585 | 585 |
| 586 return result.release(); | 586 return result; |
| 587 } | 587 } |
| 588 | 588 |
| 589 #if SK_SUPPORT_GPU | 589 #if SK_SUPPORT_GPU |
| 590 | 590 |
| 591 bool SkImageFilter::filterInputGPUDeprecated(int index, SkImageFilter::Proxy* pr
oxy, | 591 bool SkImageFilter::filterInputGPUDeprecated(int index, SkImageFilter::Proxy* pr
oxy, |
| 592 const SkBitmap& src, const Context&
ctx, | 592 const SkBitmap& src, const Context&
ctx, |
| 593 SkBitmap* result, SkIPoint* offset)
const { | 593 SkBitmap* result, SkIPoint* offset)
const { |
| 594 SkImageFilter* input = this->getInput(index); | 594 SkImageFilter* input = this->getInput(index); |
| 595 if (!input) { | 595 if (!input) { |
| 596 return true; | 596 return true; |
| 597 } | 597 } |
| 598 | 598 |
| 599 sk_sp<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src)
); | 599 sk_sp<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src)
); |
| 600 if (!specialSrc) { | 600 if (!specialSrc) { |
| 601 return false; | 601 return false; |
| 602 } | 602 } |
| 603 | 603 |
| 604 SkAutoTUnref<SkSpecialImage> tmp(input->onFilterImage(specialSrc.get(), | 604 sk_sp<SkSpecialImage> tmp(input->onFilterImage(specialSrc.get(), |
| 605 this->mapContext(ctx), | 605 this->mapContext(ctx), |
| 606 offset)); | 606 offset)); |
| 607 if (!tmp) { | 607 if (!tmp) { |
| 608 return false; | 608 return false; |
| 609 } | 609 } |
| 610 | 610 |
| 611 if (!tmp->internal_getBM(result)) { | 611 if (!tmp->internal_getBM(result)) { |
| 612 return false; | 612 return false; |
| 613 } | 613 } |
| 614 | 614 |
| 615 if (!result->getTexture()) { | 615 if (!result->getTexture()) { |
| 616 GrContext* context = src.getTexture()->getContext(); | 616 GrContext* context = src.getTexture()->getContext(); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 } | 798 } |
| 799 return dev; | 799 return dev; |
| 800 } | 800 } |
| 801 | 801 |
| 802 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, | 802 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, |
| 803 const SkImageFilter::Context& ctx, | 803 const SkImageFilter::Context& ctx, |
| 804 SkBitmap* result, SkIPoint* offset) { | 804 SkBitmap* result, SkIPoint* offset) { |
| 805 return fDevice->filterImage(filter, src, ctx, result, offset); | 805 return fDevice->filterImage(filter, src, ctx, result, offset); |
| 806 } | 806 } |
| 807 | 807 |
| OLD | NEW |