Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Unified Diff: src/effects/SkAlphaThresholdFilter.cpp

Issue 1879643003: Switch AlphaThresholdFilter over to new onFilterImage interface (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix serialize-8888 config (deserialize crop rect) Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkImageFilter.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/effects/SkAlphaThresholdFilter.cpp
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index 0b65188e83a52703974217045bfbf425d6c9b94e..832fcb39e7636b75f733ec20969b3ac4d1941cea 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -8,8 +8,8 @@
#include "SkAlphaThresholdFilter.h"
#include "SkBitmap.h"
-#include "SkDevice.h"
#include "SkReadBuffer.h"
+#include "SkSpecialImage.h"
#include "SkWriteBuffer.h"
#include "SkRegion.h"
#if SK_SUPPORT_GPU
@@ -19,7 +19,8 @@
class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter {
public:
SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold,
- SkScalar outerThreshold, sk_sp<SkImageFilter> input);
+ SkScalar outerThreshold, sk_sp<SkImageFilter> input,
+ const CropRect* cropRect = nullptr);
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAlphaThresholdFilterImpl)
@@ -28,11 +29,11 @@ public:
protected:
void flatten(SkWriteBuffer&) const override;
- bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
- SkBitmap* result, SkIPoint* offset) const override;
+ sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
+ SkIPoint* offset) const override;
+
#if SK_SUPPORT_GPU
- bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
- const SkIRect& bounds) const override;
+ sk_sp<GrTexture> createMaskTexture(GrContext*, const SkMatrix&, const SkIRect& bounds) const;
#endif
private:
@@ -53,14 +54,17 @@ static SkScalar pin_0_1(SkScalar x) {
sk_sp<SkImageFilter> SkAlphaThresholdFilter::Make(const SkRegion& region,
SkScalar innerThreshold,
SkScalar outerThreshold,
- sk_sp<SkImageFilter> input) {
+ sk_sp<SkImageFilter> input,
+ const SkImageFilter::CropRect* cropRect) {
innerThreshold = pin_0_1(innerThreshold);
outerThreshold = pin_0_1(outerThreshold);
if (!SkScalarIsFinite(innerThreshold) || !SkScalarIsFinite(outerThreshold)) {
return nullptr;
}
return sk_sp<SkImageFilter>(new SkAlphaThresholdFilterImpl(region, innerThreshold,
- outerThreshold, std::move(input)));
+ outerThreshold,
+ std::move(input),
+ cropRect));
}
#if SK_SUPPORT_GPU
@@ -271,66 +275,59 @@ sk_sp<SkFlattenable> SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer
SkScalar outer = buffer.readScalar();
SkRegion rgn;
buffer.readRegion(&rgn);
- return SkAlphaThresholdFilter::Make(rgn, inner, outer, common.getInput(0));
+ return SkAlphaThresholdFilter::Make(rgn, inner, outer, common.getInput(0),
+ &common.cropRect());
}
SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(const SkRegion& region,
SkScalar innerThreshold,
SkScalar outerThreshold,
- sk_sp<SkImageFilter> input)
- : INHERITED(&input, 1, nullptr)
+ sk_sp<SkImageFilter> input,
+ const CropRect* cropRect)
+ : INHERITED(&input, 1, cropRect)
, fRegion(region)
, fInnerThreshold(innerThreshold)
, fOuterThreshold(outerThreshold) {
}
#if SK_SUPPORT_GPU
-bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp,
- GrTexture* texture,
- const SkMatrix& inMatrix,
- const SkIRect& bounds) const {
- if (fp) {
- GrContext* context = texture->getContext();
- GrSurfaceDesc maskDesc;
- if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
- maskDesc.fConfig = kAlpha_8_GrPixelConfig;
- } else {
- maskDesc.fConfig = kRGBA_8888_GrPixelConfig;
- }
- maskDesc.fFlags = kRenderTarget_GrSurfaceFlag;
- // Add one pixel of border to ensure that clamp mode will be all zeros
- // the outside.
- maskDesc.fWidth = bounds.width();
- maskDesc.fHeight = bounds.height();
- SkAutoTUnref<GrTexture> maskTexture(
- context->textureProvider()->createApproxTexture(maskDesc));
- if (!maskTexture) {
- return false;
- }
+sk_sp<GrTexture> SkAlphaThresholdFilterImpl::createMaskTexture(GrContext* context,
+ const SkMatrix& inMatrix,
+ const SkIRect& bounds) const {
+ GrSurfaceDesc maskDesc;
+ if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
+ maskDesc.fConfig = kAlpha_8_GrPixelConfig;
+ } else {
+ maskDesc.fConfig = kRGBA_8888_GrPixelConfig;
+ }
+ maskDesc.fFlags = kRenderTarget_GrSurfaceFlag;
+ // Add one pixel of border to ensure that clamp mode will be all zeros
+ // the outside.
+ maskDesc.fWidth = bounds.width();
+ maskDesc.fHeight = bounds.height();
+ sk_sp<GrTexture> maskTexture(context->textureProvider()->createApproxTexture(maskDesc));
+ if (!maskTexture) {
+ return nullptr;
+ }
- SkAutoTUnref<GrDrawContext> drawContext(
- context->drawContext(maskTexture->asRenderTarget()));
- if (drawContext) {
- GrPaint grPaint;
- grPaint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
- SkRegion::Iterator iter(fRegion);
- drawContext->clear(nullptr, 0x0, true);
-
- GrClip clip(SkRect::Make(SkIRect::MakeWH(bounds.width(), bounds.height())));
- while (!iter.done()) {
- SkRect rect = SkRect::Make(iter.rect());
- drawContext->drawRect(clip, grPaint, inMatrix, rect);
- iter.next();
- }
- }
+ sk_sp<GrDrawContext> drawContext(context->drawContext(maskTexture->asRenderTarget()));
+ if (!drawContext) {
+ return nullptr;
+ }
- *fp = AlphaThresholdEffect::Create(texture,
- maskTexture,
- fInnerThreshold,
- fOuterThreshold,
- bounds);
+ GrPaint grPaint;
+ grPaint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
+ SkRegion::Iterator iter(fRegion);
+ drawContext->clear(nullptr, 0x0, true);
+
+ GrClip clip(SkRect::Make(SkIRect::MakeWH(bounds.width(), bounds.height())));
+ while (!iter.done()) {
+ SkRect rect = SkRect::Make(iter.rect());
+ drawContext->drawRect(clip, grPaint, inMatrix, rect);
+ iter.next();
}
- return true;
+
+ return maskTexture;
}
#endif
@@ -341,50 +338,109 @@ void SkAlphaThresholdFilterImpl::flatten(SkWriteBuffer& buffer) const {
buffer.writeRegion(fRegion);
}
-bool SkAlphaThresholdFilterImpl::onFilterImageDeprecated(Proxy* proxy, const SkBitmap& src,
- const Context& ctx, SkBitmap* dst,
- SkIPoint* offset) const {
+sk_sp<SkSpecialImage> SkAlphaThresholdFilterImpl::onFilterImage(SkSpecialImage* source,
+ const Context& ctx,
+ SkIPoint* offset) const {
+ SkIPoint inputOffset = SkIPoint::Make(0, 0);
+ sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset));
+ if (!input) {
+ return nullptr;
+ }
+
+ const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(),
+ input->width(), input->height());
+
+ SkIRect bounds;
+ if (!this->applyCropRect(ctx, inputBounds, &bounds)) {
+ return nullptr;
+ }
+
+#if SK_SUPPORT_GPU
+ if (source->isTextureBacked()) {
+ GrContext* context = source->getContext();
+
+ sk_sp<GrTexture> inputTexture(input->asTextureRef(context));
+ SkASSERT(inputTexture);
+
+ offset->fX = bounds.left();
+ offset->fY = bounds.top();
- if (src.colorType() != kN32_SkColorType) {
- return false;
+ bounds.offset(-inputOffset);
+
+ SkMatrix matrix(ctx.ctm());
+ matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
+
+ sk_sp<GrTexture> maskTexture(this->createMaskTexture(context, matrix, bounds));
+ if (!maskTexture) {
+ return nullptr;
+ }
+
+ // SRGBTODO: handle sRGB here
+ sk_sp<GrFragmentProcessor> fp(AlphaThresholdEffect::Create(inputTexture.get(),
+ maskTexture.get(),
+ fInnerThreshold,
+ fOuterThreshold,
+ bounds));
+ if (!fp) {
+ return nullptr;
+ }
+
+ return DrawWithFP(context, std::move(fp), bounds, source->internal_getProxy());
+ }
+#endif
+
+ SkBitmap inputBM;
+
+ if (!input->getROPixels(&inputBM)) {
+ return nullptr;
}
+ if (inputBM.colorType() != kN32_SkColorType) {
+ return nullptr;
+ }
+
+ SkAutoLockPixels inputLock(inputBM);
+
+ if (!inputBM.getPixels() || inputBM.width() <= 0 || inputBM.height() <= 0) {
+ return nullptr;
+ }
+
+
SkMatrix localInverse;
if (!ctx.ctm().invert(&localInverse)) {
- return false;
+ return nullptr;
}
- SkAutoLockPixels alp(src);
- SkASSERT(src.getPixels());
- if (!src.getPixels() || src.width() <= 0 || src.height() <= 0) {
- return false;
- }
+ SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(),
+ inputBM.alphaType());
- SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(src.width(), src.height()));
- if (!device) {
- return false;
+ SkBitmap dst;
+ if (!dst.tryAllocPixels(info)) {
+ return nullptr;
}
- *dst = device->accessBitmap(false);
- SkAutoLockPixels alp_dst(*dst);
+
+ SkAutoLockPixels dstLock(dst);
U8CPU innerThreshold = (U8CPU)(fInnerThreshold * 0xFF);
U8CPU outerThreshold = (U8CPU)(fOuterThreshold * 0xFF);
- SkColor* sptr = src.getAddr32(0, 0);
- SkColor* dptr = dst->getAddr32(0, 0);
- int width = src.width(), height = src.height();
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- const SkColor& source = sptr[y * width + x];
- SkColor output_color(source);
+ SkColor* dptr = dst.getAddr32(0, 0);
+ int dstWidth = dst.width(), dstHeight = dst.height();
+ for (int y = 0; y < dstHeight; ++y) {
+ const SkColor* sptr = inputBM.getAddr32(bounds.fLeft, bounds.fTop+y);
+
+ for (int x = 0; x < dstWidth; ++x) {
+ const SkColor& source = sptr[x];
+ SkColor outputColor(source);
SkPoint position;
- localInverse.mapXY((SkScalar)x, (SkScalar)y, &position);
+ localInverse.mapXY((SkScalar)x + bounds.fLeft, (SkScalar)y + bounds.fTop, &position);
if (fRegion.contains((int32_t)position.x(), (int32_t)position.y())) {
if (SkColorGetA(source) < innerThreshold) {
U8CPU alpha = SkColorGetA(source);
- if (alpha == 0)
+ if (alpha == 0) {
alpha = 1;
+ }
float scale = (float)innerThreshold / alpha;
- output_color = SkColorSetARGB(innerThreshold,
+ outputColor = SkColorSetARGB(innerThreshold,
(U8CPU)(SkColorGetR(source) * scale),
(U8CPU)(SkColorGetG(source) * scale),
(U8CPU)(SkColorGetB(source) * scale));
@@ -392,17 +448,21 @@ bool SkAlphaThresholdFilterImpl::onFilterImageDeprecated(Proxy* proxy, const SkB
} else {
if (SkColorGetA(source) > outerThreshold) {
float scale = (float)outerThreshold / SkColorGetA(source);
- output_color = SkColorSetARGB(outerThreshold,
+ outputColor = SkColorSetARGB(outerThreshold,
(U8CPU)(SkColorGetR(source) * scale),
(U8CPU)(SkColorGetG(source) * scale),
(U8CPU)(SkColorGetB(source) * scale));
}
}
- dptr[y * dst->width() + x] = output_color;
+ dptr[y * dstWidth + x] = outputColor;
}
}
- return true;
+ offset->fX = bounds.left();
+ offset->fY = bounds.top();
+ return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
+ SkIRect::MakeWH(bounds.width(), bounds.height()),
+ dst);
}
#ifndef SK_IGNORE_TO_STRING
« no previous file with comments | « src/core/SkImageFilter.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698