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" 17302cffba86a188373c99833d83392f33e6014542senorblanco@chromium.org#include "GrTexture.h" 18b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrTBackendProcessorFactory.h" 19b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 2030ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/builders/GrGLProgramBuilder.h" 2184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org#include "effects/Gr1DKernelEffect.h" 22cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 2305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 249fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 258b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkMorphologyImageFilter::SkMorphologyImageFilter(SkReadBuffer& buffer) 26ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org : INHERITED(1, buffer) { 2775589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com fRadius.fWidth = buffer.readInt(); 2875589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com fRadius.fHeight = buffer.readInt(); 29c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org buffer.validate((fRadius.fWidth >= 0) && 30c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org (fRadius.fHeight >= 0)); 3105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 329fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 3305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 342bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.orgSkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, 352bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int radiusY, 362bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkImageFilter* input, 375e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco const CropRect* cropRect, 385e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco uint32_t uniqueID) 395e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco : INHERITED(1, &input, cropRect, uniqueID), fRadius(SkISize::Make(radiusX, radiusY)) { 4005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 4105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 428b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkMorphologyImageFilter::flatten(SkWriteBuffer& buffer) const { 4305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org this->INHERITED::flatten(buffer); 4475589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com buffer.writeInt(fRadius.fWidth); 4575589257c6ac7fc55a66502b74b8bc09c0212featomhudson@google.com buffer.writeInt(fRadius.fHeight); 4605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 4705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 487a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.orgenum MorphDirection { 497a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org kX, kY 507a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org}; 517a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org 527a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.orgtemplate<MorphDirection direction> 5305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.orgstatic void erode(const SkPMColor* src, SkPMColor* dst, 5405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int radius, int width, int height, 557a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org int srcStride, int dstStride) 5605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org{ 577a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int srcStrideX = direction == kX ? 1 : srcStride; 587a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int dstStrideX = direction == kX ? 1 : dstStride; 597a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int srcStrideY = direction == kX ? srcStride : 1; 607a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int dstStrideY = direction == kX ? dstStride : 1; 6156dd630c41d662bcf2a3f08100f2c6accda05ba9senorblanco@chromium.org radius = SkMin32(radius, width - 1); 6256dd630c41d662bcf2a3f08100f2c6accda05ba9senorblanco@chromium.org const SkPMColor* upperSrc = src + radius * srcStrideX; 6305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (int x = 0; x < width; ++x) { 6405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org const SkPMColor* lp = src; 6505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org const SkPMColor* up = upperSrc; 6605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org SkPMColor* dptr = dst; 6705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (int y = 0; y < height; ++y) { 6805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int minB = 255, minG = 255, minR = 255, minA = 255; 6905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (const SkPMColor* p = lp; p <= up; p += srcStrideX) { 7005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int b = SkGetPackedB32(*p); 7105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int g = SkGetPackedG32(*p); 7205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int r = SkGetPackedR32(*p); 7305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int a = SkGetPackedA32(*p); 7405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (b < minB) minB = b; 7505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (g < minG) minG = g; 7605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (r < minR) minR = r; 7705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (a < minA) minA = a; 7805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 7905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org *dptr = SkPackARGB32(minA, minR, minG, minB); 8005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org dptr += dstStrideY; 8105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org lp += srcStrideY; 8205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org up += srcStrideY; 8305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 8405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (x >= radius) src += srcStrideX; 8505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (x + radius < width - 1) upperSrc += srcStrideX; 8605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org dst += dstStrideX; 8705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 8805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 8905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 907a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.orgtemplate<MorphDirection direction> 9105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.orgstatic void dilate(const SkPMColor* src, SkPMColor* dst, 9205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int radius, int width, int height, 937a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org int srcStride, int dstStride) 9405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org{ 957a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int srcStrideX = direction == kX ? 1 : srcStride; 967a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int dstStrideX = direction == kX ? 1 : dstStride; 977a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int srcStrideY = direction == kX ? srcStride : 1; 987a47ad3bacb36ca7609490bd7cbd85d2c49a0042senorblanco@chromium.org const int dstStrideY = direction == kX ? dstStride : 1; 9956dd630c41d662bcf2a3f08100f2c6accda05ba9senorblanco@chromium.org radius = SkMin32(radius, width - 1); 10056dd630c41d662bcf2a3f08100f2c6accda05ba9senorblanco@chromium.org const SkPMColor* upperSrc = src + radius * srcStrideX; 10105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (int x = 0; x < width; ++x) { 10205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org const SkPMColor* lp = src; 10305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org const SkPMColor* up = upperSrc; 10405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org SkPMColor* dptr = dst; 10505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (int y = 0; y < height; ++y) { 10605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int maxB = 0, maxG = 0, maxR = 0, maxA = 0; 10705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org for (const SkPMColor* p = lp; p <= up; p += srcStrideX) { 10805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int b = SkGetPackedB32(*p); 10905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int g = SkGetPackedG32(*p); 11005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int r = SkGetPackedR32(*p); 11105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org int a = SkGetPackedA32(*p); 11205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (b > maxB) maxB = b; 11305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (g > maxG) maxG = g; 11405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (r > maxR) maxR = r; 11505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (a > maxA) maxA = a; 11605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 11705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org *dptr = SkPackARGB32(maxA, maxR, maxG, maxB); 11805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org dptr += dstStrideY; 11905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org lp += srcStrideY; 12005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org up += srcStrideY; 12105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 12205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (x >= radius) src += srcStrideX; 12305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (x + radius < width - 1) upperSrc += srcStrideX; 12405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org dst += dstStrideX; 12505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 12605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 12705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1280ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgstatic void callProcX(SkMorphologyImageFilter::Proc procX, const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRect& bounds) 12905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org{ 1300ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org procX(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), 1310ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org radiusX, bounds.width(), bounds.height(), 1320ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org src.rowBytesAsPixels(), dst->rowBytesAsPixels()); 13305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 13405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1350ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgstatic void callProcY(SkMorphologyImageFilter::Proc procY, const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRect& bounds) 13605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org{ 1370ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org procY(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), 1380ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org radiusY, bounds.height(), bounds.width(), 1390ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org src.rowBytesAsPixels(), dst->rowBytesAsPixels()); 14005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 14105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1420ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgbool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc procX, 1430ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org SkMorphologyImageFilter::Proc procY, 1440ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proxy* proxy, 1450ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org const SkBitmap& source, 1464cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const Context& ctx, 1470ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org SkBitmap* dst, 148ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkIPoint* offset) const { 14968400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org SkBitmap src = source; 1506776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org SkIPoint srcOffset = SkIPoint::Make(0, 0); 1514cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { 15268400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org return false; 15368400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org } 15468400767be5f72e4b9750ccc8bcf0078d42869a7senorblanco@chromium.org 15528fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org if (src.colorType() != kN32_SkColorType) { 15605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return false; 15705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 15805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1598fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkIRect bounds; 160118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { 1618fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return false; 1628fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 1638fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org 16405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org SkAutoLockPixels alp(src); 16505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (!src.getPixels()) { 16605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return false; 16705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 16805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 169848250415eddc54075f7eb8795e8db79e749c6abreed if (!dst->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height()))) { 170cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org return false; 171cd3b15ca6364a04b0eeeb4f89c7daa8aefe854c8commit-bot@chromium.org } 17205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1732bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 1742bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIntToScalar(this->radius().height())); 1754cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org ctx.ctm().mapVectors(&radius, 1); 1762bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int width = SkScalarFloorToInt(radius.fX); 1772bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int height = SkScalarFloorToInt(radius.fY); 17805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 17905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (width < 0 || height < 0) { 18005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return false; 18105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 18205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 1832bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIRect srcBounds = bounds; 1842bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org srcBounds.offset(-srcOffset); 1852bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org 18605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (width == 0 && height == 0) { 1872bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org src.extractSubset(dst, srcBounds); 1886776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fX = bounds.left(); 1896776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fY = bounds.top(); 19005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return true; 19105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 19205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 19305054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org SkBitmap temp; 194848250415eddc54075f7eb8795e8db79e749c6abreed if (!temp.tryAllocPixels(dst->info())) { 19505054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return false; 19605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 19705054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 19805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org if (width > 0 && height > 0) { 1990ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org callProcX(procX, src, &temp, width, srcBounds); 2002bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height()); 2010ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org callProcY(procY, temp, dst, height, tmpBounds); 20205054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } else if (width > 0) { 2030ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org callProcX(procX, src, dst, width, srcBounds); 20405054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } else if (height > 0) { 2050ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org callProcY(procY, src, dst, height, srcBounds); 20605054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org } 2072bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org offset->fX = bounds.left(); 2082bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org offset->fY = bounds.top(); 20905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org return true; 21005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 21105054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 2120ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgbool SkErodeImageFilter::onFilterImage(Proxy* proxy, 2134cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const SkBitmap& source, const Context& ctx, 214ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* dst, SkIPoint* offset) const { 2150ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proc erodeXProc = SkMorphologyGetPlatformProc(kErodeX_SkMorphologyProcType); 2160ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!erodeXProc) { 2170ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org erodeXProc = erode<kX>; 2181878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com } 2190ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proc erodeYProc = SkMorphologyGetPlatformProc(kErodeY_SkMorphologyProcType); 2200ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!erodeYProc) { 2210ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org erodeYProc = erode<kY>; 2221878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com } 2234cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGeneric(erodeXProc, erodeYProc, proxy, source, ctx, dst, offset); 2240ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org} 2251878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com 2260ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgbool SkDilateImageFilter::onFilterImage(Proxy* proxy, 2274cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const SkBitmap& source, const Context& ctx, 228ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* dst, SkIPoint* offset) const { 2290ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proc dilateXProc = SkMorphologyGetPlatformProc(kDilateX_SkMorphologyProcType); 2300ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!dilateXProc) { 2310ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org dilateXProc = dilate<kX>; 2321878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com } 2330ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proc dilateYProc = SkMorphologyGetPlatformProc(kDilateY_SkMorphologyProcType); 2340ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!dilateYProc) { 2350ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org dilateYProc = dilate<kY>; 2361878a44c7490e3312a3b617fa03d2cf297b791e0skia.committer@gmail.com } 2374cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctx, dst, offset); 23805054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 23905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 240336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.orgvoid SkMorphologyImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { 241336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (getInput(0)) { 242336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org getInput(0)->computeFastBounds(src, dst); 243336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } else { 244336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org *dst = src; 245336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 246336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org dst->outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height())); 247336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org} 248336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org 249c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.orgbool SkMorphologyImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 250c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect* dst) const { 251c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIRect bounds = src; 252c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 253c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org SkIntToScalar(this->radius().height())); 254c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org ctm.mapVectors(&radius, 1); 255c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org bounds.outset(SkScalarCeilToInt(radius.x()), SkScalarCeilToInt(radius.y())); 2561150a6d151571fb6ee816dadec844ae7ab53948asenorblanco if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { 2571150a6d151571fb6ee816dadec844ae7ab53948asenorblanco return false; 2581150a6d151571fb6ee816dadec844ae7ab53948asenorblanco } 259c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org *dst = bounds; 260c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org return true; 261c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org} 262c4b12f19a46946e1c02f3525e0ea4902b09feac5senorblanco@chromium.org 2639fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkErodeImageFilter::CreateProc(SkReadBuffer& buffer) { 2649fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 2659fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int width = buffer.readInt(); 2669fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int height = buffer.readInt(); 2675e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco return Create(width, height, common.getInput(0), &common.cropRect(), common.uniqueID()); 2689fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 2699fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 2709fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkDilateImageFilter::CreateProc(SkReadBuffer& buffer) { 2719fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1); 2729fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int width = buffer.readInt(); 2739fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed const int height = buffer.readInt(); 2745e5f948b6b363dbfc8c076d8ff0c6b8e9ea99958senorblanco return Create(width, height, common.getInput(0), &common.cropRect(), common.uniqueID()); 2759fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 2769fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 277cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU 27884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 27984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 28084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 28184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgclass GrGLMorphologyEffect; 28284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 28384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/** 28484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org * Morphology effects. Depending upon the type of morphology, either the 28584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org * component-wise min (Erode_Type) or max (Dilate_Type) of all pixels in the 28684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org * kernel is selected as the new color. The new color is modulated by the input 28784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org * color. 28884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org */ 28984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgclass GrMorphologyEffect : public Gr1DKernelEffect { 29084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 29184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgpublic: 29284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 29384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org enum MorphologyType { 29484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org kErode_MorphologyType, 29584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org kDilate_MorphologyType, 29684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org }; 29784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 298b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrFragmentProcessor* Create(GrTexture* tex, Direction dir, int radius, 299b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt MorphologyType type) { 30055fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type)); 3010ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 3020ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 30384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org virtual ~GrMorphologyEffect(); 30484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 30584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org MorphologyType type() const { return fType; } 30684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 30784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org static const char* Name() { return "Morphology"; } 30884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 309b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLMorphologyEffect GLProcessor; 31084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 311b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; 31268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 31384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 31484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgprotected: 31584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 31684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org MorphologyType fType; 31784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 31884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgprivate: 319b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; 32068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 3210ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType); 3220ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 323b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 32484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 32584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org typedef Gr1DKernelEffect INHERITED; 32684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org}; 32784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 32884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 32984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 330b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLMorphologyEffect : public GrGLFragmentProcessor { 33184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgpublic: 332b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLMorphologyEffect (const GrBackendProcessorFactory&, const GrProcessor&); 33384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 33430ba436f04e61d4505fb854d5fc56079636e0788joshualitt virtual void emitCode(GrGLProgramBuilder*, 335b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor&, 336b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey&, 33747d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const char* outputColor, 33847d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const char* inputColor, 33977af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com const TransformedCoordsArray&, 34047d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const TextureSamplerArray&) SK_OVERRIDE; 34184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 342b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder* b); 34384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 344b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE; 34584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 34684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgprivate: 34784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); } 34884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 3497510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen int fRadius; 3507510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrMorphologyEffect::MorphologyType fType; 3517510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fImageIncrementUni; 35284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 353b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 35484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org}; 35584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 356b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendProcessorFactory& factory, 357b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& proc) 35877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com : INHERITED(factory) { 359b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); 36084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org fRadius = m.radius(); 36184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org fType = m.type(); 36284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 36384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 36430ba436f04e61d4505fb854d5fc56079636e0788joshualittvoid GrGLMorphologyEffect::emitCode(GrGLProgramBuilder* builder, 365b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor&, 366b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessorKey& key, 36747d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const char* outputColor, 36847d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const char* inputColor, 36977af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com const TransformedCoordsArray& coords, 37047d7a8885b02478fa41069f14bba7ffbe5475d87bsalomon@google.com const TextureSamplerArray& samplers) { 37130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 37284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org kVec2f_GrSLType, "ImageIncrement"); 37384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 37430ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 37530ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); 37684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org const char* func; 37784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org switch (fType) { 37884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org case GrMorphologyEffect::kErode_MorphologyType: 37930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", outputColor); 38084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org func = "min"; 38184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 38284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org case GrMorphologyEffect::kDilate_MorphologyType: 38330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor); 38484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org func = "max"; 38584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 38684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org default: 38788cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unexpected type"); 38884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org func = ""; // suppress warning 38984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 39084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org } 39184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org const char* imgInc = builder->getUniformCStr(fImageIncrementUni); 39284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 39330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str(), fRadius, imgInc); 39430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width()); 39530ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\t%s = %s(%s, ", outputColor, func, outputColor); 39630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->appendTextureLookup(samplers[0], "coord"); 39730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(");\n"); 39830ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t\tcoord += %s;\n", imgInc); 39930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\t}\n"); 400f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com SkString modulate; 401f910d3b23bcf590ee937628dbab8e39a98ee5860bsalomon@google.com GrGLSLMulVarBy4f(&modulate, 2, outputColor, inputColor); 40230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend(modulate.c_str()); 40384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 40484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 405b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GrGLMorphologyEffect::GenKey(const GrProcessor& proc, 406b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGLCaps&, GrProcessorKeyBuilder* b) { 407b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); 40863e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon uint32_t key = static_cast<uint32_t>(m.radius()); 40984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org key |= (m.type() << 8); 41063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(key); 41184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 41284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 4137510b224e52b9518a8ddf7418db0e9c258f79539kkinnunenvoid GrGLMorphologyEffect::setData(const GrGLProgramDataManager& pdman, 414b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrProcessor& proc) { 415b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const Gr1DKernelEffect& kern = proc.cast<Gr1DKernelEffect>(); 4162d0baded0f45dfde9dc8c25313ff14ea18c0c915bsalomon@google.com GrTexture& texture = *kern.texture(0); 41784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org // the code we generated was for a specific kernel radius 41896ae688f03f05a53c2ae6e66a431e180b90be9cdcommit-bot@chromium.org SkASSERT(kern.radius() == fRadius); 41984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org float imageIncrement[2] = { 0 }; 42084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org switch (kern.direction()) { 42184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org case Gr1DKernelEffect::kX_Direction: 42284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org imageIncrement[0] = 1.0f / texture.width(); 42384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 42484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org case Gr1DKernelEffect::kY_Direction: 42584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org imageIncrement[1] = 1.0f / texture.height(); 42684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org break; 42784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org default: 42888cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unknown filter direction."); 42984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org } 4307510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set2fv(fImageIncrementUni, 1, imageIncrement); 43184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 43284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 43384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 43484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 43584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgGrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, 43684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org Direction direction, 43784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org int radius, 43884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org MorphologyType type) 43984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org : Gr1DKernelEffect(texture, direction, radius) 44084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org , fType(type) { 44184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 44284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 44384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgGrMorphologyEffect::~GrMorphologyEffect() { 44484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 44584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 446b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrBackendFragmentProcessorFactory& GrMorphologyEffect::getFactory() const { 447b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return GrTBackendFragmentProcessorFactory<GrMorphologyEffect>::getInstance(); 44884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 44984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 450b0a8a377f832c59cee939ad721e1f87d378b7142joshualittbool GrMorphologyEffect::onIsEqual(const GrProcessor& sBase) const { 45149586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrMorphologyEffect& s = sBase.cast<GrMorphologyEffect>(); 45268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com return (this->texture(0) == s.texture(0) && 45384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org this->radius() == s.radius() && 45484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org this->direction() == s.direction() && 45584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org this->type() == s.type()); 45684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 45784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 45868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.comvoid GrMorphologyEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 45968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com // This is valid because the color components of the result of the kernel all come 46068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com // exactly from existing values in the source texture. 46168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com this->updateConstantColorComponentsForModulation(color, validFlags); 46268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com} 46368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 46484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org/////////////////////////////////////////////////////////////////////////////// 46584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 466b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMorphologyEffect); 46784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 468b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrMorphologyEffect::TestCreate(SkRandom* random, 469b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 470b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 471b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 472b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : 473b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorUnitTest::kAlphaTextureIdx; 47484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org Direction dir = random->nextBool() ? kX_Direction : kY_Direction; 47584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org static const int kMaxRadius = 10; 47684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org int radius = random->nextRangeU(1, kMaxRadius); 47784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org MorphologyType type = random->nextBool() ? GrMorphologyEffect::kErode_MorphologyType : 47884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrMorphologyEffect::kDilate_MorphologyType; 47984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 4800ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com return GrMorphologyEffect::Create(textures[texIdx], dir, radius, type); 48184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 48284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 48384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgnamespace { 48484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 48584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.orgvoid apply_morphology_pass(GrContext* context, 48684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrTexture* texture, 4878fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org const SkIRect& srcRect, 4888fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org const SkIRect& dstRect, 48984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org int radius, 49084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrMorphologyEffect::MorphologyType morphType, 49184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org Gr1DKernelEffect::Direction direction) { 49284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrPaint paint; 493b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt paint.addColorProcessor(GrMorphologyEffect::Create(texture, 494b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt direction, 495b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt radius, 496b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt morphType))->unref(); 4974469938e92d779dff05e745559e67907bbf21e78reed@google.com context->drawRectToRect(paint, SkRect::Make(dstRect), SkRect::Make(srcRect)); 49884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 49984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 5008fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.orgbool apply_morphology(const SkBitmap& input, 5018fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org const SkIRect& rect, 5028fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org GrMorphologyEffect::MorphologyType morphType, 5038fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkISize radius, 5048fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkBitmap* dst) { 5058fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org GrTexture* srcTexture = input.getTexture(); 50649f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(srcTexture); 50784207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrContext* context = srcTexture->getContext(); 50884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org srcTexture->ref(); 5098fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkAutoTUnref<GrTexture> src(srcTexture); 5103cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com 5113cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com GrContext::AutoMatrix am; 5123cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com am.setIdentity(context); 5133cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com 514fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org GrContext::AutoClip acs(context, SkRect::MakeWH(SkIntToScalar(srcTexture->width()), 51584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org SkIntToScalar(srcTexture->height()))); 5163cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com 5178fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); 51884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrTextureDesc desc; 51984207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 520c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org desc.fWidth = rect.width(); 521c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org desc.fHeight = rect.height(); 522c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org desc.fConfig = kSkia8888_GrPixelConfig; 5238fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkIRect srcRect = rect; 5243cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com 52584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org if (radius.fWidth > 0) { 52684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrAutoScratchTexture ast(context, desc); 527673d9732bf37df724500e04afcdf27d5c711ef60senorblanco if (NULL == ast.texture()) { 528673d9732bf37df724500e04afcdf27d5c711ef60senorblanco return false; 529673d9732bf37df724500e04afcdf27d5c711ef60senorblanco } 53084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget()); 5318fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org apply_morphology_pass(context, src, srcRect, dstRect, radius.fWidth, 53284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org morphType, Gr1DKernelEffect::kX_Direction); 5338fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, 5348fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org dstRect.width(), radius.fHeight); 535b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com context->clear(&clearRect, GrMorphologyEffect::kErode_MorphologyType == morphType ? 536b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com SK_ColorWHITE : 53756ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com SK_ColorTRANSPARENT, false); 5388fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org src.reset(ast.detach()); 5398fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org srcRect = dstRect; 54084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org } 54184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org if (radius.fHeight > 0) { 54284207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrAutoScratchTexture ast(context, desc); 543673d9732bf37df724500e04afcdf27d5c711ef60senorblanco if (NULL == ast.texture()) { 544673d9732bf37df724500e04afcdf27d5c711ef60senorblanco return false; 545673d9732bf37df724500e04afcdf27d5c711ef60senorblanco } 54684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget()); 5478fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org apply_morphology_pass(context, src, srcRect, dstRect, radius.fHeight, 54884207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org morphType, Gr1DKernelEffect::kY_Direction); 5498fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org src.reset(ast.detach()); 55084207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org } 5516aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkImageFilter::WrapTexture(src, rect.width(), rect.height(), dst); 5526aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org return true; 55384207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org} 55484207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 55584207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org}; 55684207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org 5570ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.orgbool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, 5580ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org Proxy* proxy, 5590ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org const SkBitmap& src, 5604cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org const Context& ctx, 5610ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org SkBitmap* result, 562ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkIPoint* offset) const { 5636aa6fec0e332c9246958245bad5fc881fefee68fsenorblanco@chromium.org SkBitmap input = src; 5642bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIPoint srcOffset = SkIPoint::Make(0, 0); 5654cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { 566c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org return false; 567c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org } 568c2594f41066102d7a8a73effd3c574142a018b9asenorblanco@chromium.org SkIRect bounds; 569118252962f89a80db661a0544f1bd61cbaab6321senorblanco@chromium.org if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { 5708fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return false; 5718fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 5722bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 5732bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIntToScalar(this->radius().height())); 5744cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org ctx.ctm().mapVectors(&radius, 1); 5752bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int width = SkScalarFloorToInt(radius.fX); 5762bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org int height = SkScalarFloorToInt(radius.fY); 5778fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org 5788fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org if (width < 0 || height < 0) { 5798fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return false; 5808fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 5818fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org 5822bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkIRect srcBounds = bounds; 5832bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org srcBounds.offset(-srcOffset); 5848fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org if (width == 0 && height == 0) { 5852bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org input.extractSubset(result, srcBounds); 5866776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fX = bounds.left(); 5876776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fY = bounds.top(); 5888fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return true; 5898fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 5908fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org 5910ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDilate_MorphologyType : GrMorphologyEffect::kErode_MorphologyType; 5920ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org if (!apply_morphology(input, srcBounds, type, 5932bfe36b68d11d05c114a33d62f9f45427e316916senorblanco@chromium.org SkISize::Make(width, height), result)) { 5948fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return false; 5958fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org } 5966776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fX = bounds.left(); 5976776b82d466fa93ccffd251fdf556fe058395444senorblanco@chromium.org offset->fY = bounds.top(); 5988fcad9879173d627ee8638c52709d924034e34cesenorblanco@chromium.org return true; 59905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 60005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 6014cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 602ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const { 6034cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); 6040ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org} 6050ded88d431a1872e21986984f009db2e84f52738senorblanco@chromium.org 6064cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.orgbool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 607ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org SkBitmap* result, SkIPoint* offset) const { 6084cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); 60905054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org} 61005054f1a78a697b507580d0025db6c90423e033fsenorblanco@chromium.org 61184207c42789e67ef377befb0c9057b9b73fbd6e3senorblanco@chromium.org#endif 612