diff options
-rw-r--r-- | gyp/gpu.gyp | 2 | ||||
-rw-r--r-- | include/effects/SkMorphologyImageFilter.h | 6 | ||||
-rw-r--r-- | include/gpu/GrContext.h | 26 | ||||
-rw-r--r-- | src/effects/SkMorphologyImageFilter.cpp | 280 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 66 | ||||
-rw-r--r-- | src/gpu/effects/GrMorphologyEffect.cpp | 168 | ||||
-rw-r--r-- | src/gpu/effects/GrMorphologyEffect.h | 49 |
7 files changed, 270 insertions, 327 deletions
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp index 4021f4f864..11e1b69a30 100644 --- a/gyp/gpu.gyp +++ b/gyp/gpu.gyp @@ -317,8 +317,6 @@ '../src/gpu/effects/GrColorTableEffect.h', '../src/gpu/effects/GrConvolutionEffect.cpp', '../src/gpu/effects/GrConvolutionEffect.h', - '../src/gpu/effects/GrMorphologyEffect.cpp', - '../src/gpu/effects/GrMorphologyEffect.h', '../src/gpu/effects/GrSingleTextureEffect.cpp', '../src/gpu/effects/GrSingleTextureEffect.h', '../src/gpu/effects/GrTextureDomainEffect.cpp', diff --git a/include/effects/SkMorphologyImageFilter.h b/include/effects/SkMorphologyImageFilter.h index f4f96e146f..d1d43ba732 100644 --- a/include/effects/SkMorphologyImageFilter.h +++ b/include/effects/SkMorphologyImageFilter.h @@ -19,7 +19,9 @@ public: protected: SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer); virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; +#if SK_SUPPORT_GPU virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; } +#endif SkISize radius() const { return fRadius; } @@ -35,7 +37,9 @@ public: virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; +#if SK_SUPPORT_GPU virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE; +#endif SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDilateImageFilter) @@ -53,7 +57,9 @@ public: virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; +#if SK_SUPPORT_GPU virtual GrTexture* onFilterImageGPU(GrTexture* src, const SkRect& rect) SK_OVERRIDE; +#endif SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkErodeImageFilter) diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 9fb47e5b1e..8dd81d9d8f 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -603,32 +603,6 @@ public: GrTexture* zoom(GrTexture* srcTexture, const SkRect& dstRect, const SkRect& srcRect, float inset); - - /** - * This enum is used with the function below, applyMorphology. - */ - enum MorphologyType { - kErode_MorphologyType, - kDilate_MorphologyType, - }; - - /** - * Applies a 2D morphology to a given texture. - * @param srcTexture The source texture to be blurred. - * @param rect The destination rectangle. - * @param filter The morphology filter. Must be kDilate_Filter or - * kErode_Filter. - * @param radius The morphology radius in X and Y. The filter is - * applied to a fWidth by fHeight rectangle of - * pixels. - * @return the morphed texture, which may be srcTexture ref'ed, or a - * new texture. It is the caller's responsibility to unref this texture. - */ - GrTexture* applyMorphology(GrTexture* srcTexture, - const GrRect& rect, - MorphologyType type, - SkISize radius); - /////////////////////////////////////////////////////////////////////////// // Helpers diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 34b3c09d62..cbfa5cf0e4 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -13,6 +13,9 @@ #if SK_SUPPORT_GPU #include "GrContext.h" #include "GrTexture.h" +#include "GrGpu.h" +#include "gl/GrGLProgramStage.h" +#include "effects/Gr1DKernelEffect.h" #endif SkMorphologyImageFilter::SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer) @@ -218,29 +221,274 @@ bool SkDilateImageFilter::onFilterImage(Proxy* proxy, return true; } -GrTexture* SkDilateImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) { #if SK_SUPPORT_GPU + +/////////////////////////////////////////////////////////////////////////////// + +class GrGLMorphologyEffect; + +/** + * Morphology effects. Depending upon the type of morphology, either the + * component-wise min (Erode_Type) or max (Dilate_Type) of all pixels in the + * kernel is selected as the new color. The new color is modulated by the input + * color. + */ +class GrMorphologyEffect : public Gr1DKernelEffect { + +public: + + enum MorphologyType { + kErode_MorphologyType, + kDilate_MorphologyType, + }; + + GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType); + virtual ~GrMorphologyEffect(); + + MorphologyType type() const { return fType; } + + static const char* Name() { return "Morphology"; } + + typedef GrGLMorphologyEffect GLProgramStage; + + virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE; + virtual bool isEqual(const GrCustomStage&) const SK_OVERRIDE; + +protected: + + MorphologyType fType; + +private: + GR_DECLARE_CUSTOM_STAGE_TEST; + + typedef Gr1DKernelEffect INHERITED; +}; + +/////////////////////////////////////////////////////////////////////////////// + +class GrGLMorphologyEffect : public GrGLProgramStage { +public: + GrGLMorphologyEffect (const GrProgramStageFactory& factory, + const GrCustomStage& stage); + + virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE; + virtual void emitVS(GrGLShaderBuilder* state, + const char* vertexCoords) SK_OVERRIDE {}; + virtual void emitFS(GrGLShaderBuilder* state, + const char* outputColor, + const char* inputColor, + const char* samplerName) SK_OVERRIDE; + + static inline StageKey GenKey(const GrCustomStage& s, const GrGLCaps& caps); + + virtual void setData(const GrGLUniformManager&, + const GrCustomStage&, + const GrRenderTarget*, + int stageNum) SK_OVERRIDE; + +private: + int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); } + + int fRadius; + GrMorphologyEffect::MorphologyType fType; + GrGLUniformManager::UniformHandle fImageIncrementUni; + + typedef GrGLProgramStage INHERITED; +}; + +GrGLMorphologyEffect::GrGLMorphologyEffect(const GrProgramStageFactory& factory, + const GrCustomStage& stage) + : GrGLProgramStage(factory) + , fImageIncrementUni(GrGLUniformManager::kInvalidUniformHandle) { + const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(stage); + fRadius = m.radius(); + fType = m.type(); +} + +void GrGLMorphologyEffect::setupVariables(GrGLShaderBuilder* builder) { + fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, + kVec2f_GrSLType, "ImageIncrement"); +} + +void GrGLMorphologyEffect::emitFS(GrGLShaderBuilder* builder, + const char* outputColor, + const char* inputColor, + const char* samplerName) { + SkString* code = &builder->fFSCode; + + const char* func; + switch (fType) { + case GrMorphologyEffect::kErode_MorphologyType: + code->appendf("\t\tvec4 value = vec4(1, 1, 1, 1);\n"); + func = "min"; + break; + case GrMorphologyEffect::kDilate_MorphologyType: + code->appendf("\t\tvec4 value = vec4(0, 0, 0, 0);\n"); + func = "max"; + break; + default: + GrCrash("Unexpected type"); + func = ""; // suppress warning + break; + } + const char* imgInc = builder->getUniformCStr(fImageIncrementUni); + + code->appendf("\t\tvec2 coord = %s - %d.0 * %s;\n", + builder->fSampleCoords.c_str(), fRadius, imgInc); + code->appendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width()); + code->appendf("\t\t\tvalue = %s(value, ", func); + builder->emitTextureLookup(samplerName, "coord"); + code->appendf(");\n"); + code->appendf("\t\t\tcoord += %s;\n", imgInc); + code->appendf("\t\t}\n"); + code->appendf("\t\t%s = value%s;\n", outputColor, builder->fModulate.c_str()); +} + +GrGLProgramStage::StageKey GrGLMorphologyEffect::GenKey(const GrCustomStage& s, + const GrGLCaps& caps) { + const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(s); + StageKey key = static_cast<StageKey>(m.radius()); + key |= (m.type() << 8); + return key; +} + +void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman, + const GrCustomStage& data, + const GrRenderTarget*, + int stageNum) { + const Gr1DKernelEffect& kern = + static_cast<const Gr1DKernelEffect&>(data); + GrGLTexture& texture = + *static_cast<GrGLTexture*>(data.texture(0)); + // the code we generated was for a specific kernel radius + GrAssert(kern.radius() == fRadius); + float imageIncrement[2] = { 0 }; + switch (kern.direction()) { + case Gr1DKernelEffect::kX_Direction: + imageIncrement[0] = 1.0f / texture.width(); + break; + case Gr1DKernelEffect::kY_Direction: + imageIncrement[1] = 1.0f / texture.height(); + break; + default: + GrCrash("Unknown filter direction."); + } + uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement); +} + +/////////////////////////////////////////////////////////////////////////////// + +GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, + Direction direction, + int radius, + MorphologyType type) + : Gr1DKernelEffect(texture, direction, radius) + , fType(type) { +} + +GrMorphologyEffect::~GrMorphologyEffect() { +} + +const GrProgramStageFactory& GrMorphologyEffect::getFactory() const { + return GrTProgramStageFactory<GrMorphologyEffect>::getInstance(); +} + +bool GrMorphologyEffect::isEqual(const GrCustomStage& sBase) const { + const GrMorphologyEffect& s = + static_cast<const GrMorphologyEffect&>(sBase); + return (INHERITED::isEqual(sBase) && + this->radius() == s.radius() && + this->direction() == s.direction() && + this->type() == s.type()); +} + +/////////////////////////////////////////////////////////////////////////////// + +GR_DEFINE_CUSTOM_STAGE_TEST(GrMorphologyEffect); + +GrCustomStage* GrMorphologyEffect::TestCreate(SkRandom* random, + GrContext* context, + GrTexture* textures[]) { + int texIdx = random->nextBool() ? GrCustomStageUnitTest::kSkiaPMTextureIdx : + GrCustomStageUnitTest::kAlphaTextureIdx; + Direction dir = random->nextBool() ? kX_Direction : kY_Direction; + static const int kMaxRadius = 10; + int radius = random->nextRangeU(1, kMaxRadius); + MorphologyType type = random->nextBool() ? GrMorphologyEffect::kErode_MorphologyType : + GrMorphologyEffect::kDilate_MorphologyType; + + return SkNEW_ARGS(GrMorphologyEffect, (textures[texIdx], dir, radius, type)); +} + +namespace { + +void apply_morphology_pass(GrContext* context, + GrTexture* texture, + const SkRect& rect, + int radius, + GrMorphologyEffect::MorphologyType morphType, + Gr1DKernelEffect::Direction direction) { + GrMatrix sampleM; + sampleM.setIDiv(texture->width(), texture->height()); + GrPaint paint; + paint.reset(); + paint.textureSampler(0)->reset(sampleM); + paint.textureSampler(0)->setCustomStage(SkNEW_ARGS(GrMorphologyEffect, (texture, direction, radius, morphType)))->unref(); + context->drawRect(paint, rect); +} + +GrTexture* apply_morphology(GrTexture* srcTexture, + const GrRect& rect, + GrMorphologyEffect::MorphologyType morphType, + SkISize radius) { + GrContext* context = srcTexture->getContext(); + srcTexture->ref(); + GrContext::AutoMatrix avm(context, GrMatrix::I()); + GrContext::AutoClip acs(context, GrRect::MakeWH(SkIntToScalar(srcTexture->width()), + SkIntToScalar(srcTexture->height()))); + GrTextureDesc desc; + desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; + desc.fWidth = SkScalarCeilToInt(rect.width()); + desc.fHeight = SkScalarCeilToInt(rect.height()); + desc.fConfig = kRGBA_8888_GrPixelConfig; + if (radius.fWidth > 0) { + GrAutoScratchTexture ast(context, desc); + GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget()); + apply_morphology_pass(context, srcTexture, rect, radius.fWidth, + morphType, Gr1DKernelEffect::kX_Direction); + SkIRect clearRect = SkIRect::MakeXYWH( + SkScalarFloorToInt(rect.fLeft), + SkScalarFloorToInt(rect.fBottom), + SkScalarFloorToInt(rect.width()), + radius.fHeight); + context->clear(&clearRect, 0x0); + srcTexture->unref(); + srcTexture = ast.detach(); + } + if (radius.fHeight > 0) { + GrAutoScratchTexture ast(context, desc); + GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget()); + apply_morphology_pass(context, srcTexture, rect, radius.fHeight, + morphType, Gr1DKernelEffect::kY_Direction); + srcTexture->unref(); + srcTexture = ast.detach(); + } + return srcTexture; +} + +}; + +GrTexture* SkDilateImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) { SkAutoTUnref<GrTexture> input(this->getInputResultAsTexture(src, rect)); - return src->getContext()->applyMorphology(input.get(), rect, - GrContext::kDilate_MorphologyType, - radius()); -#else - SkDEBUGFAIL("Should not call in GPU-less build"); - return NULL; -#endif + return apply_morphology(src, rect, GrMorphologyEffect::kDilate_MorphologyType, radius()); } GrTexture* SkErodeImageFilter::onFilterImageGPU(GrTexture* src, const SkRect& rect) { -#if SK_SUPPORT_GPU SkAutoTUnref<GrTexture> input(this->getInputResultAsTexture(src, rect)); - return src->getContext()->applyMorphology(input.get(), rect, - GrContext::kErode_MorphologyType, - radius()); -#else - SkDEBUGFAIL("Should not call in GPU-less build"); - return NULL; -#endif + return apply_morphology(src, rect, GrMorphologyEffect::kErode_MorphologyType, radius()); } +#endif + SK_DEFINE_FLATTENABLE_REGISTRAR(SkDilateImageFilter) SK_DEFINE_FLATTENABLE_REGISTRAR(SkErodeImageFilter) diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 66da55971c..f2419ae57e 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -9,7 +9,6 @@ #include "GrContext.h" -#include "effects/GrMorphologyEffect.h" #include "effects/GrConvolutionEffect.h" #include "effects/GrSingleTextureEffect.h" @@ -185,26 +184,6 @@ float adjust_sigma(float sigma, int *scaleFactor, int *radius) { return sigma; } -void apply_morphology(GrDrawTarget* target, - GrTexture* texture, - const SkRect& rect, - int radius, - GrContext::MorphologyType morphType, - Gr1DKernelEffect::Direction direction) { - - GrRenderTarget* rt = target->drawState()->getRenderTarget(); - GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit); - GrDrawState* drawState = target->drawState(); - drawState->setRenderTarget(rt); - GrMatrix sampleM; - sampleM.setIDiv(texture->width(), texture->height()); - drawState->sampler(0)->reset(sampleM); - SkAutoTUnref<GrCustomStage> morph( - SkNEW_ARGS(GrMorphologyEffect, (texture, direction, radius, morphType))); - drawState->sampler(0)->setCustomStage(morph); - target->drawSimpleRect(rect, NULL); -} - void convolve_gaussian(GrDrawTarget* target, GrTexture* texture, const SkRect& rect, @@ -1852,51 +1831,6 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, } } -GrTexture* GrContext::applyMorphology(GrTexture* srcTexture, - const GrRect& rect, - MorphologyType morphType, - SkISize radius) { - ASSERT_OWNED_RESOURCE(srcTexture); - srcTexture->ref(); - GrRenderTarget* oldRenderTarget = this->getRenderTarget(); - - AutoMatrix avm(this, GrMatrix::I()); - - AutoClip acs(this, GrRect::MakeWH(SkIntToScalar(srcTexture->width()), - SkIntToScalar(srcTexture->height()))); - GrTextureDesc desc; - desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; - desc.fWidth = SkScalarCeilToInt(rect.width()); - desc.fHeight = SkScalarCeilToInt(rect.height()); - desc.fConfig = kRGBA_8888_GrPixelConfig; - if (radius.fWidth > 0) { - GrAutoScratchTexture ast(this, desc); - this->setRenderTarget(ast.texture()->asRenderTarget()); - GrDrawTarget* target = this->prepareToDraw(NULL, DEFAULT_BUFFERING); - apply_morphology(target, srcTexture, rect, radius.fWidth, morphType, - Gr1DKernelEffect::kX_Direction); - SkIRect clearRect = SkIRect::MakeXYWH( - SkScalarFloorToInt(rect.fLeft), - SkScalarFloorToInt(rect.fBottom), - SkScalarFloorToInt(rect.width()), - radius.fHeight); - this->clear(&clearRect, 0x0); - srcTexture->unref(); - srcTexture = ast.detach(); - } - if (radius.fHeight > 0) { - GrAutoScratchTexture ast(this, desc); - this->setRenderTarget(ast.texture()->asRenderTarget()); - GrDrawTarget* target = this->prepareToDraw(NULL, DEFAULT_BUFFERING); - apply_morphology(target, srcTexture, rect, radius.fHeight, morphType, - Gr1DKernelEffect::kY_Direction); - srcTexture->unref(); - srcTexture = ast.detach(); - } - this->setRenderTarget(oldRenderTarget); - return srcTexture; -} - /////////////////////////////////////////////////////////////////////////////// #if GR_DEBUG void GrContext::printCacheStats() const { diff --git a/src/gpu/effects/GrMorphologyEffect.cpp b/src/gpu/effects/GrMorphologyEffect.cpp index 14b3aef546..e69de29bb2 100644 --- a/src/gpu/effects/GrMorphologyEffect.cpp +++ b/src/gpu/effects/GrMorphologyEffect.cpp @@ -1,168 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrMorphologyEffect.h" -#include "gl/GrGLProgramStage.h" -#include "gl/GrGLSL.h" -#include "gl/GrGLTexture.h" -#include "GrProgramStageFactory.h" - -/////////////////////////////////////////////////////////////////////////////// - -class GrGLMorphologyEffect : public GrGLProgramStage { -public: - GrGLMorphologyEffect (const GrProgramStageFactory& factory, - const GrCustomStage& stage); - - virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE; - virtual void emitVS(GrGLShaderBuilder* state, - const char* vertexCoords) SK_OVERRIDE {}; - virtual void emitFS(GrGLShaderBuilder* state, - const char* outputColor, - const char* inputColor, - const char* samplerName) SK_OVERRIDE; - - static inline StageKey GenKey(const GrCustomStage& s, const GrGLCaps& caps); - - virtual void setData(const GrGLUniformManager&, - const GrCustomStage&, - const GrRenderTarget*, - int stageNum) SK_OVERRIDE; - -private: - int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); } - - int fRadius; - GrMorphologyEffect::MorphologyType fType; - GrGLUniformManager::UniformHandle fImageIncrementUni; - - typedef GrGLProgramStage INHERITED; -}; - -GrGLMorphologyEffect ::GrGLMorphologyEffect(const GrProgramStageFactory& factory, - const GrCustomStage& stage) - : GrGLProgramStage(factory) - , fImageIncrementUni(GrGLUniformManager::kInvalidUniformHandle) { - const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(stage); - fRadius = m.radius(); - fType = m.type(); -} - -void GrGLMorphologyEffect::setupVariables(GrGLShaderBuilder* builder) { - fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, - kVec2f_GrSLType, "ImageIncrement"); -} - -void GrGLMorphologyEffect ::emitFS(GrGLShaderBuilder* builder, - const char* outputColor, - const char* inputColor, - const char* samplerName) { - SkString* code = &builder->fFSCode; - - const char* func; - switch (fType) { - case GrContext::kErode_MorphologyType: - code->appendf("\t\tvec4 value = vec4(1, 1, 1, 1);\n"); - func = "min"; - break; - case GrContext::kDilate_MorphologyType: - code->appendf("\t\tvec4 value = vec4(0, 0, 0, 0);\n"); - func = "max"; - break; - default: - GrCrash("Unexpected type"); - func = ""; // suppress warning - break; - } - const char* imgInc = builder->getUniformCStr(fImageIncrementUni); - - code->appendf("\t\tvec2 coord = %s - %d.0 * %s;\n", - builder->fSampleCoords.c_str(), fRadius, imgInc); - code->appendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width()); - code->appendf("\t\t\tvalue = %s(value, ", func); - builder->emitTextureLookup(samplerName, "coord"); - code->appendf(");\n"); - code->appendf("\t\t\tcoord += %s;\n", imgInc); - code->appendf("\t\t}\n"); - code->appendf("\t\t%s = value%s;\n", outputColor, builder->fModulate.c_str()); -} - -GrGLProgramStage::StageKey GrGLMorphologyEffect::GenKey(const GrCustomStage& s, - const GrGLCaps& caps) { - const GrMorphologyEffect& m = static_cast<const GrMorphologyEffect&>(s); - StageKey key = static_cast<StageKey>(m.radius()); - key |= (m.type() << 8); - return key; -} - -void GrGLMorphologyEffect ::setData(const GrGLUniformManager& uman, - const GrCustomStage& data, - const GrRenderTarget*, - int stageNum) { - const Gr1DKernelEffect& kern = - static_cast<const Gr1DKernelEffect&>(data); - GrGLTexture& texture = - *static_cast<GrGLTexture*>(data.texture(0)); - // the code we generated was for a specific kernel radius - GrAssert(kern.radius() == fRadius); - float imageIncrement[2] = { 0 }; - switch (kern.direction()) { - case Gr1DKernelEffect::kX_Direction: - imageIncrement[0] = 1.0f / texture.width(); - break; - case Gr1DKernelEffect::kY_Direction: - imageIncrement[1] = 1.0f / texture.height(); - break; - default: - GrCrash("Unknown filter direction."); - } - uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement); -} - -/////////////////////////////////////////////////////////////////////////////// - -GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, - Direction direction, - int radius, - MorphologyType type) - : Gr1DKernelEffect(texture, direction, radius) - , fType(type) { -} - -GrMorphologyEffect::~GrMorphologyEffect() { -} - -const GrProgramStageFactory& GrMorphologyEffect::getFactory() const { - return GrTProgramStageFactory<GrMorphologyEffect>::getInstance(); -} - -bool GrMorphologyEffect::isEqual(const GrCustomStage& sBase) const { - const GrMorphologyEffect& s = - static_cast<const GrMorphologyEffect&>(sBase); - return (INHERITED::isEqual(sBase) && - this->radius() == s.radius() && - this->direction() == s.direction() && - this->type() == s.type()); -} - -/////////////////////////////////////////////////////////////////////////////// - -GR_DEFINE_CUSTOM_STAGE_TEST(GrMorphologyEffect); - -GrCustomStage* GrMorphologyEffect::TestCreate(SkRandom* random, - GrContext* context, - GrTexture* textures[]) { - int texIdx = random->nextBool() ? GrCustomStageUnitTest::kSkiaPMTextureIdx : - GrCustomStageUnitTest::kAlphaTextureIdx; - Direction dir = random->nextBool() ? kX_Direction : kY_Direction; - static const int kMaxRadius = 10; - int radius = random->nextRangeU(1, kMaxRadius); - MorphologyType type = random->nextBool() ? GrContext::kErode_MorphologyType : - GrContext::kDilate_MorphologyType; - - return SkNEW_ARGS(GrMorphologyEffect, (textures[texIdx], dir, radius, type)); -} diff --git a/src/gpu/effects/GrMorphologyEffect.h b/src/gpu/effects/GrMorphologyEffect.h index bb65de73c6..e69de29bb2 100644 --- a/src/gpu/effects/GrMorphologyEffect.h +++ b/src/gpu/effects/GrMorphologyEffect.h @@ -1,49 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrMorphologyEffect_DEFINED -#define GrMorphologyEffect_DEFINED - -#include "GrContext.h" -#include "Gr1DKernelEffect.h" - -class GrGLMorphologyEffect; - -/** - * Morphology effects. Depending upon the type of morphology, either the - * component-wise min (Erode_Type) or max (Dilate_Type) of all pixels in the - * kernel is selected as the new color. The new color is modulated by the input - * color. - */ -class GrMorphologyEffect : public Gr1DKernelEffect { - -public: - - typedef GrContext::MorphologyType MorphologyType; - - GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType); - virtual ~GrMorphologyEffect(); - - MorphologyType type() const { return fType; } - - static const char* Name() { return "Morphology"; } - - typedef GrGLMorphologyEffect GLProgramStage; - - virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE; - virtual bool isEqual(const GrCustomStage&) const SK_OVERRIDE; - -protected: - - MorphologyType fType; - -private: - GR_DECLARE_CUSTOM_STAGE_TEST; - - typedef Gr1DKernelEffect INHERITED; -}; -#endif |