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

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 (again) 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 int shiftPerPixel = SkColorTypeBytesPerPixel(src.colorType()) >> 1;
49 procX(src.addr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
45 radiusX, bounds.width(), bounds.height(), 50 radiusX, bounds.width(), bounds.height(),
46 src.rowBytesAsPixels(), dst->rowBytesAsPixels()); 51 src.rowBytes() >> shiftPerPixel, dst->rowBytesAsPixels());
47 } 52 }
48 53
49 static void callProcY(SkMorphologyImageFilter::Proc procY, const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRect& bounds) 54 static void call_proc_Y(SkMorphologyImageFilter::Proc procY,
50 { 55 const SkPMColor* src, int srcRowBytesAsPixels, SkBitmap* dst,
51 procY(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), 56 int radiusY, const SkIRect& bounds) {
57 procY(src, dst->getAddr32(0, 0),
52 radiusY, bounds.height(), bounds.width(), 58 radiusY, bounds.height(), bounds.width(),
53 src.rowBytesAsPixels(), dst->rowBytesAsPixels()); 59 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 } 60 }
144 61
145 SkRect SkMorphologyImageFilter::computeFastBounds(const SkRect& src) const { 62 SkRect SkMorphologyImageFilter::computeFastBounds(const SkRect& src) const {
146 SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src ) : src; 63 SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src ) : src;
147 bounds.outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height() )); 64 bounds.outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height() ));
148 return bounds; 65 return bounds;
149 } 66 }
150 67
151 SkIRect SkMorphologyImageFilter::onFilterNodeBounds(const SkIRect& src, const Sk Matrix& ctm, 68 SkIRect SkMorphologyImageFilter::onFilterNodeBounds(const SkIRect& src, const Sk Matrix& ctm,
152 MapDirection) const { 69 MapDirection) const {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 } 294 }
378 } 295 }
379 296
380 /////////////////////////////////////////////////////////////////////////////// 297 ///////////////////////////////////////////////////////////////////////////////
381 298
382 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, 299 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
383 Direction direction, 300 Direction direction,
384 int radius, 301 int radius,
385 MorphologyType type) 302 MorphologyType type)
386 : INHERITED(texture, direction, radius) 303 : INHERITED(texture, direction, radius)
387 , fType(type), fUseRange(false) { 304 , fType(type)
305 , fUseRange(false) {
388 this->initClassID<GrMorphologyEffect>(); 306 this->initClassID<GrMorphologyEffect>();
389 } 307 }
390 308
391 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, 309 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
392 Direction direction, 310 Direction direction,
393 int radius, 311 int radius,
394 MorphologyType type, 312 MorphologyType type,
395 float range[2]) 313 float range[2])
396 : INHERITED(texture, direction, radius) 314 : INHERITED(texture, direction, radius)
397 , fType(type), fUseRange(true) { 315 , fType(type)
316 , fUseRange(true) {
398 this->initClassID<GrMorphologyEffect>(); 317 this->initClassID<GrMorphologyEffect>();
399 fRange[0] = range[0]; 318 fRange[0] = range[0];
400 fRange[1] = range[1]; 319 fRange[1] = range[1];
401 } 320 }
402 321
403 GrMorphologyEffect::~GrMorphologyEffect() { 322 GrMorphologyEffect::~GrMorphologyEffect() {
404 } 323 }
405 324
406 void GrMorphologyEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, 325 void GrMorphologyEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
407 GrProcessorKeyBuilder* b) const { 326 GrProcessorKeyBuilder* b) const {
(...skipping 26 matching lines...) Expand all
434 GrProcessorUnitTest::kAlphaTextureIdx; 353 GrProcessorUnitTest::kAlphaTextureIdx;
435 Direction dir = d->fRandom->nextBool() ? kX_Direction : kY_Direction; 354 Direction dir = d->fRandom->nextBool() ? kX_Direction : kY_Direction;
436 static const int kMaxRadius = 10; 355 static const int kMaxRadius = 10;
437 int radius = d->fRandom->nextRangeU(1, kMaxRadius); 356 int radius = d->fRandom->nextRangeU(1, kMaxRadius);
438 MorphologyType type = d->fRandom->nextBool() ? GrMorphologyEffect::kErode_Mo rphologyType : 357 MorphologyType type = d->fRandom->nextBool() ? GrMorphologyEffect::kErode_Mo rphologyType :
439 GrMorphologyEffect::kDilate_Morph ologyType; 358 GrMorphologyEffect::kDilate_Morph ologyType;
440 359
441 return GrMorphologyEffect::Create(d->fTextures[texIdx], dir, radius, type); 360 return GrMorphologyEffect::Create(d->fTextures[texIdx], dir, radius, type);
442 } 361 }
443 362
444 namespace {
445 363
446 364 static void apply_morphology_rect(GrDrawContext* drawContext,
447 void apply_morphology_rect(GrDrawContext* drawContext, 365 const GrClip& clip,
448 const GrClip& clip, 366 GrTexture* texture,
449 GrTexture* texture, 367 const SkIRect& srcRect,
450 const SkIRect& srcRect, 368 const SkIRect& dstRect,
451 const SkIRect& dstRect, 369 int radius,
452 int radius, 370 GrMorphologyEffect::MorphologyType morphType,
453 GrMorphologyEffect::MorphologyType morphType, 371 float bounds[2],
454 float bounds[2], 372 Gr1DKernelEffect::Direction direction) {
455 Gr1DKernelEffect::Direction direction) {
456 GrPaint paint; 373 GrPaint paint;
457 paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture, 374 paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture,
458 direction, 375 direction,
459 radius, 376 radius,
460 morphType, 377 morphType,
461 bounds))->unref() ; 378 bounds))->unref() ;
462 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 379 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
463 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect ), 380 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect ),
464 SkRect::Make(srcRect)); 381 SkRect::Make(srcRect));
465 } 382 }
466 383
467 void apply_morphology_rect_no_bounds(GrDrawContext* drawContext, 384 static void apply_morphology_rect_no_bounds(GrDrawContext* drawContext,
468 const GrClip& clip, 385 const GrClip& clip,
469 GrTexture* texture, 386 GrTexture* texture,
470 const SkIRect& srcRect, 387 const SkIRect& srcRect,
471 const SkIRect& dstRect, 388 const SkIRect& dstRect,
472 int radius, 389 int radius,
473 GrMorphologyEffect::MorphologyType morphTyp e, 390 GrMorphologyEffect::MorphologyType m orphType,
474 Gr1DKernelEffect::Direction direction) { 391 Gr1DKernelEffect::Direction directio n) {
475 GrPaint paint; 392 GrPaint paint;
476 paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture, 393 paint.addColorFragmentProcessor(GrMorphologyEffect::Create(texture,
477 direction, 394 direction,
478 radius, 395 radius,
479 morphType))->unre f(); 396 morphType))->unre f();
480 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 397 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
481 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect ), 398 drawContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect ),
482 SkRect::Make(srcRect)); 399 SkRect::Make(srcRect));
483 } 400 }
484 401
485 void apply_morphology_pass(GrDrawContext* drawContext, 402 static void apply_morphology_pass(GrDrawContext* drawContext,
486 const GrClip& clip, 403 const GrClip& clip,
487 GrTexture* texture, 404 GrTexture* texture,
488 const SkIRect& srcRect, 405 const SkIRect& srcRect,
489 const SkIRect& dstRect, 406 const SkIRect& dstRect,
490 int radius, 407 int radius,
491 GrMorphologyEffect::MorphologyType morphType, 408 GrMorphologyEffect::MorphologyType morphType,
492 Gr1DKernelEffect::Direction direction) { 409 Gr1DKernelEffect::Direction direction) {
493 float bounds[2] = { 0.0f, 1.0f }; 410 float bounds[2] = { 0.0f, 1.0f };
494 SkIRect lowerSrcRect = srcRect, lowerDstRect = dstRect; 411 SkIRect lowerSrcRect = srcRect, lowerDstRect = dstRect;
495 SkIRect middleSrcRect = srcRect, middleDstRect = dstRect; 412 SkIRect middleSrcRect = srcRect, middleDstRect = dstRect;
496 SkIRect upperSrcRect = srcRect, upperDstRect = dstRect; 413 SkIRect upperSrcRect = srcRect, upperDstRect = dstRect;
497 if (direction == Gr1DKernelEffect::kX_Direction) { 414 if (direction == Gr1DKernelEffect::kX_Direction) {
498 bounds[0] = (SkIntToScalar(srcRect.left()) + 0.5f) / texture->width(); 415 bounds[0] = (SkIntToScalar(srcRect.left()) + 0.5f) / texture->width();
499 bounds[1] = (SkIntToScalar(srcRect.right()) - 0.5f) / texture->width(); 416 bounds[1] = (SkIntToScalar(srcRect.right()) - 0.5f) / texture->width();
500 lowerSrcRect.fRight = srcRect.left() + radius; 417 lowerSrcRect.fRight = srcRect.left() + radius;
501 lowerDstRect.fRight = dstRect.left() + radius; 418 lowerDstRect.fRight = dstRect.left() + radius;
502 upperSrcRect.fLeft = srcRect.right() - radius; 419 upperSrcRect.fLeft = srcRect.right() - radius;
(...skipping 18 matching lines...) Expand all
521 // Draw upper and lower margins with bounds; middle without. 438 // Draw upper and lower margins with bounds; middle without.
522 apply_morphology_rect(drawContext, clip, texture, lowerSrcRect, lowerDst Rect, radius, 439 apply_morphology_rect(drawContext, clip, texture, lowerSrcRect, lowerDst Rect, radius,
523 morphType, bounds, direction); 440 morphType, bounds, direction);
524 apply_morphology_rect(drawContext, clip, texture, upperSrcRect, upperDst Rect, radius, 441 apply_morphology_rect(drawContext, clip, texture, upperSrcRect, upperDst Rect, radius,
525 morphType, bounds, direction); 442 morphType, bounds, direction);
526 apply_morphology_rect_no_bounds(drawContext, clip, texture, middleSrcRec t, middleDstRect, 443 apply_morphology_rect_no_bounds(drawContext, clip, texture, middleSrcRec t, middleDstRect,
527 radius, morphType, direction); 444 radius, morphType, direction);
528 } 445 }
529 } 446 }
530 447
531 bool apply_morphology(const SkBitmap& input, 448 static sk_sp<SkSpecialImage> apply_morphology(SkSpecialImage* input,
532 const SkIRect& rect, 449 const SkIRect& rect,
533 GrMorphologyEffect::MorphologyType morphType, 450 GrMorphologyEffect::MorphologyType morphType,
534 SkISize radius, 451 SkISize radius) {
535 SkBitmap* dst) { 452 SkAutoTUnref<GrTexture> srcTexture(SkRef(input->peekTexture()));
536 SkAutoTUnref<GrTexture> srcTexture(SkRef(input.getTexture()));
537 SkASSERT(srcTexture); 453 SkASSERT(srcTexture);
538 GrContext* context = srcTexture->getContext(); 454 GrContext* context = srcTexture->getContext();
539 455
540 // setup new clip 456 // setup new clip
541 GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()), 457 GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()),
542 SkIntToScalar(srcTexture->height()))); 458 SkIntToScalar(srcTexture->height())));
543 459
544 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); 460 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
545 GrSurfaceDesc desc; 461 GrSurfaceDesc desc;
546 desc.fFlags = kRenderTarget_GrSurfaceFlag; 462 desc.fFlags = kRenderTarget_GrSurfaceFlag;
547 desc.fWidth = rect.width(); 463 desc.fWidth = rect.width();
548 desc.fHeight = rect.height(); 464 desc.fHeight = rect.height();
549 desc.fConfig = kSkia8888_GrPixelConfig; 465 desc.fConfig = kSkia8888_GrPixelConfig;
550 SkIRect srcRect = rect; 466 SkIRect srcRect = rect;
551 467
468 SkASSERT(radius.width() > 0 || radius.height() > 0);
469
552 if (radius.fWidth > 0) { 470 if (radius.fWidth > 0) {
553 GrTexture* scratch = context->textureProvider()->createApproxTexture(des c); 471 GrTexture* scratch = context->textureProvider()->createApproxTexture(des c);
554 if (nullptr == scratch) { 472 if (!scratch) {
555 return false; 473 return nullptr;
556 } 474 }
557 SkAutoTUnref<GrDrawContext> dstDrawContext( 475 SkAutoTUnref<GrDrawContext> dstDrawContext(
558 context->drawContext(scratch->as RenderTarget())); 476 context->drawContext(scratch->as RenderTarget()));
559 if (!dstDrawContext) { 477 if (!dstDrawContext) {
560 return false; 478 return nullptr;
561 } 479 }
562 480
563 apply_morphology_pass(dstDrawContext, clip, srcTexture, 481 apply_morphology_pass(dstDrawContext, clip, srcTexture,
564 srcRect, dstRect, radius.fWidth, morphType, 482 srcRect, dstRect, radius.fWidth, morphType,
565 Gr1DKernelEffect::kX_Direction); 483 Gr1DKernelEffect::kX_Direction);
566 SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, 484 SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom,
567 dstRect.width(), radius.fHeight); 485 dstRect.width(), radius.fHeight);
568 GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphT ype ? 486 GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphT ype ?
569 SK_ColorWHITE : 487 SK_ColorWHITE :
570 SK_ColorTRANSPARENT; 488 SK_ColorTRANSPARENT;
571 dstDrawContext->clear(&clearRect, clearColor, false); 489 dstDrawContext->clear(&clearRect, clearColor, false);
572 490
573 srcTexture.reset(scratch); 491 srcTexture.reset(scratch);
574 srcRect = dstRect; 492 srcRect = dstRect;
575 } 493 }
576 if (radius.fHeight > 0) { 494 if (radius.fHeight > 0) {
577 GrTexture* scratch = context->textureProvider()->createApproxTexture(des c); 495 GrTexture* scratch = context->textureProvider()->createApproxTexture(des c);
578 if (nullptr == scratch) { 496 if (!scratch) {
579 return false; 497 return nullptr;
580 } 498 }
581 SkAutoTUnref<GrDrawContext> dstDrawContext( 499 SkAutoTUnref<GrDrawContext> dstDrawContext(
582 context->drawContext(scratch->as RenderTarget())); 500 context->drawContext(scratch->as RenderTarget()));
583 if (!dstDrawContext) { 501 if (!dstDrawContext) {
584 return false; 502 return nullptr;
585 } 503 }
586 504
587 apply_morphology_pass(dstDrawContext, clip, srcTexture, 505 apply_morphology_pass(dstDrawContext, clip, srcTexture,
588 srcRect, dstRect, radius.fHeight, morphType, 506 srcRect, dstRect, radius.fHeight, morphType,
589 Gr1DKernelEffect::kY_Direction); 507 Gr1DKernelEffect::kY_Direction);
590 508
591 srcTexture.reset(scratch); 509 srcTexture.reset(scratch);
592 } 510 }
593 GrWrapTextureInBitmap(srcTexture, rect.width(), rect.height(), false, dst); 511
594 return true; 512 return SkSpecialImage::MakeFromGpu(input->internal_getProxy(),
513 SkIRect::MakeWH(rect.width(), rect.height ()),
514 kNeedNewImageUniqueID_SpecialImage,
515 srcTexture);
595 } 516 }
517 #endif
596 518
597 }; 519 sk_sp<SkSpecialImage> SkMorphologyImageFilter::filterImageGeneric(bool dilate,
520 SkSpecialImage * source,
521 const Context& ctx,
522 SkIPoint* offs et) const {
523 SkIPoint inputOffset = SkIPoint::Make(0, 0);
524 sk_sp<SkSpecialImage> input(this->filterInput(0, source, ctx, &inputOffset)) ;
525 if (!input) {
526 return nullptr;
527 }
598 528
599 bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, 529 SkIRect bounds;
600 Proxy* proxy, 530 input = this->applyCropRect(this->mapContext(ctx), input.get(), &inputOffset , &bounds);
601 const SkBitmap& src, 531 if (!input) {
602 const Context& ctx, 532 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 } 533 }
610 SkIRect bounds; 534
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()), 535 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
616 SkIntToScalar(this->radius().height())); 536 SkIntToScalar(this->radius().height()));
617 ctx.ctm().mapVectors(&radius, 1); 537 ctx.ctm().mapVectors(&radius, 1);
618 int width = SkScalarFloorToInt(radius.fX); 538 int width = SkScalarFloorToInt(radius.fX);
619 int height = SkScalarFloorToInt(radius.fY); 539 int height = SkScalarFloorToInt(radius.fY);
620 540
621 if (width < 0 || height < 0) { 541 if (width < 0 || height < 0) {
622 return false; 542 return nullptr;
623 } 543 }
624 544
625 SkIRect srcBounds = bounds; 545 SkIRect srcBounds = bounds;
626 srcBounds.offset(-srcOffset); 546 srcBounds.offset(-inputOffset);
627 if (width == 0 && height == 0) { 547
628 input.extractSubset(result, srcBounds); 548 if (0 == width && 0 == height) {
629 offset->fX = bounds.left(); 549 offset->fX = bounds.left();
630 offset->fY = bounds.top(); 550 offset->fY = bounds.top();
631 return true; 551 return input->makeSubset(srcBounds);
632 } 552 }
633 553
634 GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDila te_MorphologyType 554 #if SK_SUPPORT_GPU
635 : GrMorphologyEffect::kErod e_MorphologyType; 555 if (input->peekTexture()) {
636 if (!apply_morphology(input, srcBounds, type, SkISize::Make(width, height), result)) { 556 auto type = dilate ? GrMorphologyEffect::kDilate_MorphologyType
637 return false; 557 : GrMorphologyEffect::kErode_MorphologyType;
558 sk_sp<SkSpecialImage> result(apply_morphology(input.get(), srcBounds, ty pe,
559 SkISize::Make(width, heigh t)));
560 if (result) {
561 offset->fX = bounds.left();
562 offset->fY = bounds.top();
563 }
564 return result;
565 }
566 #endif
567
568 SkPixmap inputPixmap;
569
570 if (!input->peekPixels(&inputPixmap)) {
571 return nullptr;
572 }
573
574 if (inputPixmap.colorType() != kN32_SkColorType) {
575 return nullptr;
576 }
577
578 SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(),
579 inputPixmap.colorType(), inputPixmap.al phaType());
580
581 SkBitmap dst;
582 if (!dst.tryAllocPixels(info)) {
583 return nullptr;
584 }
585
586 SkAutoLockPixels dstLock(dst);
587
588 SkMorphologyImageFilter::Proc procX, procY;
589
590 if (dilate) {
591 procX = SkOpts::dilate_x;
592 procY = SkOpts::dilate_y;
593 } else {
594 procX = SkOpts::erode_x;
595 procY = SkOpts::erode_y;
596 }
597
598 if (width > 0 && height > 0) {
599 SkBitmap tmp;
600 if (!tmp.tryAllocPixels(info)) {
601 return nullptr;
602 }
603
604 SkAutoLockPixels tmpLock(tmp);
605
606 call_proc_X(procX, inputPixmap, &tmp, width, srcBounds);
607 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height( ));
608 call_proc_Y(procY,
609 tmp.getAddr32(tmpBounds.left(), tmpBounds.top()), tmp.rowByt esAsPixels(),
610 &dst, height, tmpBounds);
611 } else if (width > 0) {
612 call_proc_X(procX, inputPixmap, &dst, width, srcBounds);
613 } else if (height > 0) {
614 int shiftPerPixel = SkColorTypeBytesPerPixel(inputPixmap.colorType()) >> 1;
Stephen White 2016/03/24 15:16:34 As a side note, could we have SkPixmap::getRowByte
robertphillips 2016/03/24 18:08:13 Done.
615 call_proc_Y(procY,
616 inputPixmap.addr32(srcBounds.left(), srcBounds.top()),
617 inputPixmap.rowBytes() >> shiftPerPixel,
618 &dst, height, srcBounds);
638 } 619 }
639 offset->fX = bounds.left(); 620 offset->fX = bounds.left();
640 offset->fY = bounds.top(); 621 offset->fY = bounds.top();
641 return true; 622
623 return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
624 SkIRect::MakeWH(bounds.width(), bounds .height()),
Stephen White 2016/03/24 14:57:02 Not new to this patch, but could we make the subse
robertphillips 2016/03/24 18:08:13 Acknowledged.
625 dst);
642 } 626 }
643 627
644 bool SkDilateImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src, 628 sk_sp<SkSpecialImage> SkDilateImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx,
645 const Context& ctx, 629 SkIPoint* offset) const {
646 SkBitmap* result, SkIPoint* o ffset) const { 630 return this->filterImageGeneric(true, source, ctx, offset);
Stephen White 2016/03/24 14:57:03 Not new to this patch, but we should probably repl
robertphillips 2016/03/24 18:08:13 Let me do that in a follow up CL. I think this CL
647 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset);
648 } 631 }
649 632
650 bool SkErodeImageFilter::filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src, 633 sk_sp<SkSpecialImage> SkErodeImageFilter::onFilterImage(SkSpecialImage* source, const Context& ctx,
651 const Context& ctx, 634 SkIPoint* offset) const {
652 SkBitmap* result, SkIPoint* of fset) const { 635 return this->filterImageGeneric(false, source, ctx, offset);
653 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset);
654 } 636 }
655 637
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