| 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 "SkMorphologyImageFilter.h" | 8 #include "SkMorphologyImageFilter.h" |
| 9 | 9 |
| 10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 , fRadius(SkISize::Make(radiusX, radiusY)) { | 36 , fRadius(SkISize::Make(radiusX, radiusY)) { |
| 37 } | 37 } |
| 38 | 38 |
| 39 void SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const { | 39 void SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const { |
| 40 this->INHERITED::flatten(buffer); | 40 this->INHERITED::flatten(buffer); |
| 41 buffer.writeInt(fRadius.fWidth); | 41 buffer.writeInt(fRadius.fWidth); |
| 42 buffer.writeInt(fRadius.fHeight); | 42 buffer.writeInt(fRadius.fHeight); |
| 43 } | 43 } |
| 44 | 44 |
| 45 static void call_proc_X(SkMorphologyImageFilter::Proc procX, | 45 static void call_proc_X(SkMorphologyImageFilter::Proc procX, |
| 46 const SkPixmap& src, SkBitmap* dst, | 46 const SkBitmap& src, SkBitmap* dst, |
| 47 int radiusX, const SkIRect& bounds) { | 47 int radiusX, const SkIRect& bounds) { |
| 48 procX(src.addr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), | 48 procX(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), |
| 49 radiusX, bounds.width(), bounds.height(), | 49 radiusX, bounds.width(), bounds.height(), |
| 50 src.rowBytesAsPixels(), dst->rowBytesAsPixels()); | 50 src.rowBytesAsPixels(), dst->rowBytesAsPixels()); |
| 51 } | 51 } |
| 52 | 52 |
| 53 static void call_proc_Y(SkMorphologyImageFilter::Proc procY, | 53 static void call_proc_Y(SkMorphologyImageFilter::Proc procY, |
| 54 const SkPMColor* src, int srcRowBytesAsPixels, SkBitmap*
dst, | 54 const SkPMColor* src, int srcRowBytesAsPixels, SkBitmap*
dst, |
| 55 int radiusY, const SkIRect& bounds) { | 55 int radiusY, const SkIRect& bounds) { |
| 56 procY(src, dst->getAddr32(0, 0), | 56 procY(src, dst->getAddr32(0, 0), |
| 57 radiusY, bounds.height(), bounds.width(), | 57 radiusY, bounds.height(), bounds.width(), |
| 58 srcRowBytesAsPixels, dst->rowBytesAsPixels()); | 58 srcRowBytesAsPixels, dst->rowBytesAsPixels()); |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 // Draw upper and lower margins with bounds; middle without. | 439 // Draw upper and lower margins with bounds; middle without. |
| 440 apply_morphology_rect(drawContext, clip, texture, lowerSrcRect, lowerDst
Rect, radius, | 440 apply_morphology_rect(drawContext, clip, texture, lowerSrcRect, lowerDst
Rect, radius, |
| 441 morphType, bounds, direction); | 441 morphType, bounds, direction); |
| 442 apply_morphology_rect(drawContext, clip, texture, upperSrcRect, upperDst
Rect, radius, | 442 apply_morphology_rect(drawContext, clip, texture, upperSrcRect, upperDst
Rect, radius, |
| 443 morphType, bounds, direction); | 443 morphType, bounds, direction); |
| 444 apply_morphology_rect_no_bounds(drawContext, clip, texture, middleSrcRec
t, middleDstRect, | 444 apply_morphology_rect_no_bounds(drawContext, clip, texture, middleSrcRec
t, middleDstRect, |
| 445 radius, morphType, direction); | 445 radius, morphType, direction); |
| 446 } | 446 } |
| 447 } | 447 } |
| 448 | 448 |
| 449 static sk_sp<SkSpecialImage> apply_morphology(SkSpecialImage* input, | 449 static sk_sp<SkSpecialImage> apply_morphology(GrContext* context, |
| 450 SkSpecialImage* input, |
| 450 const SkIRect& rect, | 451 const SkIRect& rect, |
| 451 GrMorphologyEffect::MorphologyType
morphType, | 452 GrMorphologyEffect::MorphologyType
morphType, |
| 452 SkISize radius) { | 453 SkISize radius) { |
| 453 SkAutoTUnref<GrTexture> srcTexture(SkRef(input->peekTexture())); | 454 SkAutoTUnref<GrTexture> srcTexture(input->asTextureRef(context)); |
| 454 SkASSERT(srcTexture); | 455 SkASSERT(srcTexture); |
| 455 GrContext* context = srcTexture->getContext(); | |
| 456 | 456 |
| 457 // setup new clip | 457 // setup new clip |
| 458 GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()), | 458 GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()), |
| 459 SkIntToScalar(srcTexture->height()))); | 459 SkIntToScalar(srcTexture->height()))); |
| 460 | 460 |
| 461 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); | 461 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); |
| 462 GrSurfaceDesc desc; | 462 GrSurfaceDesc desc; |
| 463 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 463 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 464 desc.fWidth = rect.width(); | 464 desc.fWidth = rect.width(); |
| 465 desc.fHeight = rect.height(); | 465 desc.fHeight = rect.height(); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 SkIRect srcBounds = bounds; | 545 SkIRect srcBounds = bounds; |
| 546 srcBounds.offset(-inputOffset); | 546 srcBounds.offset(-inputOffset); |
| 547 | 547 |
| 548 if (0 == width && 0 == height) { | 548 if (0 == width && 0 == height) { |
| 549 offset->fX = bounds.left(); | 549 offset->fX = bounds.left(); |
| 550 offset->fY = bounds.top(); | 550 offset->fY = bounds.top(); |
| 551 return input->makeSubset(srcBounds); | 551 return input->makeSubset(srcBounds); |
| 552 } | 552 } |
| 553 | 553 |
| 554 #if SK_SUPPORT_GPU | 554 #if SK_SUPPORT_GPU |
| 555 if (input->peekTexture() && input->peekTexture()->getContext()) { | 555 if (source->isTextureBacked()) { |
| 556 GrContext* context = source->getContext(); |
| 557 |
| 556 auto type = (kDilate_Op == this->op()) ? GrMorphologyEffect::kDilate_Mor
phologyType | 558 auto type = (kDilate_Op == this->op()) ? GrMorphologyEffect::kDilate_Mor
phologyType |
| 557 : GrMorphologyEffect::kErode_Morp
hologyType; | 559 : GrMorphologyEffect::kErode_Morp
hologyType; |
| 558 sk_sp<SkSpecialImage> result(apply_morphology(input.get(), srcBounds, ty
pe, | 560 sk_sp<SkSpecialImage> result(apply_morphology(context, input.get(), srcB
ounds, type, |
| 559 SkISize::Make(width, heigh
t))); | 561 SkISize::Make(width, heigh
t))); |
| 560 if (result) { | 562 if (result) { |
| 561 offset->fX = bounds.left(); | 563 offset->fX = bounds.left(); |
| 562 offset->fY = bounds.top(); | 564 offset->fY = bounds.top(); |
| 563 } | 565 } |
| 564 return result; | 566 return result; |
| 565 } | 567 } |
| 566 #endif | 568 #endif |
| 567 | 569 |
| 568 SkPixmap inputPixmap; | 570 SkBitmap inputBM; |
| 569 | 571 |
| 570 if (!input->peekPixels(&inputPixmap)) { | 572 if (!input->getROPixels(&inputBM)) { |
| 571 return nullptr; | 573 return nullptr; |
| 572 } | 574 } |
| 573 | 575 |
| 574 if (inputPixmap.colorType() != kN32_SkColorType) { | 576 if (inputBM.colorType() != kN32_SkColorType) { |
| 575 return nullptr; | 577 return nullptr; |
| 576 } | 578 } |
| 577 | 579 |
| 578 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), | 580 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), |
| 579 inputPixmap.colorType(), inputPixmap.al
phaType()); | 581 inputBM.colorType(), inputBM.alphaType(
)); |
| 580 | 582 |
| 581 SkBitmap dst; | 583 SkBitmap dst; |
| 582 if (!dst.tryAllocPixels(info)) { | 584 if (!dst.tryAllocPixels(info)) { |
| 583 return nullptr; | 585 return nullptr; |
| 584 } | 586 } |
| 585 | 587 |
| 586 SkAutoLockPixels dstLock(dst); | 588 SkAutoLockPixels inputLock(inputBM), dstLock(dst); |
| 587 | 589 |
| 588 SkMorphologyImageFilter::Proc procX, procY; | 590 SkMorphologyImageFilter::Proc procX, procY; |
| 589 | 591 |
| 590 if (kDilate_Op == this->op()) { | 592 if (kDilate_Op == this->op()) { |
| 591 procX = SkOpts::dilate_x; | 593 procX = SkOpts::dilate_x; |
| 592 procY = SkOpts::dilate_y; | 594 procY = SkOpts::dilate_y; |
| 593 } else { | 595 } else { |
| 594 procX = SkOpts::erode_x; | 596 procX = SkOpts::erode_x; |
| 595 procY = SkOpts::erode_y; | 597 procY = SkOpts::erode_y; |
| 596 } | 598 } |
| 597 | 599 |
| 598 if (width > 0 && height > 0) { | 600 if (width > 0 && height > 0) { |
| 599 SkBitmap tmp; | 601 SkBitmap tmp; |
| 600 if (!tmp.tryAllocPixels(info)) { | 602 if (!tmp.tryAllocPixels(info)) { |
| 601 return nullptr; | 603 return nullptr; |
| 602 } | 604 } |
| 603 | 605 |
| 604 SkAutoLockPixels tmpLock(tmp); | 606 SkAutoLockPixels tmpLock(tmp); |
| 605 | 607 |
| 606 call_proc_X(procX, inputPixmap, &tmp, width, srcBounds); | 608 call_proc_X(procX, inputBM, &tmp, width, srcBounds); |
| 607 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height(
)); | 609 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height(
)); |
| 608 call_proc_Y(procY, | 610 call_proc_Y(procY, |
| 609 tmp.getAddr32(tmpBounds.left(), tmpBounds.top()), tmp.rowByt
esAsPixels(), | 611 tmp.getAddr32(tmpBounds.left(), tmpBounds.top()), tmp.rowByt
esAsPixels(), |
| 610 &dst, height, tmpBounds); | 612 &dst, height, tmpBounds); |
| 611 } else if (width > 0) { | 613 } else if (width > 0) { |
| 612 call_proc_X(procX, inputPixmap, &dst, width, srcBounds); | 614 call_proc_X(procX, inputBM, &dst, width, srcBounds); |
| 613 } else if (height > 0) { | 615 } else if (height > 0) { |
| 614 call_proc_Y(procY, | 616 call_proc_Y(procY, |
| 615 inputPixmap.addr32(srcBounds.left(), srcBounds.top()), | 617 inputBM.getAddr32(srcBounds.left(), srcBounds.top()), |
| 616 inputPixmap.rowBytesAsPixels(), | 618 inputBM.rowBytesAsPixels(), |
| 617 &dst, height, srcBounds); | 619 &dst, height, srcBounds); |
| 618 } | 620 } |
| 619 offset->fX = bounds.left(); | 621 offset->fX = bounds.left(); |
| 620 offset->fY = bounds.top(); | 622 offset->fY = bounds.top(); |
| 621 | 623 |
| 622 return SkSpecialImage::MakeFromRaster(source->internal_getProxy(), | 624 return SkSpecialImage::MakeFromRaster(source->internal_getProxy(), |
| 623 SkIRect::MakeWH(bounds.width(), bounds
.height()), | 625 SkIRect::MakeWH(bounds.width(), bounds
.height()), |
| 624 dst, &source->props()); | 626 dst, &source->props()); |
| 625 } | 627 } |
| OLD | NEW |