105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org/* 205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org * Copyright 2012 The Android Open Source Project 305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org * 405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org * Use of this source code is governed by a BSD-style license that can be 505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org * found in the LICENSE file. 605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org */ 705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org#include "SkMorphologyImageFilter.h" 964a0ec36555352ec31aa7c5a7630a5d042b010badjsollen@google.com#include "SkBitmap.h" 1005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org#include "SkColorPriv.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 13c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com#include "SkRect.h" 147a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org#include "SkMorphology_opts.h" 15cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 16302cffba86a188373c99833d83392f33e6014542senorblanco@chromium.org#include "GrContext.h" 17605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h" 18302cffba86a188373c99833d83392f33e6014542senorblanco@chromium.org#include "GrTexture.h" 19eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "effects/Gr1DKernelEffect.h" 20b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 2130ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/builders/GrGLProgramBuilder.h" 22cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 2305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 242bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.orgSkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, 252bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int radiusY, 262bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkImageFilter* input, 2724e06d5244ae96e440410e1d76e039983b2efac9senorblanco const CropRect* cropRect) 2824e06d5244ae96e440410e1d76e039983b2efac9senorblanco : INHERITED(1, &input, cropRect), fRadius(SkISize::Make(radiusX, radiusY)) { 2905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 3005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 318b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const { 3205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org this->INHERITED::flatten(buffer); 3375589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com buffer.writeInt(fRadius.fWidth); 3475589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com buffer.writeInt(fRadius.fHeight); 3505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 3605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 377a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.orgenum MorphDirection { 387a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org kX, kY 397a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org}; 407a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org 417a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.orgtemplate<MorphDirection direction> 4205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.orgstatic void erode(const SkPMColor* src, SkPMColor* dst, 4305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int radius, int width, int height, 447a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org int srcStride, int dstStride) 4505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org{ 467a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int srcStrideX = direction == kX ? 1 : srcStride; 477a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int dstStrideX = direction == kX ? 1 : dstStride; 487a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int srcStrideY = direction == kX ? srcStride : 1; 497a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int dstStrideY = direction == kX ? dstStride : 1; 5056dd630c41d662bcf2a3f08100f2c6accda05ba9senorblanco@chromium.org radius = SkMin32(radius, width - 1); 5156dd630c41d662bcf2a3f08100f2c6accda05ba9senorblanco@chromium.org const SkPMColor* upperSrc = src + radius * srcStrideX; 5205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (int x = 0; x < width; ++x) { 5305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org const SkPMColor* lp = src; 5405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org const SkPMColor* up = upperSrc; 5505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org SkPMColor* dptr = dst; 5605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (int y = 0; y < height; ++y) { 5705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int minB = 255, minG = 255, minR = 255, minA = 255; 5805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (const SkPMColor* p = lp; p <= up; p += srcStrideX) { 5905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int b = SkGetPackedB32(*p); 6005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int g = SkGetPackedG32(*p); 6105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int r = SkGetPackedR32(*p); 6205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int a = SkGetPackedA32(*p); 6305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (b < minB) minB = b; 6405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (g < minG) minG = g; 6505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (r < minR) minR = r; 6605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (a < minA) minA = a; 6705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 6805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org *dptr = SkPackARGB32(minA, minR, minG, minB); 6905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org dptr += dstStrideY; 7005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org lp += srcStrideY; 7105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org up += srcStrideY; 7205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 7305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (x >= radius) src += srcStrideX; 7405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (x + radius < width - 1) upperSrc += srcStrideX; 7505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org dst += dstStrideX; 7605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 7705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 7805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 797a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.orgtemplate<MorphDirection direction> 8005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.orgstatic void dilate(const SkPMColor* src, SkPMColor* dst, 8105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int radius, int width, int height, 827a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org int srcStride, int dstStride) 8305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org{ 847a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int srcStrideX = direction == kX ? 1 : srcStride; 857a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int dstStrideX = direction == kX ? 1 : dstStride; 867a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int srcStrideY = direction == kX ? srcStride : 1; 877a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int dstStrideY = direction == kX ? dstStride : 1; 8856dd630c41d662bcf2a3f08100f2c6accda05ba9senorblanco@chromium.org radius = SkMin32(radius, width - 1); 8956dd630c41d662bcf2a3f08100f2c6accda05ba9senorblanco@chromium.org const SkPMColor* upperSrc = src + radius * srcStrideX; 9005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (int x = 0; x < width; ++x) { 9105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org const SkPMColor* lp = src; 9205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org const SkPMColor* up = upperSrc; 9305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org SkPMColor* dptr = dst; 9405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (int y = 0; y < height; ++y) { 9505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int maxB = 0, maxG = 0, maxR = 0, maxA = 0; 9605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (const SkPMColor* p = lp; p <= up; p += srcStrideX) { 9705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int b = SkGetPackedB32(*p); 9805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int g = SkGetPackedG32(*p); 9905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int r = SkGetPackedR32(*p); 10005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int a = SkGetPackedA32(*p); 10105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (b > maxB) maxB = b; 10205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (g > maxG) maxG = g; 10305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (r > maxR) maxR = r; 10405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (a > maxA) maxA = a; 10505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 10605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org *dptr = SkPackARGB32(maxA, maxR, maxG, maxB); 10705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org dptr += dstStrideY; 10805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org lp += srcStrideY; 10905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org up += srcStrideY; 11005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 11105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (x >= radius) src += srcStrideX; 11205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (x + radius < width - 1) upperSrc += srcStrideX; 11305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org dst += dstStrideX; 11405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 11505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 11605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1170ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgstatic void callProcX(SkMorphologyImageFilter::Proc procX, const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRect& bounds) 11805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org{ 1190ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org procX(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), 1200ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org radiusX, bounds.width(), bounds.height(), 1210ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org src.rowBytesAsPixels(), dst->rowBytesAsPixels()); 12205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 12305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1240ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgstatic void callProcY(SkMorphologyImageFilter::Proc procY, const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRect& bounds) 12505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org{ 1260ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org procY(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), 1270ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org radiusY, bounds.height(), bounds.width(), 1280ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org src.rowBytesAsPixels(), dst->rowBytesAsPixels()); 12905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 13005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1310ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgbool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc procX, 1320ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org SkMorphologyImageFilter::Proc procY, 1330ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proxy* proxy, 1340ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org const SkBitmap& source, 1354cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const Context& ctx, 1360ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org SkBitmap* dst, 137ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkIPoint* offset) const { 13868400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org SkBitmap src = source; 1396776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint srcOffset = SkIPoint::Make(0, 0); 1404cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { 14168400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org return false; 14268400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org } 14368400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org 14428fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org if (src.colorType() != kN32_SkColorType) { 14505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return false; 14605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 14705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1488fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkIRect bounds; 149118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { 1508fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return false; 1518fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 1528fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org 15305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org SkAutoLockPixels alp(src); 15405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (!src.getPixels()) { 15505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return false; 15605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 15705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 158848250415eddc54075f7eb8795e8db79e749c6abreed if (!dst->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height()))) { 159cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org return false; 160cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org } 16105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1622bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 1632bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIntToScalar(this->radius().height())); 1644cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org ctx.ctm().mapVectors(&radius, 1); 1652bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int width = SkScalarFloorToInt(radius.fX); 1662bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int height = SkScalarFloorToInt(radius.fY); 16705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 16805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (width < 0 || height < 0) { 16905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return false; 17005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 17105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1722bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIRect srcBounds = bounds; 1732bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org srcBounds.offset(-srcOffset); 1742bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org 17505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (width == 0 && height == 0) { 1762bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org src.extractSubset(dst, srcBounds); 1776776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fX = bounds.left(); 1786776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fY = bounds.top(); 17905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return true; 18005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 18105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 18205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org SkBitmap temp; 183848250415eddc54075f7eb8795e8db79e749c6abreed if (!temp.tryAllocPixels(dst->info())) { 18405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return false; 18505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 18605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 18705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (width > 0 && height > 0) { 1880ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org callProcX(procX, src, &temp, width, srcBounds); 1892bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height()); 1900ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org callProcY(procY, temp, dst, height, tmpBounds); 19105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } else if (width > 0) { 1920ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org callProcX(procX, src, dst, width, srcBounds); 19305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } else if (height > 0) { 1940ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org callProcY(procY, src, dst, height, srcBounds); 19505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 1962bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org offset->fX = bounds.left(); 1972bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org offset->fY = bounds.top(); 19805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return true; 19905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 20005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 2010ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgbool SkErodeImageFilter::onFilterImage(Proxy* proxy, 2024cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const SkBitmap& source, const Context& ctx, 203ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* dst, SkIPoint* offset) const { 2040ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proc erodeXProc = SkMorphologyGetPlatformProc(kErodeX_SkMorphologyProcType); 2050ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!erodeXProc) { 2060ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org erodeXProc = erode<kX>; 2071878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com } 2080ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proc erodeYProc = SkMorphologyGetPlatformProc(kErodeY_SkMorphologyProcType); 2090ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!erodeYProc) { 2100ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org erodeYProc = erode<kY>; 2111878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com } 2124cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGeneric(erodeXProc, erodeYProc, proxy, source, ctx, dst, offset); 2130ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org} 2141878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com 2150ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgbool SkDilateImageFilter::onFilterImage(Proxy* proxy, 2164cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const SkBitmap& source, const Context& ctx, 217ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* dst, SkIPoint* offset) const { 2180ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proc dilateXProc = SkMorphologyGetPlatformProc(kDilateX_SkMorphologyProcType); 2190ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!dilateXProc) { 2200ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org dilateXProc = dilate<kX>; 2211878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com } 2220ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proc dilateYProc = SkMorphologyGetPlatformProc(kDilateY_SkMorphologyProcType); 2230ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!dilateYProc) { 2240ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org dilateYProc = dilate<kY>; 2251878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com } 2264cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctx, dst, offset); 22705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 22805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 229336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.orgvoid SkMorphologyImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { 230336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (getInput(0)) { 231336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org getInput(0)->computeFastBounds(src, dst); 232336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } else { 233336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org *dst = src; 234336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 235336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org dst->outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height())); 236336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org} 237336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org 238c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.orgbool SkMorphologyImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 239c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* dst) const { 240c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect bounds = src; 241c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 242c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIntToScalar(this->radius().height())); 243c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org ctm.mapVectors(&radius, 1); 244c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org bounds.outset(SkScalarCeilToInt(radius.x()), SkScalarCeilToInt(radius.y())); 2451150a6d151571fb6ee816dadec844ae7ab53948asenorblanco if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { 2461150a6d151571fb6ee816dadec844ae7ab53948asenorblanco return false; 2471150a6d151571fb6ee816dadec844ae7ab53948asenorblanco } 248c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org *dst = bounds; 249c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org return true; 250c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org} 251c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 2529fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkErodeImageFilter::CreateProc(SkReadBuffer& buffer) { 2539fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 2549fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int width = buffer.readInt(); 2559fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int height = buffer.readInt(); 25624e06d5244ae96e440410e1d76e039983b2efac9senorblanco return Create(width, height, common.getInput(0), &common.cropRect()); 2579fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 2589fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 2599fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkDilateImageFilter::CreateProc(SkReadBuffer& buffer) { 2609fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 2619fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int width = buffer.readInt(); 2629fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int height = buffer.readInt(); 26324e06d5244ae96e440410e1d76e039983b2efac9senorblanco return Create(width, height, common.getInput(0), &common.cropRect()); 2649fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 2659fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 266f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#ifndef SK_IGNORE_TO_STRING 267f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillipsvoid SkErodeImageFilter::toString(SkString* str) const { 268f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->appendf("SkErodeImageFilter: ("); 269f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->appendf("radius: (%d,%d)", this->radius().fWidth, this->radius().fHeight); 270f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->append(")"); 271f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips} 272f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#endif 273f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips 274f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#ifndef SK_IGNORE_TO_STRING 275f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillipsvoid SkDilateImageFilter::toString(SkString* str) const { 276f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->appendf("SkDilateImageFilter: ("); 277f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->appendf("radius: (%d,%d)", this->radius().fWidth, this->radius().fHeight); 278f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips str->append(")"); 279f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips} 280f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips#endif 281f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips 282cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 28384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 28484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 28584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/** 28684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org * Morphology effects. Depending upon the type of morphology, either the 28784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org * component-wise min (Erode_Type) or max (Dilate_Type) of all pixels in the 28884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org * kernel is selected as the new color. The new color is modulated by the input 28984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org * color. 29084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org */ 29184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgclass GrMorphologyEffect : public Gr1DKernelEffect { 29284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 29384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgpublic: 29484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 29584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org enum MorphologyType { 29684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org kErode_MorphologyType, 29784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org kDilate_MorphologyType, 29884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org }; 29984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 300b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrFragmentProcessor* Create(GrTexture* tex, Direction dir, int radius, 301b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt MorphologyType type) { 30255fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type)); 3030ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 3040ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 30580a61df691bd5756dfbcbc57441806f2594511d8cwallez static GrFragmentProcessor* Create(GrTexture* tex, Direction dir, int radius, 30680a61df691bd5756dfbcbc57441806f2594511d8cwallez MorphologyType type, float bounds[2]) { 30780a61df691bd5756dfbcbc57441806f2594511d8cwallez return SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type, bounds)); 30880a61df691bd5756dfbcbc57441806f2594511d8cwallez } 30980a61df691bd5756dfbcbc57441806f2594511d8cwallez 31084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org virtual ~GrMorphologyEffect(); 31184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 31284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org MorphologyType type() const { return fType; } 31380a61df691bd5756dfbcbc57441806f2594511d8cwallez bool useRange() const { return fUseRange; } 31480a61df691bd5756dfbcbc57441806f2594511d8cwallez const float* range() const { return fRange; } 31584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 31636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "Morphology"; } 31784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 318cfc18867d982119d9dc2888bf09f1093012daaddjvanverth void getGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override; 31984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 32036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrGLFragmentProcessor* createGLInstance() const override; 32184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 32284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgprotected: 32384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 32484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org MorphologyType fType; 32580a61df691bd5756dfbcbc57441806f2594511d8cwallez bool fUseRange; 32680a61df691bd5756dfbcbc57441806f2594511d8cwallez float fRange[2]; 32784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 32884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgprivate: 32936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onIsEqual(const GrFragmentProcessor&) const override; 33068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 33136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onComputeInvariantOutput(GrInvariantOutput* inout) const override; 3321a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel 3330ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType); 33480a61df691bd5756dfbcbc57441806f2594511d8cwallez GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType, float bounds[2]); 3350ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 336b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 33784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 33884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org typedef Gr1DKernelEffect INHERITED; 33984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org}; 34084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 34184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 34284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 343b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLMorphologyEffect : public GrGLFragmentProcessor { 34484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgpublic: 345eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLMorphologyEffect(const GrProcessor&); 34684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 3471598899975ecc85b003a59740b588d1ddbcedb09joshualitt virtual void emitCode(GrGLFPBuilder*, 348b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor&, 34947d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const char* outputColor, 35047d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const char* inputColor, 35177af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com const TransformedCoordsArray&, 35236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const TextureSamplerArray&) override; 35384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 354cfc18867d982119d9dc2888bf09f1093012daaddjvanverth static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b); 35584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 35636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void setData(const GrGLProgramDataManager&, const GrProcessor&) override; 35784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 35884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgprivate: 35984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); } 36084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 3617510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen int fRadius; 36280a61df691bd5756dfbcbc57441806f2594511d8cwallez Gr1DKernelEffect::Direction fDirection; 36380a61df691bd5756dfbcbc57441806f2594511d8cwallez bool fUseRange; 3647510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrMorphologyEffect::MorphologyType fType; 36580a61df691bd5756dfbcbc57441806f2594511d8cwallez GrGLProgramDataManager::UniformHandle fPixelSizeUni; 36680a61df691bd5756dfbcbc57441806f2594511d8cwallez GrGLProgramDataManager::UniformHandle fRangeUni; 36784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 368b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 36984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org}; 37084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 371eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLMorphologyEffect::GrGLMorphologyEffect(const GrProcessor& proc) { 372b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); 37384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org fRadius = m.radius(); 37480a61df691bd5756dfbcbc57441806f2594511d8cwallez fDirection = m.direction(); 37580a61df691bd5756dfbcbc57441806f2594511d8cwallez fUseRange = m.useRange(); 37684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org fType = m.type(); 37784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 37884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 3791598899975ecc85b003a59740b588d1ddbcedb09joshualittvoid GrGLMorphologyEffect::emitCode(GrGLFPBuilder* builder, 380b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor&, 38147d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const char* outputColor, 38247d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const char* inputColor, 38377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com const TransformedCoordsArray& coords, 38447d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const TextureSamplerArray& samplers) { 38580a61df691bd5756dfbcbc57441806f2594511d8cwallez fPixelSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 38680a61df691bd5756dfbcbc57441806f2594511d8cwallez kFloat_GrSLType, kDefault_GrSLPrecision, 38780a61df691bd5756dfbcbc57441806f2594511d8cwallez "PixelSize"); 38880a61df691bd5756dfbcbc57441806f2594511d8cwallez const char* pixelSizeInc = builder->getUniformCStr(fPixelSizeUni); 38980a61df691bd5756dfbcbc57441806f2594511d8cwallez fRangeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 39080a61df691bd5756dfbcbc57441806f2594511d8cwallez kVec2f_GrSLType, kDefault_GrSLPrecision, 39180a61df691bd5756dfbcbc57441806f2594511d8cwallez "Range"); 39280a61df691bd5756dfbcbc57441806f2594511d8cwallez const char* range = builder->getUniformCStr(fRangeUni); 39384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 39429bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 39530ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); 39684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org const char* func; 39784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org switch (fType) { 39884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org case GrMorphologyEffect::kErode_MorphologyType: 39930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", outputColor); 40084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org func = "min"; 40184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 40284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org case GrMorphologyEffect::kDilate_MorphologyType: 40330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor); 40484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org func = "max"; 40584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 40684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org default: 40788cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unexpected type"); 40884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org func = ""; // suppress warning 40984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 41084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org } 41184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 41280a61df691bd5756dfbcbc57441806f2594511d8cwallez const char* dir; 41380a61df691bd5756dfbcbc57441806f2594511d8cwallez switch (fDirection) { 41480a61df691bd5756dfbcbc57441806f2594511d8cwallez case Gr1DKernelEffect::kX_Direction: 41580a61df691bd5756dfbcbc57441806f2594511d8cwallez dir = "x"; 41680a61df691bd5756dfbcbc57441806f2594511d8cwallez break; 41780a61df691bd5756dfbcbc57441806f2594511d8cwallez case Gr1DKernelEffect::kY_Direction: 41880a61df691bd5756dfbcbc57441806f2594511d8cwallez dir = "y"; 41980a61df691bd5756dfbcbc57441806f2594511d8cwallez break; 42080a61df691bd5756dfbcbc57441806f2594511d8cwallez default: 42180a61df691bd5756dfbcbc57441806f2594511d8cwallez SkFAIL("Unknown filter direction."); 42280a61df691bd5756dfbcbc57441806f2594511d8cwallez dir = ""; // suppress warning 42380a61df691bd5756dfbcbc57441806f2594511d8cwallez } 42480a61df691bd5756dfbcbc57441806f2594511d8cwallez 42580a61df691bd5756dfbcbc57441806f2594511d8cwallez // vec2 coord = coord2D; 42680a61df691bd5756dfbcbc57441806f2594511d8cwallez fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); 42780a61df691bd5756dfbcbc57441806f2594511d8cwallez // coord.x -= radius * pixelSize; 42880a61df691bd5756dfbcbc57441806f2594511d8cwallez fsBuilder->codeAppendf("\t\tcoord.%s -= %d.0 * %s; \n", dir, fRadius, pixelSizeInc); 42980a61df691bd5756dfbcbc57441806f2594511d8cwallez if (fUseRange) { 43080a61df691bd5756dfbcbc57441806f2594511d8cwallez // highBound = min(highBound, coord.x + (width-1) * pixelSize); 43180a61df691bd5756dfbcbc57441806f2594511d8cwallez fsBuilder->codeAppendf("\t\tfloat highBound = min(%s.y, coord.%s + %f * %s);", 43280a61df691bd5756dfbcbc57441806f2594511d8cwallez range, dir, float(width() - 1), pixelSizeInc); 43380a61df691bd5756dfbcbc57441806f2594511d8cwallez // coord.x = max(lowBound, coord.x); 43480a61df691bd5756dfbcbc57441806f2594511d8cwallez fsBuilder->codeAppendf("\t\tcoord.%s = max(%s.x, coord.%s);", dir, range, dir); 43580a61df691bd5756dfbcbc57441806f2594511d8cwallez } 43680a61df691bd5756dfbcbc57441806f2594511d8cwallez fsBuilder->codeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", width()); 43730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s = %s(%s, ", outputColor, func, outputColor); 43830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], "coord"); 43930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(");\n"); 44080a61df691bd5756dfbcbc57441806f2594511d8cwallez // coord.x += pixelSize; 44180a61df691bd5756dfbcbc57441806f2594511d8cwallez fsBuilder->codeAppendf("\t\t\tcoord.%s += %s;\n", dir, pixelSizeInc); 44280a61df691bd5756dfbcbc57441806f2594511d8cwallez if (fUseRange) { 44380a61df691bd5756dfbcbc57441806f2594511d8cwallez // coord.x = min(highBound, coord.x); 44480a61df691bd5756dfbcbc57441806f2594511d8cwallez fsBuilder->codeAppendf("\t\t\tcoord.%s = min(highBound, coord.%s);", dir, dir); 44580a61df691bd5756dfbcbc57441806f2594511d8cwallez } 44630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t}\n"); 447f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com SkString modulate; 448089f8de82d6c342faa9170d8c19d8504177bf5fbegdaniel GrGLSLMulVarBy4f(&modulate, outputColor, inputColor); 44930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(modulate.c_str()); 45084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 45184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 452b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GrGLMorphologyEffect::GenKey(const GrProcessor& proc, 453cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, GrProcessorKeyBuilder* b) { 454b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); 45563e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon uint32_t key = static_cast<uint32_t>(m.radius()); 45684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org key |= (m.type() << 8); 45780a61df691bd5756dfbcbc57441806f2594511d8cwallez key |= (m.direction() << 9); 45880a61df691bd5756dfbcbc57441806f2594511d8cwallez if (m.useRange()) key |= 1 << 10; 45963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(key); 46084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 46184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 4627510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GrGLMorphologyEffect::setData(const GrGLProgramDataManager& pdman, 463b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& proc) { 46480a61df691bd5756dfbcbc57441806f2594511d8cwallez const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); 46580a61df691bd5756dfbcbc57441806f2594511d8cwallez GrTexture& texture = *m.texture(0); 46680a61df691bd5756dfbcbc57441806f2594511d8cwallez // the code we generated was for a specific kernel radius, direction and bound usage 46780a61df691bd5756dfbcbc57441806f2594511d8cwallez SkASSERT(m.radius() == fRadius); 46880a61df691bd5756dfbcbc57441806f2594511d8cwallez SkASSERT(m.direction() == fDirection); 46980a61df691bd5756dfbcbc57441806f2594511d8cwallez SkASSERT(m.useRange() == fUseRange); 47080a61df691bd5756dfbcbc57441806f2594511d8cwallez 47180a61df691bd5756dfbcbc57441806f2594511d8cwallez float pixelSize = 0.0f; 47280a61df691bd5756dfbcbc57441806f2594511d8cwallez switch (fDirection) { 47384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org case Gr1DKernelEffect::kX_Direction: 47480a61df691bd5756dfbcbc57441806f2594511d8cwallez pixelSize = 1.0f / texture.width(); 47584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 47684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org case Gr1DKernelEffect::kY_Direction: 47780a61df691bd5756dfbcbc57441806f2594511d8cwallez pixelSize = 1.0f / texture.height(); 47884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 47984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org default: 48088cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unknown filter direction."); 48184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org } 48280a61df691bd5756dfbcbc57441806f2594511d8cwallez pdman.set1f(fPixelSizeUni, pixelSize); 48380a61df691bd5756dfbcbc57441806f2594511d8cwallez 48480a61df691bd5756dfbcbc57441806f2594511d8cwallez if (fUseRange) { 48580a61df691bd5756dfbcbc57441806f2594511d8cwallez const float* range = m.range(); 48680a61df691bd5756dfbcbc57441806f2594511d8cwallez if (fDirection && texture.origin() == kBottomLeft_GrSurfaceOrigin) { 48780a61df691bd5756dfbcbc57441806f2594511d8cwallez pdman.set2f(fRangeUni, 1.0f - range[1], 1.0f - range[0]); 48880a61df691bd5756dfbcbc57441806f2594511d8cwallez } else { 48980a61df691bd5756dfbcbc57441806f2594511d8cwallez pdman.set2f(fRangeUni, range[0], range[1]); 49080a61df691bd5756dfbcbc57441806f2594511d8cwallez } 49180a61df691bd5756dfbcbc57441806f2594511d8cwallez } 49284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 49384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 49484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 49584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 49684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgGrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, 49784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org Direction direction, 49884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org int radius, 49984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org MorphologyType type) 50084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org : Gr1DKernelEffect(texture, direction, radius) 50180a61df691bd5756dfbcbc57441806f2594511d8cwallez , fType(type), fUseRange(false) { 502eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<GrMorphologyEffect>(); 50384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 50484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 50580a61df691bd5756dfbcbc57441806f2594511d8cwallezGrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, 50680a61df691bd5756dfbcbc57441806f2594511d8cwallez Direction direction, 50780a61df691bd5756dfbcbc57441806f2594511d8cwallez int radius, 50880a61df691bd5756dfbcbc57441806f2594511d8cwallez MorphologyType type, 50980a61df691bd5756dfbcbc57441806f2594511d8cwallez float range[2]) 51080a61df691bd5756dfbcbc57441806f2594511d8cwallez : Gr1DKernelEffect(texture, direction, radius) 51180a61df691bd5756dfbcbc57441806f2594511d8cwallez , fType(type), fUseRange(true) { 51280a61df691bd5756dfbcbc57441806f2594511d8cwallez this->initClassID<GrMorphologyEffect>(); 51380a61df691bd5756dfbcbc57441806f2594511d8cwallez fRange[0] = range[0]; 51480a61df691bd5756dfbcbc57441806f2594511d8cwallez fRange[1] = range[1]; 51580a61df691bd5756dfbcbc57441806f2594511d8cwallez} 51680a61df691bd5756dfbcbc57441806f2594511d8cwallez 51784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgGrMorphologyEffect::~GrMorphologyEffect() { 51884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 51984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 520cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GrMorphologyEffect::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const { 521eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLMorphologyEffect::GenKey(*this, caps, b); 52284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 52384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 524eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLFragmentProcessor* GrMorphologyEffect::createGLInstance() const { 525eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GrGLMorphologyEffect, (*this)); 526eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 5270e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrMorphologyEffect::onIsEqual(const GrFragmentProcessor& sBase) const { 52849586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrMorphologyEffect& s = sBase.cast<GrMorphologyEffect>(); 529420d7e9a79358908850c74192b4949375563449absalomon return (this->radius() == s.radius() && 53084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org this->direction() == s.direction() && 53180a61df691bd5756dfbcbc57441806f2594511d8cwallez this->useRange() == s.useRange() && 53284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org this->type() == s.type()); 53384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 53484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 535605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdanielvoid GrMorphologyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { 53668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com // This is valid because the color components of the result of the kernel all come 53768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com // exactly from existing values in the source texture. 5381a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel this->updateInvariantOutputForModulation(inout); 53968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com} 54068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 54184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 54284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 543b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMorphologyEffect); 54484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 545b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrMorphologyEffect::TestCreate(SkRandom* random, 546b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 547b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 548b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 549b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 550b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 55184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org Direction dir = random->nextBool() ? kX_Direction : kY_Direction; 55284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org static const int kMaxRadius = 10; 55384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org int radius = random->nextRangeU(1, kMaxRadius); 55484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org MorphologyType type = random->nextBool() ? GrMorphologyEffect::kErode_MorphologyType : 55584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrMorphologyEffect::kDilate_MorphologyType; 55684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 5570ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com return GrMorphologyEffect::Create(textures[texIdx], dir, radius, type); 55884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 55984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 56084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgnamespace { 56184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 56280a61df691bd5756dfbcbc57441806f2594511d8cwallez 56380a61df691bd5756dfbcbc57441806f2594511d8cwallezvoid apply_morphology_rect(GrContext* context, 56425d9c154087d2132a51d1ca74a104726f60ef380joshualitt GrRenderTarget* rt, 565570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 56680a61df691bd5756dfbcbc57441806f2594511d8cwallez GrTexture* texture, 56780a61df691bd5756dfbcbc57441806f2594511d8cwallez const SkIRect& srcRect, 56880a61df691bd5756dfbcbc57441806f2594511d8cwallez const SkIRect& dstRect, 56980a61df691bd5756dfbcbc57441806f2594511d8cwallez int radius, 57080a61df691bd5756dfbcbc57441806f2594511d8cwallez GrMorphologyEffect::MorphologyType morphType, 57180a61df691bd5756dfbcbc57441806f2594511d8cwallez float bounds[2], 57280a61df691bd5756dfbcbc57441806f2594511d8cwallez Gr1DKernelEffect::Direction direction) { 57380a61df691bd5756dfbcbc57441806f2594511d8cwallez GrPaint paint; 57480a61df691bd5756dfbcbc57441806f2594511d8cwallez paint.addColorProcessor(GrMorphologyEffect::Create(texture, 57580a61df691bd5756dfbcbc57441806f2594511d8cwallez direction, 57680a61df691bd5756dfbcbc57441806f2594511d8cwallez radius, 57780a61df691bd5756dfbcbc57441806f2594511d8cwallez morphType, 57880a61df691bd5756dfbcbc57441806f2594511d8cwallez bounds))->unref(); 579570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), SkRect::Make(dstRect), 58025d9c154087d2132a51d1ca74a104726f60ef380joshualitt SkRect::Make(srcRect)); 58180a61df691bd5756dfbcbc57441806f2594511d8cwallez} 58280a61df691bd5756dfbcbc57441806f2594511d8cwallez 58380a61df691bd5756dfbcbc57441806f2594511d8cwallezvoid apply_morphology_rect_no_bounds(GrContext* context, 58425d9c154087d2132a51d1ca74a104726f60ef380joshualitt GrRenderTarget* rt, 585570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 58625d9c154087d2132a51d1ca74a104726f60ef380joshualitt GrTexture* texture, 58725d9c154087d2132a51d1ca74a104726f60ef380joshualitt const SkIRect& srcRect, 58825d9c154087d2132a51d1ca74a104726f60ef380joshualitt const SkIRect& dstRect, 58925d9c154087d2132a51d1ca74a104726f60ef380joshualitt int radius, 59025d9c154087d2132a51d1ca74a104726f60ef380joshualitt GrMorphologyEffect::MorphologyType morphType, 59125d9c154087d2132a51d1ca74a104726f60ef380joshualitt Gr1DKernelEffect::Direction direction) { 59284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrPaint paint; 593b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt paint.addColorProcessor(GrMorphologyEffect::Create(texture, 594b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt direction, 595b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt radius, 596b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt morphType))->unref(); 597570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt context->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), SkRect::Make(dstRect), 59825d9c154087d2132a51d1ca74a104726f60ef380joshualitt SkRect::Make(srcRect)); 59984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 60084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 60180a61df691bd5756dfbcbc57441806f2594511d8cwallezvoid apply_morphology_pass(GrContext* context, 60225d9c154087d2132a51d1ca74a104726f60ef380joshualitt GrRenderTarget* rt, 603570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const GrClip& clip, 60480a61df691bd5756dfbcbc57441806f2594511d8cwallez GrTexture* texture, 60580a61df691bd5756dfbcbc57441806f2594511d8cwallez const SkIRect& srcRect, 60680a61df691bd5756dfbcbc57441806f2594511d8cwallez const SkIRect& dstRect, 60780a61df691bd5756dfbcbc57441806f2594511d8cwallez int radius, 60880a61df691bd5756dfbcbc57441806f2594511d8cwallez GrMorphologyEffect::MorphologyType morphType, 60980a61df691bd5756dfbcbc57441806f2594511d8cwallez Gr1DKernelEffect::Direction direction) { 61080a61df691bd5756dfbcbc57441806f2594511d8cwallez float bounds[2] = { 0.0f, 1.0f }; 61180a61df691bd5756dfbcbc57441806f2594511d8cwallez SkIRect lowerSrcRect = srcRect, lowerDstRect = dstRect; 61280a61df691bd5756dfbcbc57441806f2594511d8cwallez SkIRect middleSrcRect = srcRect, middleDstRect = dstRect; 61380a61df691bd5756dfbcbc57441806f2594511d8cwallez SkIRect upperSrcRect = srcRect, upperDstRect = dstRect; 61480a61df691bd5756dfbcbc57441806f2594511d8cwallez if (direction == Gr1DKernelEffect::kX_Direction) { 61580a61df691bd5756dfbcbc57441806f2594511d8cwallez bounds[0] = (SkIntToScalar(srcRect.left()) + 0.5f) / texture->width(); 61680a61df691bd5756dfbcbc57441806f2594511d8cwallez bounds[1] = (SkIntToScalar(srcRect.right()) - 0.5f) / texture->width(); 61780a61df691bd5756dfbcbc57441806f2594511d8cwallez lowerSrcRect.fRight = srcRect.left() + radius; 61880a61df691bd5756dfbcbc57441806f2594511d8cwallez lowerDstRect.fRight = dstRect.left() + radius; 61980a61df691bd5756dfbcbc57441806f2594511d8cwallez upperSrcRect.fLeft = srcRect.right() - radius; 62080a61df691bd5756dfbcbc57441806f2594511d8cwallez upperDstRect.fLeft = dstRect.right() - radius; 62180a61df691bd5756dfbcbc57441806f2594511d8cwallez middleSrcRect.inset(radius, 0); 62280a61df691bd5756dfbcbc57441806f2594511d8cwallez middleDstRect.inset(radius, 0); 62380a61df691bd5756dfbcbc57441806f2594511d8cwallez } else { 62480a61df691bd5756dfbcbc57441806f2594511d8cwallez bounds[0] = (SkIntToScalar(srcRect.top()) + 0.5f) / texture->height(); 62580a61df691bd5756dfbcbc57441806f2594511d8cwallez bounds[1] = (SkIntToScalar(srcRect.bottom()) - 0.5f) / texture->height(); 62680a61df691bd5756dfbcbc57441806f2594511d8cwallez lowerSrcRect.fBottom = srcRect.top() + radius; 62780a61df691bd5756dfbcbc57441806f2594511d8cwallez lowerDstRect.fBottom = dstRect.top() + radius; 62880a61df691bd5756dfbcbc57441806f2594511d8cwallez upperSrcRect.fTop = srcRect.bottom() - radius; 62980a61df691bd5756dfbcbc57441806f2594511d8cwallez upperDstRect.fTop = dstRect.bottom() - radius; 63080a61df691bd5756dfbcbc57441806f2594511d8cwallez middleSrcRect.inset(0, radius); 63180a61df691bd5756dfbcbc57441806f2594511d8cwallez middleDstRect.inset(0, radius); 63280a61df691bd5756dfbcbc57441806f2594511d8cwallez } 63380a61df691bd5756dfbcbc57441806f2594511d8cwallez if (middleSrcRect.fLeft - middleSrcRect.fRight >= 0) { 63480a61df691bd5756dfbcbc57441806f2594511d8cwallez // radius covers srcRect; use bounds over entire draw 635570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt apply_morphology_rect(context, rt, clip, texture, srcRect, dstRect, radius, 63680a61df691bd5756dfbcbc57441806f2594511d8cwallez morphType, bounds, direction); 63780a61df691bd5756dfbcbc57441806f2594511d8cwallez } else { 63880a61df691bd5756dfbcbc57441806f2594511d8cwallez // Draw upper and lower margins with bounds; middle without. 639570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt apply_morphology_rect(context, rt, clip, texture, lowerSrcRect, lowerDstRect, radius, 64080a61df691bd5756dfbcbc57441806f2594511d8cwallez morphType, bounds, direction); 641570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt apply_morphology_rect(context, rt, clip, texture, upperSrcRect, upperDstRect, radius, 64280a61df691bd5756dfbcbc57441806f2594511d8cwallez morphType, bounds, direction); 643570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt apply_morphology_rect_no_bounds(context, rt, clip, texture, middleSrcRect, middleDstRect, 644570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt radius, morphType, direction); 64580a61df691bd5756dfbcbc57441806f2594511d8cwallez } 64680a61df691bd5756dfbcbc57441806f2594511d8cwallez} 64780a61df691bd5756dfbcbc57441806f2594511d8cwallez 6488fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.orgbool apply_morphology(const SkBitmap& input, 6498fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org const SkIRect& rect, 6508fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org GrMorphologyEffect::MorphologyType morphType, 6518fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkISize radius, 6528fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkBitmap* dst) { 653e30597375c19dfb5197fd065a3d1768401eb00fabsalomon SkAutoTUnref<GrTexture> srcTexture(SkRef(input.getTexture())); 65449f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(srcTexture); 65584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrContext* context = srcTexture->getContext(); 6563cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com 657570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt // setup new clip 658570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt GrClip clip(SkRect::MakeWH(SkIntToScalar(srcTexture->width()), 659570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt SkIntToScalar(srcTexture->height()))); 6603cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com 6618fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); 662f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon GrSurfaceDesc desc; 6636bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon desc.fFlags = kRenderTarget_GrSurfaceFlag; 664c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org desc.fWidth = rect.width(); 665c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org desc.fHeight = rect.height(); 666c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org desc.fConfig = kSkia8888_GrPixelConfig; 6678fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkIRect srcRect = rect; 6683cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com 66984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org if (radius.fWidth > 0) { 670d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon GrTexture* texture = context->textureProvider()->refScratchTexture( 671d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon desc, GrTextureProvider::kApprox_ScratchTexMatch); 672e30597375c19dfb5197fd065a3d1768401eb00fabsalomon if (NULL == texture) { 673673d9732bf37df724500e04afcdf27d5c711ef60senorblanco return false; 674673d9732bf37df724500e04afcdf27d5c711ef60senorblanco } 675570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt apply_morphology_pass(context, texture->asRenderTarget(), clip, srcTexture, 676570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt srcRect, dstRect, radius.fWidth, morphType, 677570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt Gr1DKernelEffect::kX_Direction); 6788fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, 6798fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org dstRect.width(), radius.fHeight); 68089c62980c1eb50b2090f33312086c7e8c66739b4bsalomon GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphType ? 68189c62980c1eb50b2090f33312086c7e8c66739b4bsalomon SK_ColorWHITE : 68289c62980c1eb50b2090f33312086c7e8c66739b4bsalomon SK_ColorTRANSPARENT; 68389c62980c1eb50b2090f33312086c7e8c66739b4bsalomon context->clear(&clearRect, clearColor, false, texture->asRenderTarget()); 684e30597375c19dfb5197fd065a3d1768401eb00fabsalomon srcTexture.reset(texture); 6858fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org srcRect = dstRect; 68684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org } 68784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org if (radius.fHeight > 0) { 688d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon GrTexture* texture = context->textureProvider()->refScratchTexture(desc, 689d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon GrTextureProvider::kApprox_ScratchTexMatch); 690e30597375c19dfb5197fd065a3d1768401eb00fabsalomon if (NULL == texture) { 691673d9732bf37df724500e04afcdf27d5c711ef60senorblanco return false; 692673d9732bf37df724500e04afcdf27d5c711ef60senorblanco } 693570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt apply_morphology_pass(context, texture->asRenderTarget(), clip, srcTexture, 694570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt srcRect, dstRect, radius.fHeight, morphType, 695570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt Gr1DKernelEffect::kY_Direction); 696e30597375c19dfb5197fd065a3d1768401eb00fabsalomon srcTexture.reset(texture); 69784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org } 698e30597375c19dfb5197fd065a3d1768401eb00fabsalomon SkImageFilter::WrapTexture(srcTexture, rect.width(), rect.height(), dst); 6996aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org return true; 70084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 70184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 70284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org}; 70384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 7040ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgbool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, 7050ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proxy* proxy, 7060ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org const SkBitmap& src, 7074cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const Context& ctx, 7080ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org SkBitmap* result, 709ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkIPoint* offset) const { 7106aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkBitmap input = src; 7112bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIPoint srcOffset = SkIPoint::Make(0, 0); 7124cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { 713c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org return false; 714c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org } 715c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org SkIRect bounds; 716118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { 7178fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return false; 7188fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 7192bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 7202bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIntToScalar(this->radius().height())); 7214cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org ctx.ctm().mapVectors(&radius, 1); 7222bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int width = SkScalarFloorToInt(radius.fX); 7232bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int height = SkScalarFloorToInt(radius.fY); 7248fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org 7258fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org if (width < 0 || height < 0) { 7268fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return false; 7278fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 7288fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org 7292bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIRect srcBounds = bounds; 7302bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org srcBounds.offset(-srcOffset); 7318fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org if (width == 0 && height == 0) { 7322bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org input.extractSubset(result, srcBounds); 7336776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fX = bounds.left(); 7346776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fY = bounds.top(); 7358fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return true; 7368fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 7378fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org 7380ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDilate_MorphologyType : GrMorphologyEffect::kErode_MorphologyType; 7390ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!apply_morphology(input, srcBounds, type, 7402bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkISize::Make(width, height), result)) { 7418fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return false; 7428fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 7436776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fX = bounds.left(); 7446776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fY = bounds.top(); 7458fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return true; 74605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 74705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 7484cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 749ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const { 7504cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); 7510ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org} 7520ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org 7534cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 754ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const { 7554cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); 75605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 75705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 75884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org#endif 759