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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/core/SkImageFilter.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
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 "SkAlphaThresholdFilter.h" 8 #include "SkAlphaThresholdFilter.h"
9 9
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
11 #include "SkDevice.h"
12 #include "SkReadBuffer.h" 11 #include "SkReadBuffer.h"
12 #include "SkSpecialImage.h"
13 #include "SkWriteBuffer.h" 13 #include "SkWriteBuffer.h"
14 #include "SkRegion.h" 14 #include "SkRegion.h"
15 #if SK_SUPPORT_GPU 15 #if SK_SUPPORT_GPU
16 #include "GrDrawContext.h" 16 #include "GrDrawContext.h"
17 #endif 17 #endif
18 18
19 class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter { 19 class SK_API SkAlphaThresholdFilterImpl : public SkImageFilter {
20 public: 20 public:
21 SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold, 21 SkAlphaThresholdFilterImpl(const SkRegion& region, SkScalar innerThreshold,
22 SkScalar outerThreshold, sk_sp<SkImageFilter> inp ut); 22 SkScalar outerThreshold, sk_sp<SkImageFilter> inp ut,
23 const CropRect* cropRect = nullptr);
23 24
24 SK_TO_STRING_OVERRIDE() 25 SK_TO_STRING_OVERRIDE()
25 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAlphaThresholdFilterIm pl) 26 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAlphaThresholdFilterIm pl)
26 friend void SkAlphaThresholdFilter::InitializeFlattenables(); 27 friend void SkAlphaThresholdFilter::InitializeFlattenables();
27 28
28 protected: 29 protected:
29 void flatten(SkWriteBuffer&) const override; 30 void flatten(SkWriteBuffer&) const override;
30 31
31 bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&, 32 sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
32 SkBitmap* result, SkIPoint* offset) const overr ide; 33 SkIPoint* offset) const override;
34
33 #if SK_SUPPORT_GPU 35 #if SK_SUPPORT_GPU
34 bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&, 36 sk_sp<GrTexture> createMaskTexture(GrContext*, const SkMatrix&, const SkIRec t& bounds) const;
35 const SkIRect& bounds) const override;
36 #endif 37 #endif
37 38
38 private: 39 private:
39 SkRegion fRegion; 40 SkRegion fRegion;
40 SkScalar fInnerThreshold; 41 SkScalar fInnerThreshold;
41 SkScalar fOuterThreshold; 42 SkScalar fOuterThreshold;
42 typedef SkImageFilter INHERITED; 43 typedef SkImageFilter INHERITED;
43 }; 44 };
44 45
45 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkAlphaThresholdFilter) 46 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkAlphaThresholdFilter)
46 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAlphaThresholdFilterImpl) 47 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAlphaThresholdFilterImpl)
47 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 48 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
48 49
49 static SkScalar pin_0_1(SkScalar x) { 50 static SkScalar pin_0_1(SkScalar x) {
50 return SkMinScalar(SkMaxScalar(x, 0), 1); 51 return SkMinScalar(SkMaxScalar(x, 0), 1);
51 } 52 }
52 53
53 sk_sp<SkImageFilter> SkAlphaThresholdFilter::Make(const SkRegion& region, 54 sk_sp<SkImageFilter> SkAlphaThresholdFilter::Make(const SkRegion& region,
54 SkScalar innerThreshold, 55 SkScalar innerThreshold,
55 SkScalar outerThreshold, 56 SkScalar outerThreshold,
56 sk_sp<SkImageFilter> input) { 57 sk_sp<SkImageFilter> input,
58 const SkImageFilter::CropRect* cropRect) {
57 innerThreshold = pin_0_1(innerThreshold); 59 innerThreshold = pin_0_1(innerThreshold);
58 outerThreshold = pin_0_1(outerThreshold); 60 outerThreshold = pin_0_1(outerThreshold);
59 if (!SkScalarIsFinite(innerThreshold) || !SkScalarIsFinite(outerThreshold)) { 61 if (!SkScalarIsFinite(innerThreshold) || !SkScalarIsFinite(outerThreshold)) {
60 return nullptr; 62 return nullptr;
61 } 63 }
62 return sk_sp<SkImageFilter>(new SkAlphaThresholdFilterImpl(region, innerThre shold, 64 return sk_sp<SkImageFilter>(new SkAlphaThresholdFilterImpl(region, innerThre shold,
63 outerThreshold, s td::move(input))); 65 outerThreshold,
66 std::move(input),
67 cropRect));
64 } 68 }
65 69
66 #if SK_SUPPORT_GPU 70 #if SK_SUPPORT_GPU
67 #include "GrContext.h" 71 #include "GrContext.h"
68 #include "GrCoordTransform.h" 72 #include "GrCoordTransform.h"
69 #include "GrFragmentProcessor.h" 73 #include "GrFragmentProcessor.h"
70 #include "GrInvariantOutput.h" 74 #include "GrInvariantOutput.h"
71 #include "GrTextureAccess.h" 75 #include "GrTextureAccess.h"
72 #include "effects/GrPorterDuffXferProcessor.h" 76 #include "effects/GrPorterDuffXferProcessor.h"
73 77
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 } 268 }
265 269
266 #endif 270 #endif
267 271
268 sk_sp<SkFlattenable> SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer ) { 272 sk_sp<SkFlattenable> SkAlphaThresholdFilterImpl::CreateProc(SkReadBuffer& buffer ) {
269 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 273 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
270 SkScalar inner = buffer.readScalar(); 274 SkScalar inner = buffer.readScalar();
271 SkScalar outer = buffer.readScalar(); 275 SkScalar outer = buffer.readScalar();
272 SkRegion rgn; 276 SkRegion rgn;
273 buffer.readRegion(&rgn); 277 buffer.readRegion(&rgn);
274 return SkAlphaThresholdFilter::Make(rgn, inner, outer, common.getInput(0)); 278 return SkAlphaThresholdFilter::Make(rgn, inner, outer, common.getInput(0),
279 &common.cropRect());
275 } 280 }
276 281
277 SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(const SkRegion& region, 282 SkAlphaThresholdFilterImpl::SkAlphaThresholdFilterImpl(const SkRegion& region,
278 SkScalar innerThreshold, 283 SkScalar innerThreshold,
279 SkScalar outerThreshold, 284 SkScalar outerThreshold,
280 sk_sp<SkImageFilter> inpu t) 285 sk_sp<SkImageFilter> inpu t,
281 : INHERITED(&input, 1, nullptr) 286 const CropRect* cropRect)
287 : INHERITED(&input, 1, cropRect)
282 , fRegion(region) 288 , fRegion(region)
283 , fInnerThreshold(innerThreshold) 289 , fInnerThreshold(innerThreshold)
284 , fOuterThreshold(outerThreshold) { 290 , fOuterThreshold(outerThreshold) {
285 } 291 }
286 292
287 #if SK_SUPPORT_GPU 293 #if SK_SUPPORT_GPU
288 bool SkAlphaThresholdFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp, 294 sk_sp<GrTexture> SkAlphaThresholdFilterImpl::createMaskTexture(GrContext* contex t,
289 GrTexture* texture, 295 const SkMatrix& i nMatrix,
290 const SkMatrix& inMatrix, 296 const SkIRect& bo unds) const {
291 const SkIRect& bounds) cons t { 297 GrSurfaceDesc maskDesc;
292 if (fp) { 298 if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
293 GrContext* context = texture->getContext(); 299 maskDesc.fConfig = kAlpha_8_GrPixelConfig;
294 GrSurfaceDesc maskDesc; 300 } else {
295 if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { 301 maskDesc.fConfig = kRGBA_8888_GrPixelConfig;
296 maskDesc.fConfig = kAlpha_8_GrPixelConfig; 302 }
297 } else { 303 maskDesc.fFlags = kRenderTarget_GrSurfaceFlag;
298 maskDesc.fConfig = kRGBA_8888_GrPixelConfig; 304 // Add one pixel of border to ensure that clamp mode will be all zeros
299 } 305 // the outside.
300 maskDesc.fFlags = kRenderTarget_GrSurfaceFlag; 306 maskDesc.fWidth = bounds.width();
301 // Add one pixel of border to ensure that clamp mode will be all zeros 307 maskDesc.fHeight = bounds.height();
302 // the outside. 308 sk_sp<GrTexture> maskTexture(context->textureProvider()->createApproxTexture (maskDesc));
303 maskDesc.fWidth = bounds.width(); 309 if (!maskTexture) {
304 maskDesc.fHeight = bounds.height(); 310 return nullptr;
305 SkAutoTUnref<GrTexture> maskTexture( 311 }
306 context->textureProvider()->createApproxTexture(maskDesc));
307 if (!maskTexture) {
308 return false;
309 }
310 312
311 SkAutoTUnref<GrDrawContext> drawContext( 313 sk_sp<GrDrawContext> drawContext(context->drawContext(maskTexture->asRenderT arget()));
312 context->drawContext(maskTexture->as RenderTarget())); 314 if (!drawContext) {
313 if (drawContext) { 315 return nullptr;
314 GrPaint grPaint; 316 }
315 grPaint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
316 SkRegion::Iterator iter(fRegion);
317 drawContext->clear(nullptr, 0x0, true);
318 317
319 GrClip clip(SkRect::Make(SkIRect::MakeWH(bounds.width(), bounds.heig ht()))); 318 GrPaint grPaint;
320 while (!iter.done()) { 319 grPaint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
321 SkRect rect = SkRect::Make(iter.rect()); 320 SkRegion::Iterator iter(fRegion);
322 drawContext->drawRect(clip, grPaint, inMatrix, rect); 321 drawContext->clear(nullptr, 0x0, true);
323 iter.next();
324 }
325 }
326 322
327 *fp = AlphaThresholdEffect::Create(texture, 323 GrClip clip(SkRect::Make(SkIRect::MakeWH(bounds.width(), bounds.height())));
328 maskTexture, 324 while (!iter.done()) {
329 fInnerThreshold, 325 SkRect rect = SkRect::Make(iter.rect());
330 fOuterThreshold, 326 drawContext->drawRect(clip, grPaint, inMatrix, rect);
331 bounds); 327 iter.next();
332 } 328 }
333 return true; 329
330 return maskTexture;
334 } 331 }
335 #endif 332 #endif
336 333
337 void SkAlphaThresholdFilterImpl::flatten(SkWriteBuffer& buffer) const { 334 void SkAlphaThresholdFilterImpl::flatten(SkWriteBuffer& buffer) const {
338 this->INHERITED::flatten(buffer); 335 this->INHERITED::flatten(buffer);
339 buffer.writeScalar(fInnerThreshold); 336 buffer.writeScalar(fInnerThreshold);
340 buffer.writeScalar(fOuterThreshold); 337 buffer.writeScalar(fOuterThreshold);
341 buffer.writeRegion(fRegion); 338 buffer.writeRegion(fRegion);
342 } 339 }
343 340
344 bool SkAlphaThresholdFilterImpl::onFilterImageDeprecated(Proxy* proxy, const SkB itmap& src, 341 sk_sp<SkSpecialImage> SkAlphaThresholdFilterImpl::onFilterImage(SkSpecialImage* source,
345 const Context& ctx, SkB itmap* dst, 342 const Context& c tx,
346 SkIPoint* offset) const { 343 SkIPoint* offset ) const {
344 SkIPoint inputOffset = SkIPoint::Make(0, 0);
345 sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset)) ;
346 if (!input) {
347 return nullptr;
348 }
347 349
348 if (src.colorType() != kN32_SkColorType) { 350 const SkIRect inputBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y (),
349 return false; 351 input->width(), input->height( ));
352
353 SkIRect bounds;
354 if (!this->applyCropRect(ctx, inputBounds, &bounds)) {
355 return nullptr;
350 } 356 }
351 357
358 #if SK_SUPPORT_GPU
359 if (source->isTextureBacked()) {
360 GrContext* context = source->getContext();
361
362 sk_sp<GrTexture> inputTexture(input->asTextureRef(context));
363 SkASSERT(inputTexture);
364
365 offset->fX = bounds.left();
366 offset->fY = bounds.top();
367
368 bounds.offset(-inputOffset);
369
370 SkMatrix matrix(ctx.ctm());
371 matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bound s.top()));
372
373 sk_sp<GrTexture> maskTexture(this->createMaskTexture(context, matrix, bo unds));
374 if (!maskTexture) {
375 return nullptr;
376 }
377
378 // SRGBTODO: handle sRGB here
379 sk_sp<GrFragmentProcessor> fp(AlphaThresholdEffect::Create(inputTexture. get(),
380 maskTexture.g et(),
381 fInnerThresho ld,
382 fOuterThresho ld,
383 bounds));
384 if (!fp) {
385 return nullptr;
386 }
387
388 return DrawWithFP(context, std::move(fp), bounds, source->internal_getPr oxy());
389 }
390 #endif
391
392 SkBitmap inputBM;
393
394 if (!input->getROPixels(&inputBM)) {
395 return nullptr;
396 }
397
398 if (inputBM.colorType() != kN32_SkColorType) {
399 return nullptr;
400 }
401
402 SkAutoLockPixels inputLock(inputBM);
403
404 if (!inputBM.getPixels() || inputBM.width() <= 0 || inputBM.height() <= 0) {
405 return nullptr;
406 }
407
408
352 SkMatrix localInverse; 409 SkMatrix localInverse;
353 if (!ctx.ctm().invert(&localInverse)) { 410 if (!ctx.ctm().invert(&localInverse)) {
354 return false; 411 return nullptr;
355 } 412 }
356 413
357 SkAutoLockPixels alp(src); 414 SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(),
358 SkASSERT(src.getPixels()); 415 inputBM.alphaType());
359 if (!src.getPixels() || src.width() <= 0 || src.height() <= 0) { 416
360 return false; 417 SkBitmap dst;
418 if (!dst.tryAllocPixels(info)) {
419 return nullptr;
361 } 420 }
362 421
363 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(src.width(), src.heigh t())); 422 SkAutoLockPixels dstLock(dst);
364 if (!device) {
365 return false;
366 }
367 *dst = device->accessBitmap(false);
368 SkAutoLockPixels alp_dst(*dst);
369 423
370 U8CPU innerThreshold = (U8CPU)(fInnerThreshold * 0xFF); 424 U8CPU innerThreshold = (U8CPU)(fInnerThreshold * 0xFF);
371 U8CPU outerThreshold = (U8CPU)(fOuterThreshold * 0xFF); 425 U8CPU outerThreshold = (U8CPU)(fOuterThreshold * 0xFF);
372 SkColor* sptr = src.getAddr32(0, 0); 426 SkColor* dptr = dst.getAddr32(0, 0);
373 SkColor* dptr = dst->getAddr32(0, 0); 427 int dstWidth = dst.width(), dstHeight = dst.height();
374 int width = src.width(), height = src.height(); 428 for (int y = 0; y < dstHeight; ++y) {
375 for (int y = 0; y < height; ++y) { 429 const SkColor* sptr = inputBM.getAddr32(bounds.fLeft, bounds.fTop+y);
376 for (int x = 0; x < width; ++x) { 430
377 const SkColor& source = sptr[y * width + x]; 431 for (int x = 0; x < dstWidth; ++x) {
378 SkColor output_color(source); 432 const SkColor& source = sptr[x];
433 SkColor outputColor(source);
379 SkPoint position; 434 SkPoint position;
380 localInverse.mapXY((SkScalar)x, (SkScalar)y, &position); 435 localInverse.mapXY((SkScalar)x + bounds.fLeft, (SkScalar)y + bounds. fTop, &position);
381 if (fRegion.contains((int32_t)position.x(), (int32_t)position.y())) { 436 if (fRegion.contains((int32_t)position.x(), (int32_t)position.y())) {
382 if (SkColorGetA(source) < innerThreshold) { 437 if (SkColorGetA(source) < innerThreshold) {
383 U8CPU alpha = SkColorGetA(source); 438 U8CPU alpha = SkColorGetA(source);
384 if (alpha == 0) 439 if (alpha == 0) {
385 alpha = 1; 440 alpha = 1;
441 }
386 float scale = (float)innerThreshold / alpha; 442 float scale = (float)innerThreshold / alpha;
387 output_color = SkColorSetARGB(innerThreshold, 443 outputColor = SkColorSetARGB(innerThreshold,
388 (U8CPU)(SkColorGetR(source) * scale), 444 (U8CPU)(SkColorGetR(source) * scale),
389 (U8CPU)(SkColorGetG(source) * scale), 445 (U8CPU)(SkColorGetG(source) * scale),
390 (U8CPU)(SkColorGetB(source) * scale)); 446 (U8CPU)(SkColorGetB(source) * scale));
391 } 447 }
392 } else { 448 } else {
393 if (SkColorGetA(source) > outerThreshold) { 449 if (SkColorGetA(source) > outerThreshold) {
394 float scale = (float)outerThreshold / SkColorGetA(source); 450 float scale = (float)outerThreshold / SkColorGetA(source);
395 output_color = SkColorSetARGB(outerThreshold, 451 outputColor = SkColorSetARGB(outerThreshold,
396 (U8CPU)(SkColorGetR(source) * scale), 452 (U8CPU)(SkColorGetR(source) * scale),
397 (U8CPU)(SkColorGetG(source) * scale), 453 (U8CPU)(SkColorGetG(source) * scale),
398 (U8CPU)(SkColorGetB(source) * scale)); 454 (U8CPU)(SkColorGetB(source) * scale));
399 } 455 }
400 } 456 }
401 dptr[y * dst->width() + x] = output_color; 457 dptr[y * dstWidth + x] = outputColor;
402 } 458 }
403 } 459 }
404 460
405 return true; 461 offset->fX = bounds.left();
462 offset->fY = bounds.top();
463 return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
464 SkIRect::MakeWH(bounds.width(), bounds .height()),
465 dst);
406 } 466 }
407 467
408 #ifndef SK_IGNORE_TO_STRING 468 #ifndef SK_IGNORE_TO_STRING
409 void SkAlphaThresholdFilterImpl::toString(SkString* str) const { 469 void SkAlphaThresholdFilterImpl::toString(SkString* str) const {
410 str->appendf("SkAlphaThresholdImageFilter: ("); 470 str->appendf("SkAlphaThresholdImageFilter: (");
411 str->appendf("inner: %f outer: %f", fInnerThreshold, fOuterThreshold); 471 str->appendf("inner: %f outer: %f", fInnerThreshold, fOuterThreshold);
412 str->append(")"); 472 str->append(")");
413 } 473 }
414 #endif 474 #endif
OLDNEW
« 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