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

Side by Side Diff: src/effects/SkMorphologyImageFilter.cpp

Issue 1819393002: Switch SkMorphologyImageFilter over to new onFilterImage interface (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Update to ToT Created 4 years, 9 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 | « include/effects/SkMorphologyImageFilter.h ('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 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 #include "SkBitmap.h" 10 #include "SkBitmap.h"
10 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
11 #include "SkDevice.h"
12 #include "SkOpts.h" 12 #include "SkOpts.h"
13 #include "SkReadBuffer.h" 13 #include "SkReadBuffer.h"
14 #include "SkRect.h" 14 #include "SkRect.h"
15 #include "SkSpecialImage.h"
15 #include "SkWriteBuffer.h" 16 #include "SkWriteBuffer.h"
17
16 #if SK_SUPPORT_GPU 18 #if SK_SUPPORT_GPU
17 #include "GrContext.h" 19 #include "GrContext.h"
18 #include "GrDrawContext.h" 20 #include "GrDrawContext.h"
19 #include "GrInvariantOutput.h" 21 #include "GrInvariantOutput.h"
20 #include "GrTexture.h" 22 #include "GrTexture.h"
21 #include "SkGr.h" 23 #include "SkGr.h"
22 #include "effects/Gr1DKernelEffect.h" 24 #include "effects/Gr1DKernelEffect.h"
23 #include "glsl/GrGLSLFragmentProcessor.h" 25 #include "glsl/GrGLSLFragmentProcessor.h"
24 #include "glsl/GrGLSLFragmentShaderBuilder.h" 26 #include "glsl/GrGLSLFragmentShaderBuilder.h"
25 #include "glsl/GrGLSLProgramDataManager.h" 27 #include "glsl/GrGLSLProgramDataManager.h"
26 #include "glsl/GrGLSLUniformHandler.h" 28 #include "glsl/GrGLSLUniformHandler.h"
27 #endif 29 #endif
28 30
29 SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, 31 SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX,
30 int radiusY, 32 int radiusY,
31 SkImageFilter* input, 33 SkImageFilter* input,
32 const CropRect* cropRect) 34 const CropRect* cropRect)
33 : INHERITED(1, &input, cropRect), fRadius(SkISize::Make(radiusX, radiusY)) { 35 : INHERITED(1, &input, cropRect)
36 , fRadius(SkISize::Make(radiusX, radiusY)) {
34 } 37 }
35 38
36 void SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const { 39 void SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const {
37 this->INHERITED::flatten(buffer); 40 this->INHERITED::flatten(buffer);
38 buffer.writeInt(fRadius.fWidth); 41 buffer.writeInt(fRadius.fWidth);
39 buffer.writeInt(fRadius.fHeight); 42 buffer.writeInt(fRadius.fHeight);
40 } 43 }
41 44
42 static void callProcX(SkMorphologyImageFilter::Proc procX, const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRect& bounds) 45 static void call_proc_X(SkMorphologyImageFilter::Proc procX,
43 { 46 const SkPixmap& src, SkBitmap* dst,
44 procX(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), 47 int radiusX, const SkIRect& bounds) {
48 procX(src.addr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
45 radiusX, bounds.width(), bounds.height(), 49 radiusX, bounds.width(), bounds.height(),
46 src.rowBytesAsPixels(), dst->rowBytesAsPixels()); 50 src.rowBytesAsPixels(), dst->rowBytesAsPixels());
47 } 51 }
48 52
49 static void callProcY(SkMorphologyImageFilter::Proc procY, const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRect& bounds) 53 static void call_proc_Y(SkMorphologyImageFilter::Proc procY,
50 { 54 const SkPMColor* src, int srcRowBytesAsPixels, SkBitmap* dst,
51 procY(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), 55 int radiusY, const SkIRect& bounds) {
56 procY(src, dst->getAddr32(0, 0),
52 radiusY, bounds.height(), bounds.width(), 57 radiusY, bounds.height(), bounds.width(),
53 src.rowBytesAsPixels(), dst->rowBytesAsPixels()); 58 srcRowBytesAsPixels, dst->rowBytesAsPixels());
54 }
55
56 bool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc p rocX,
57 SkMorphologyImageFilter::Proc p rocY,
58 Proxy* proxy,
59 const SkBitmap& source,
60 const Context& ctx,
61 SkBitmap* dst,
62 SkIPoint* offset) const {
63 SkBitmap src = source;
64 SkIPoint srcOffset = SkIPoint::Make(0, 0);
65 if (!this->filterInputDeprecated(0, proxy, source, ctx, &src, &srcOffset)) {
66 return false;
67 }
68
69 if (src.colorType() != kN32_SkColorType) {
70 return false;
71 }
72
73 SkIRect bounds;
74 if (!this->applyCropRectDeprecated(this->mapContext(ctx), proxy, src, &srcOf fset,
75 &bounds, &src)) {
76 return false;
77 }
78
79 SkAutoLockPixels alp(src);
80 if (!src.getPixels()) {
81 return false;
82 }
83
84 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
85 SkIntToScalar(this->radius().height()));
86 ctx.ctm().mapVectors(&radius, 1);
87 int width = SkScalarFloorToInt(radius.fX);
88 int height = SkScalarFloorToInt(radius.fY);
89
90 if (width < 0 || height < 0) {
91 return false;
92 }
93
94 SkIRect srcBounds = bounds;
95 srcBounds.offset(-srcOffset);
96
97 if (width == 0 && height == 0) {
98 src.extractSubset(dst, srcBounds);
99 offset->fX = bounds.left();
100 offset->fY = bounds.top();
101 return true;
102 }
103
104 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds .height()));
105 if (!device) {
106 return false;
107 }
108 *dst = device->accessBitmap(false);
109 SkAutoLockPixels alp_dst(*dst);
110
111 if (width > 0 && height > 0) {
112 SkAutoTUnref<SkBaseDevice> tempDevice(proxy->createDevice(dst->width(), dst->height()));
113 if (!tempDevice) {
114 return false;
115 }
116 SkBitmap temp = tempDevice->accessBitmap(false);
117 SkAutoLockPixels alp_temp(temp);
118 callProcX(procX, src, &temp, width, srcBounds);
119 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height( ));
120 callProcY(procY, temp, dst, height, tmpBounds);
121 } else if (width > 0) {
122 callProcX(procX, src, dst, width, srcBounds);
123 } else if (height > 0) {
124 callProcY(procY, src, dst, height, srcBounds);
125 }
126 offset->fX = bounds.left();
127 offset->fY = bounds.top();
128 return true;
129 }
130
131 bool SkErodeImageFilter::onFilterImageDeprecated(Proxy* proxy,
132 const SkBitmap& source, const C ontext& ctx,
133 SkBitmap* dst, SkIPoint* offset ) const {
134 return this->filterImageGeneric(SkOpts::erode_x, SkOpts::erode_y,
135 proxy, source, ctx, dst, offset);
136 }
137
138 bool SkDilateImageFilter::onFilterImageDeprecated(Proxy* proxy,
139 const SkBitmap& source, const Context& ctx,
140 SkBitmap* dst, SkIPoint* offse t) const {
141 return this->filterImageGeneric(SkOpts::dilate_x, SkOpts::dilate_y,
142 proxy, source, ctx, dst, offset);
143 } 59 }
144 60
145 SkRect SkMorphologyImageFilter::computeFastBounds(const SkRect& src) const { 61 SkRect SkMorphologyImageFilter::computeFastBounds(const SkRect& src) const {
146 SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src ) : src; 62 SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src ) : src;
147 bounds.outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height() )); 63 bounds.outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height() ));
148 return bounds; 64 return bounds;
149 } 65 }
150 66
151 SkIRect SkMorphologyImageFilter::onFilterNodeBounds(const SkIRect& src, const Sk Matrix& ctm, 67 SkIRect SkMorphologyImageFilter::onFilterNodeBounds(const SkIRect& src, const Sk Matrix& ctm,
152 MapDirection) const { 68 MapDirection) const {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 } 293 }
378 } 294 }
379 295
380 /////////////////////////////////////////////////////////////////////////////// 296 ///////////////////////////////////////////////////////////////////////////////
381 297
382 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, 298 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
383 Direction direction, 299 Direction direction,
384 int radius, 300 int radius,
385 MorphologyType type) 301 MorphologyType type)
386 : INHERITED(texture, direction, radius) 302 : INHERITED(texture, direction, radius)
387 , fType(type), fUseRange(false) { 303 , fType(type)
304 , fUseRange(false) {
388 this->initClassID<GrMorphologyEffect>(); 305 this->initClassID<GrMorphologyEffect>();
389 } 306 }
390 307
391 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, 308 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
392 Direction direction, 309 Direction direction,
393 int radius, 310 int radius,
394 MorphologyType type, 311 MorphologyType type,
395 float range[2]) 312 float range[2])
396 : INHERITED(texture, direction, radius) 313 : INHERITED(texture, direction, radius)
397 , fType(type), fUseRange(true) { 314 , fType(type)
315 , fUseRange(true) {
398 this->initClassID<GrMorphologyEffect>(); 316 this->initClassID<GrMorphologyEffect>();
399 fRange[0] = range[0]; 317 fRange[0] = range[0];
400 fRange[1] = range[1]; 318 fRange[1] = range[1];
401 } 319 }
402 320
403 GrMorphologyEffect::~GrMorphologyEffect() { 321 GrMorphologyEffect::~GrMorphologyEffect() {
404 } 322 }
405 323
406 void GrMorphologyEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, 324 void GrMorphologyEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
407 GrProcessorKeyBuilder* b) const { 325 GrProcessorKeyBuilder* b) const {
(...skipping 26 matching lines...) Expand all
434 GrProcessorUnitTest::kAlphaTextureIdx; 352 GrProcessorUnitTest::kAlphaTextureIdx;
435 Direction dir = d->fRandom->nextBool() ? kX_Direction : kY_Direction; 353 Direction dir = d->fRandom->nextBool() ? kX_Direction : kY_Direction;
436 static const int kMaxRadius = 10; 354 static const int kMaxRadius = 10;
437 int radius = d->fRandom->nextRangeU(1, kMaxRadius); 355 int radius = d->fRandom->nextRangeU(1, kMaxRadius);
438 MorphologyType type = d->fRandom->nextBool() ? GrMorphologyEffect::kErode_Mo rphologyType : 356 MorphologyType type = d->fRandom->nextBool() ? GrMorphologyEffect::kErode_Mo rphologyType :
439 GrMorphologyEffect::kDilate_Morph ologyType; 357 GrMorphologyEffect::kDilate_Morph ologyType;
440 358
441 return GrMorphologyEffect::Create(d->fTextures[texIdx], dir, radius, type); 359 return GrMorphologyEffect::Create(d->fTextures[texIdx], dir, radius, type);
442 } 360 }
443 361
444 namespace {
445 362
446 363 static void apply_morphology_rect(GrDrawContext* drawContext,
447 void apply_morphology_rect(GrDrawContext* drawContext, 364 const GrClip& clip,
448 const GrClip& clip, 365 GrTexture* texture,
449 GrTexture* texture, 366 const SkIRect& srcRect,
450 const SkIRect& srcRect, 367 const SkIRect& dstRect,
451 const SkIRect& dstRect, 368 int radius,
452 int radius, 369 GrMorphologyEffect::MorphologyType morphType,
453 GrMorphologyEffect::MorphologyType morphType, 370 float bounds[2],
454 float bounds[2], 371 Gr1DKernelEffect::Direction direction) {
455 Gr1DKernelEffect::Direction direction) {
456 GrPaint paint; 372 GrPaint paint;
457 paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture, 373 paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture,
458 direction, 374 direction,
459 radius, 375 radius,
460 morphType, 376 morphType,
461 bounds))->unref() ; 377 bounds))->unref() ;
462 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 378 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
463 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect ), 379 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect ),
464 SkRect::Make(srcRect)); 380 SkRect::Make(srcRect));
465 } 381 }
466 382
467 void apply_morphology_rect_no_bounds(GrDrawContext* drawContext, 383 static void apply_morphology_rect_no_bounds(GrDrawContext* drawContext,
468 const GrClip& clip, 384 const GrClip& clip,
469 GrTexture* texture, 385 GrTexture* texture,
470 const SkIRect& srcRect, 386 const SkIRect& srcRect,
471 const SkIRect& dstRect, 387 const SkIRect& dstRect,
472 int radius, 388 int radius,
473 GrMorphologyEffect::MorphologyType morphTyp e, 389 GrMorphologyEffect::MorphologyType m orphType,
474 Gr1DKernelEffect::Direction direction) { 390 Gr1DKernelEffect::Direction directio n) {
475 GrPaint paint; 391 GrPaint paint;
476 paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture, 392 paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture,
477 direction, 393 direction,
478 radius, 394 radius,
479 morphType))->unre f(); 395 morphType))->unre f();
480 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 396 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
481 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect ), 397 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect ),
482 SkRect::Make(srcRect)); 398 SkRect::Make(srcRect));
483 } 399 }
484 400
485 void apply_morphology_pass(GrDrawContext* drawContext, 401 static void apply_morphology_pass(GrDrawContext* drawContext,
486 const GrClip& clip, 402 const GrClip& clip,
487 GrTexture* texture, 403 GrTexture* texture,
488 const SkIRect& srcRect, 404 const SkIRect& srcRect,
489 const SkIRect& dstRect, 405 const SkIRect& dstRect,
490 int radius, 406 int radius,
491 GrMorphologyEffect::MorphologyType morphType, 407 GrMorphologyEffect::MorphologyType morphType,
492 Gr1DKernelEffect::Direction direction) { 408 Gr1DKernelEffect::Direction direction) {
493 float bounds[2] = { 0.0f, 1.0f }; 409 float bounds[2] = { 0.0f, 1.0f };
494 SkIRect lowerSrcRect = srcRect, lowerDstRect = dstRect; 410 SkIRect lowerSrcRect = srcRect, lowerDstRect = dstRect;
495 SkIRect middleSrcRect = srcRect, middleDstRect = dstRect; 411 SkIRect middleSrcRect = srcRect, middleDstRect = dstRect;
496 SkIRect upperSrcRect = srcRect, upperDstRect = dstRect; 412 SkIRect upperSrcRect = srcRect, upperDstRect = dstRect;
497 if (direction == Gr1DKernelEffect::kX_Direction) { 413 if (direction == Gr1DKernelEffect::kX_Direction) {
498 bounds[0] = (SkIntToScalar(srcRect.left()) + 0.5f) / texture->width(); 414 bounds[0] = (SkIntToScalar(srcRect.left()) + 0.5f) / texture->width();
499 bounds[1] = (SkIntToScalar(srcRect.right()) - 0.5f) / texture->width(); 415 bounds[1] = (SkIntToScalar(srcRect.right()) - 0.5f) / texture->width();
500 lowerSrcRect.fRight = srcRect.left() + radius; 416 lowerSrcRect.fRight = srcRect.left() + radius;
501 lowerDstRect.fRight = dstRect.left() + radius; 417 lowerDstRect.fRight = dstRect.left() + radius;
502 upperSrcRect.fLeft = srcRect.right() - radius; 418 upperSrcRect.fLeft = srcRect.right() - radius;
(...skipping 18 matching lines...) Expand all
521 // Draw upper and lower margins with bounds; middle without. 437 // Draw upper and lower margins with bounds; middle without.
522 apply_morphology_rect(drawContext, clip, texture, lowerSrcRect, lowerDst Rect, radius, 438 apply_morphology_rect(drawContext, clip, texture, lowerSrcRect, lowerDst Rect, radius,
523 morphType, bounds, direction); 439 morphType, bounds, direction);
524 apply_morphology_rect(drawContext, clip, texture, upperSrcRect, upperDst Rect, radius, 440 apply_morphology_rect(drawContext, clip, texture, upperSrcRect, upperDst Rect, radius,
525 morphType, bounds, direction); 441 morphType, bounds, direction);
526 apply_morphology_rect_no_bounds(drawContext, clip, texture, middleSrcRec t, middleDstRect, 442 apply_morphology_rect_no_bounds(drawContext, clip, texture, middleSrcRec t, middleDstRect,
527 radius, morphType, direction); 443 radius, morphType, direction);
528 } 444 }
529 } 445 }
530 446
531 bool apply_morphology(const SkBitmap& input, 447 static sk_sp<SkSpecialImage> apply_morphology(SkSpecialImage* input,
532 const SkIRect& rect, 448 const SkIRect& rect,
533 GrMorphologyEffect::MorphologyType morphType, 449 GrMorphologyEffect::MorphologyType morphType,
534 SkISize radius, 450 SkISize radius) {
535 SkBitmap* dst) { 451 SkAutoTUnref<GrTexture> srcTexture(SkRef(input->peekTexture()));
536 SkAutoTUnref<GrTexture> srcTexture(SkRef(input.getTexture()));
537 SkASSERT(srcTexture); 452 SkASSERT(srcTexture);
538 GrContext* context = srcTexture->getContext(); 453 GrContext* context = srcTexture->getContext();
539 454
540 // setup new clip 455 // setup new clip
541 GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()), 456 GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()),
542 SkIntToScalar(srcTexture->height()))); 457 SkIntToScalar(srcTexture->height())));
543 458
544 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); 459 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
545 GrSurfaceDesc desc; 460 GrSurfaceDesc desc;
546 desc.fFlags = kRenderTarget_GrSurfaceFlag; 461 desc.fFlags = kRenderTarget_GrSurfaceFlag;
547 desc.fWidth = rect.width(); 462 desc.fWidth = rect.width();
548 desc.fHeight = rect.height(); 463 desc.fHeight = rect.height();
549 desc.fConfig = kSkia8888_GrPixelConfig; 464 desc.fConfig = kSkia8888_GrPixelConfig;
550 SkIRect srcRect = rect; 465 SkIRect srcRect = rect;
551 466
467 SkASSERT(radius.width() > 0 || radius.height() > 0);
468
552 if (radius.fWidth > 0) { 469 if (radius.fWidth > 0) {
553 GrTexture* scratch = context->textureProvider()->createApproxTexture(des c); 470 GrTexture* scratch = context->textureProvider()->createApproxTexture(des c);
554 if (nullptr == scratch) { 471 if (!scratch) {
555 return false; 472 return nullptr;
556 } 473 }
557 SkAutoTUnref<GrDrawContext> dstDrawContext( 474 SkAutoTUnref<GrDrawContext> dstDrawContext(
558 context->drawContext(scratch->as RenderTarget())); 475 context->drawContext(scratch->as RenderTarget()));
559 if (!dstDrawContext) { 476 if (!dstDrawContext) {
560 return false; 477 return nullptr;
561 } 478 }
562 479
563 apply_morphology_pass(dstDrawContext, clip, srcTexture, 480 apply_morphology_pass(dstDrawContext, clip, srcTexture,
564 srcRect, dstRect, radius.fWidth, morphType, 481 srcRect, dstRect, radius.fWidth, morphType,
565 Gr1DKernelEffect::kX_Direction); 482 Gr1DKernelEffect::kX_Direction);
566 SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, 483 SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom,
567 dstRect.width(), radius.fHeight); 484 dstRect.width(), radius.fHeight);
568 GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphT ype ? 485 GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphT ype ?
569 SK_ColorWHITE : 486 SK_ColorWHITE :
570 SK_ColorTRANSPARENT; 487 SK_ColorTRANSPARENT;
571 dstDrawContext->clear(&clearRect, clearColor, false); 488 dstDrawContext->clear(&clearRect, clearColor, false);
572 489
573 srcTexture.reset(scratch); 490 srcTexture.reset(scratch);
574 srcRect = dstRect; 491 srcRect = dstRect;
575 } 492 }
576 if (radius.fHeight > 0) { 493 if (radius.fHeight > 0) {
577 GrTexture* scratch = context->textureProvider()->createApproxTexture(des c); 494 GrTexture* scratch = context->textureProvider()->createApproxTexture(des c);
578 if (nullptr == scratch) { 495 if (!scratch) {
579 return false; 496 return nullptr;
580 } 497 }
581 SkAutoTUnref<GrDrawContext> dstDrawContext( 498 SkAutoTUnref<GrDrawContext> dstDrawContext(
582 context->drawContext(scratch->as RenderTarget())); 499 context->drawContext(scratch->as RenderTarget()));
583 if (!dstDrawContext) { 500 if (!dstDrawContext) {
584 return false; 501 return nullptr;
585 } 502 }
586 503
587 apply_morphology_pass(dstDrawContext, clip, srcTexture, 504 apply_morphology_pass(dstDrawContext, clip, srcTexture,
588 srcRect, dstRect, radius.fHeight, morphType, 505 srcRect, dstRect, radius.fHeight, morphType,
589 Gr1DKernelEffect::kY_Direction); 506 Gr1DKernelEffect::kY_Direction);
590 507
591 srcTexture.reset(scratch); 508 srcTexture.reset(scratch);
592 } 509 }
593 GrWrapTextureInBitmap(srcTexture, rect.width(), rect.height(), false, dst); 510
594 return true; 511 return SkSpecialImage::MakeFromGpu(input->internal_getProxy(),
512 SkIRect::MakeWH(rect.width(), rect.height ()),
513 kNeedNewImageUniqueID_SpecialImage,
514 srcTexture);
595 } 515 }
516 #endif
596 517
597 }; 518 sk_sp<SkSpecialImage> SkMorphologyImageFilter::filterImageGeneric(bool dilate,
519 SkSpecialImage * source,
520 const Context& ctx,
521 SkIPoint* offs et) const {
522 SkIPoint inputOffset = SkIPoint::Make(0, 0);
523 sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset)) ;
524 if (!input) {
525 return nullptr;
526 }
598 527
599 bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, 528 SkIRect bounds;
600 Proxy* proxy, 529 input = this->applyCropRect(this->mapContext(ctx), input.get(), &inputOffset , &bounds);
601 const SkBitmap& src, 530 if (!input) {
602 const Context& ctx, 531 return nullptr;
603 SkBitmap* result,
604 SkIPoint* offset) const {
605 SkBitmap input = src;
606 SkIPoint srcOffset = SkIPoint::Make(0, 0);
607 if (!this->filterInputGPUDeprecated(0, proxy, src, ctx, &input, &srcOffset)) {
608 return false;
609 } 532 }
610 SkIRect bounds; 533
611 if (!this->applyCropRectDeprecated(this->mapContext(ctx), proxy, input, &src Offset,
612 &bounds, &input)) {
613 return false;
614 }
615 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 534 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
616 SkIntToScalar(this->radius().height())); 535 SkIntToScalar(this->radius().height()));
617 ctx.ctm().mapVectors(&radius, 1); 536 ctx.ctm().mapVectors(&radius, 1);
618 int width = SkScalarFloorToInt(radius.fX); 537 int width = SkScalarFloorToInt(radius.fX);
619 int height = SkScalarFloorToInt(radius.fY); 538 int height = SkScalarFloorToInt(radius.fY);
620 539
621 if (width < 0 || height < 0) { 540 if (width < 0 || height < 0) {
622 return false; 541 return nullptr;
623 } 542 }
624 543
625 SkIRect srcBounds = bounds; 544 SkIRect srcBounds = bounds;
626 srcBounds.offset(-srcOffset); 545 srcBounds.offset(-inputOffset);
627 if (width == 0 && height == 0) { 546
628 input.extractSubset(result, srcBounds); 547 if (0 == width && 0 == height) {
629 offset->fX = bounds.left(); 548 offset->fX = bounds.left();
630 offset->fY = bounds.top(); 549 offset->fY = bounds.top();
631 return true; 550 return input->makeSubset(srcBounds);
632 } 551 }
633 552
634 GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDila te_MorphologyType 553 #if SK_SUPPORT_GPU
635 : GrMorphologyEffect::kErod e_MorphologyType; 554 if (input->peekTexture()) {
636 if (!apply_morphology(input, srcBounds, type, SkISize::Make(width, height), result)) { 555 auto type = dilate ? GrMorphologyEffect::kDilate_MorphologyType
637 return false; 556 : GrMorphologyEffect::kErode_MorphologyType;
557 sk_sp<SkSpecialImage> result(apply_morphology(input.get(), srcBounds, ty pe,
558 SkISize::Make(width, heigh t)));
559 if (result) {
560 offset->fX = bounds.left();
561 offset->fY = bounds.top();
562 }
563 return result;
564 }
565 #endif
566
567 SkPixmap inputPixmap;
568
569 if (!input->peekPixels(&inputPixmap)) {
570 return nullptr;
571 }
572
573 if (inputPixmap.colorType() != kN32_SkColorType) {
574 return nullptr;
575 }
576
577 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(),
578 inputPixmap.colorType(), inputPixmap.al phaType());
579
580 SkBitmap dst;
581 if (!dst.tryAllocPixels(info)) {
582 return nullptr;
583 }
584
585 SkAutoLockPixels dstLock(dst);
586
587 SkMorphologyImageFilter::Proc procX, procY;
588
589 if (dilate) {
590 procX = SkOpts::dilate_x;
591 procY = SkOpts::dilate_y;
592 } else {
593 procX = SkOpts::erode_x;
594 procY = SkOpts::erode_y;
595 }
596
597 if (width > 0 && height > 0) {
598 SkBitmap tmp;
599 if (!tmp.tryAllocPixels(info)) {
600 return nullptr;
601 }
602
603 SkAutoLockPixels tmpLock(tmp);
604
605 call_proc_X(procX, inputPixmap, &tmp, width, srcBounds);
606 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height( ));
607 call_proc_Y(procY,
608 tmp.getAddr32(tmpBounds.left(), tmpBounds.top()), tmp.rowByt esAsPixels(),
609 &dst, height, tmpBounds);
610 } else if (width > 0) {
611 call_proc_X(procX, inputPixmap, &dst, width, srcBounds);
612 } else if (height > 0) {
613 call_proc_Y(procY,
614 inputPixmap.addr32(srcBounds.left(), srcBounds.top()),
615 inputPixmap.rowBytesAsPixels(),
616 &dst, height, srcBounds);
638 } 617 }
639 offset->fX = bounds.left(); 618 offset->fX = bounds.left();
640 offset->fY = bounds.top(); 619 offset->fY = bounds.top();
641 return true; 620
621 return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
622 SkIRect::MakeWH(bounds.width(), bounds .height()),
623 dst);
642 } 624 }
643 625
644 bool SkDilateImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src, 626 sk_sp<SkSpecialImage> SkDilateImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx,
645 const Context& ctx, 627 SkIPoint* offset) const {
646 SkBitmap* result, SkIPoint* o ffset) const { 628 return this->filterImageGeneric(true, source, ctx, offset);
647 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset);
648 } 629 }
649 630
650 bool SkErodeImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src, 631 sk_sp<SkSpecialImage> SkErodeImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx,
651 const Context& ctx, 632 SkIPoint* offset) const {
652 SkBitmap* result, SkIPoint* of fset) const { 633 return this->filterImageGeneric(false, source, ctx, offset);
653 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset);
654 } 634 }
655 635
656 #endif
OLDNEW
« no previous file with comments | « include/effects/SkMorphologyImageFilter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698