Add morphology, convolution, single texture, texture domain effects to new unit test...
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 3 Aug 2012 18:12:20 +0000 (18:12 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 3 Aug 2012 18:12:20 +0000 (18:12 +0000)
Review URL: http://codereview.appspot.com/6442085/

git-svn-id: http://skia.googlecode.com/svn/trunk@4951 2bbb7eff-a529-9590-31e7-b0007b416f81

12 files changed:
include/core/SkRandom.h
src/gpu/effects/GrColorTableEffect.cpp
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
src/gpu/effects/GrTextureDomainEffect.h
tests/GLProgramsTest.cpp

index b1b7564..c033f40 100644 (file)
@@ -81,6 +81,13 @@ public:
     SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
 
     /** Return the next pseudo random number expressed as a SkScalar
+        in the range [min..max).
+    */
+    SkScalar nextRangeScalar(SkScalar min, SkScalar max) {
+        return SkScalarMul(this->nextSScalar1(), (max - min)) + min;
+    }
+
+    /** Return the next pseudo random number expressed as a SkScalar
         in the range (-SK_Scalar1..SK_Scalar1).
     */
     SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
index 94eb8fd..c6ce559 100644 (file)
@@ -124,3 +124,13 @@ const GrTextureAccess* GrColorTableEffect::textureAccess(unsigned int index) con
 
     return NULL;
 }
+
+///////////////////////////////////////////////////////////////////////////////
+
+GR_DEFINE_CUSTOM_STAGE_TEST(GrColorTableEffect);
+
+GrCustomStage* GrColorTableEffect::TestCreate(SkRandom* random,
+                                              GrContext* context,
+                                              GrTexture* textures[]) {
+    return SkNEW_ARGS(GrColorTableEffect, (textures[GrCustomStageTestFactory::kAlphaTextureIdx]));
+}
index 16d76ad..de86768 100644 (file)
@@ -34,6 +34,7 @@ public:
     typedef GrGLColorTableEffect GLProgramStage;
 
 private:
+    GR_DECLARE_CUSTOM_STAGE_TEST;
 
     GrTextureAccess fTextureAccess;
 
index 5cce800..a28d44d 100644 (file)
@@ -22,7 +22,7 @@ public:
 
     virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
     virtual void emitVS(GrGLShaderBuilder* builder,
-                        const char* vertexCoords) SK_OVERRIDE;
+                        const char* vertexCoords) SK_OVERRIDE {};
     virtual void emitFS(GrGLShaderBuilder* builder,
                         const char* outputColor,
                         const char* inputColor,
@@ -56,20 +56,12 @@ GrGLConvolutionEffect::GrGLConvolutionEffect(const GrProgramStageFactory& factor
 }
 
 void GrGLConvolutionEffect::setupVariables(GrGLShaderBuilder* builder) {
-    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType |
-                                             GrGLShaderBuilder::kVertex_ShaderType,
+    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                              kVec2f_GrSLType, "ImageIncrement");
     fKernelUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_ShaderType,
                                           kFloat_GrSLType, "Kernel", this->width());
 }
 
-void GrGLConvolutionEffect::emitVS(GrGLShaderBuilder* builder,
-                                   const char* vertexCoords) {
-    SkString* code = &builder->fVSCode;
-    const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
-    code->appendf("\t\t%s -= vec2(%d, %d) * %s;\n", vertexCoords, fRadius, fRadius, imgInc);
-}
-
 void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* builder,
                                    const char* outputColor,
                                    const char* inputColor,
@@ -77,12 +69,14 @@ void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* builder,
     SkString* code = &builder->fFSCode;
 
     code->appendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor);
-
-    code->appendf("\t\tvec2 coord = %s;\n", builder->fSampleCoords.c_str());
     
     int width = this ->width();
     const GrGLShaderVar& kernel = builder->getUniformVariable(fKernelUni);
     const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
+
+    code->appendf("\t\tvec2 coord = %s - %d * %s;\n",
+                  builder->fSampleCoords.c_str(), fRadius, imgInc);
+
     // Manually unroll loop because some drivers don't; yields 20-30% speedup.
     for (int i = 0; i < width; i++) {
         SkString index;
@@ -185,3 +179,23 @@ bool GrConvolutionEffect::isEqual(const GrCustomStage& sBase) const {
             this->direction() == s.direction() &&
             0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float)));
 }
+
+///////////////////////////////////////////////////////////////////////////////
+
+GR_DEFINE_CUSTOM_STAGE_TEST(GrConvolutionEffect);
+
+GrCustomStage* GrConvolutionEffect::TestCreate(SkRandom* random,
+                                              GrContext* context,
+                                              GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrCustomStageTestFactory::kSkiaPMTextureIdx :
+                                      GrCustomStageTestFactory::kAlphaTextureIdx;
+    Direction dir = random->nextBool() ? kX_Direction : kY_Direction;
+    int radius = random->nextRangeU(1, kMaxKernelRadius);
+    float kernel[kMaxKernelRadius];
+    for (int i = 0; i < kMaxKernelRadius; ++i) {
+        kernel[i] = random->nextSScalar1();
+    }
+
+    return SkNEW_ARGS(GrConvolutionEffect, (textures[texIdx], dir, radius, kernel));
+}
+
index e04e802..21c022d 100644 (file)
@@ -55,6 +55,7 @@ protected:
     float fKernel[kMaxKernelWidth];
 
 private:
+    GR_DECLARE_CUSTOM_STAGE_TEST;
 
     typedef Gr1DKernelEffect INHERITED;
 };
index be8485e..a4c5ef9 100644 (file)
@@ -20,7 +20,7 @@ public:
 
     virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE;
     virtual void emitVS(GrGLShaderBuilder* state,
-                        const char* vertexCoords) SK_OVERRIDE;
+                        const char* vertexCoords) SK_OVERRIDE {};
     virtual void emitFS(GrGLShaderBuilder* state,
                         const char* outputColor,
                         const char* inputColor,
@@ -53,18 +53,10 @@ GrGLMorphologyEffect ::GrGLMorphologyEffect(const GrProgramStageFactory& factory
 }
 
 void GrGLMorphologyEffect::setupVariables(GrGLShaderBuilder* builder) {
-    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType |
-                                             GrGLShaderBuilder::kVertex_ShaderType,
+    fImageIncrementUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
                                              kVec2f_GrSLType, "ImageIncrement");
 }
 
-void GrGLMorphologyEffect::emitVS(GrGLShaderBuilder* builder,
-                                  const char* vertexCoords) {
-    SkString* code = &builder->fVSCode;
-    const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
-    code->appendf("\t\t%s -= vec2(%d, %d) * %s;\n", vertexCoords, fRadius, fRadius, imgInc);
-}
-
 void GrGLMorphologyEffect ::emitFS(GrGLShaderBuilder* builder,
                                    const char* outputColor,
                                    const char* inputColor,
@@ -88,7 +80,8 @@ void GrGLMorphologyEffect ::emitFS(GrGLShaderBuilder* builder,
     }
     const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
 
-    code->appendf("\t\tvec2 coord = %s;\n", builder->fSampleCoords.c_str());
+    code->appendf("\t\tvec2 coord = %s - %d * %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");
@@ -155,3 +148,21 @@ bool GrMorphologyEffect::isEqual(const GrCustomStage& sBase) const {
             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() ? GrCustomStageTestFactory::kSkiaPMTextureIdx :
+                                      GrCustomStageTestFactory::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));
+}
index c8bd2d5..bb65de7 100644 (file)
@@ -42,6 +42,7 @@ protected:
     MorphologyType fType;
 
 private:
+    GR_DECLARE_CUSTOM_STAGE_TEST;
 
     typedef Gr1DKernelEffect INHERITED;
 };
index 5f66e09..ebd0913 100644 (file)
@@ -56,3 +56,15 @@ GrTexture* GrSingleTextureEffect::texture(unsigned int index) const {
 const GrProgramStageFactory& GrSingleTextureEffect::getFactory() const {
     return GrTProgramStageFactory<GrSingleTextureEffect>::getInstance();
 }
+
+///////////////////////////////////////////////////////////////////////////////
+
+GR_DEFINE_CUSTOM_STAGE_TEST(GrSingleTextureEffect);
+
+GrCustomStage* GrSingleTextureEffect::TestCreate(SkRandom* random,
+                                                 GrContext* context,
+                                                 GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrCustomStageTestFactory::kSkiaPMTextureIdx :
+                                      GrCustomStageTestFactory::kAlphaTextureIdx;
+    return SkNEW_ARGS(GrSingleTextureEffect, (textures[texIdx]));
+}
index c49dac8..211319c 100644 (file)
@@ -31,6 +31,8 @@ public:
     virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE;
 
 private:
+    GR_DECLARE_CUSTOM_STAGE_TEST;
+
     GrTexture* fTexture;
 
     typedef GrCustomStage INHERITED;
index e76d0c9..6b22690 100644 (file)
@@ -107,3 +107,20 @@ bool GrTextureDomainEffect::isEqual(const GrCustomStage& sBase) const {
     const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
     return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain);
 }
+
+///////////////////////////////////////////////////////////////////////////////
+
+GR_DEFINE_CUSTOM_STAGE_TEST(GrTextureDomainEffect);
+
+GrCustomStage* GrTextureDomainEffect::TestCreate(SkRandom* random,
+                                                 GrContext* context,
+                                                 GrTexture* textures[]) {
+    int texIdx = random->nextBool() ? GrCustomStageTestFactory::kSkiaPMTextureIdx :
+                                      GrCustomStageTestFactory::kAlphaTextureIdx;
+    GrRect domain;
+    domain.fLeft = random->nextUScalar1();
+    domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1);
+    domain.fTop = random->nextUScalar1();
+    domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
+    return SkNEW_ARGS(GrTextureDomainEffect, (textures[texIdx], domain));
+}
index 6157175..559398e 100644 (file)
@@ -38,6 +38,7 @@ protected:
     GrRect fTextureDomain;
 
 private:
+    GR_DECLARE_CUSTOM_STAGE_TEST;
 
     typedef GrSingleTextureEffect INHERITED;
 };
index 199cc49..1228b4e 100644 (file)
@@ -13,9 +13,6 @@
 #if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
 
 #include "gl/GrGpuGL.h"
-#include "effects/GrColorTableEffect.h"
-#include "effects/GrConvolutionEffect.h"
-#include "effects/GrMorphologyEffect.h"
 #include "SkLightingImageFilter.h"
 #include "GrProgramStageFactory.h"
 #include "GrRandom.h"
@@ -51,9 +48,6 @@ const GrCustomStage* create_random_effect(StageDesc* stageDesc,
                                           GrContext* context,
                                           GrTexture* dummyTextures[]) {
     enum EffectType {
-        kConvolution_EffectType,
-        kErode_EffectType,
-        kDilate_EffectType,
         /**
          * Lighting effects don't work in unit test because they assume they insert functions and
          * assume the names are unique. This breaks when there are two light effects in the same
@@ -68,8 +62,6 @@ const GrCustomStage* create_random_effect(StageDesc* stageDesc,
         kSpecularSpot_EffectType,
         */
 
-        kColorTable_EffectType,
-
         kEffectCount
     };
 
@@ -79,11 +71,6 @@ const GrCustomStage* create_random_effect(StageDesc* stageDesc,
         StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag |
         StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag;
 
-    static const Gr1DKernelEffect::Direction gKernelDirections[] = {
-        Gr1DKernelEffect::kX_Direction,
-        Gr1DKernelEffect::kY_Direction
-    };
-
     // The new code uses SkRandom not GrRandom.
     // TODO: Remove GrRandom.
     SkRandom sk_random;
@@ -102,48 +89,7 @@ const GrCustomStage* create_random_effect(StageDesc* stageDesc,
     // TODO: When matrices are property of the custom-stage then remove the
     // no-persp flag code below.
     int effect = random_int(random, kEffectCount);
-    switch (effect) {
-        case kConvolution_EffectType: {
-            int direction = random_int(random, 2);
-            int kernelRadius = random_int(random, 1, 4);
-            float kernel[GrConvolutionEffect::kMaxKernelWidth];
-            for (int i = 0; i < GrConvolutionEffect::kMaxKernelWidth; i++) {
-                kernel[i] = random->nextF();
-            }
-            // does not work with perspective or mul-by-alpha-mask
-            stageDesc->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
-            stageDesc->fInConfigFlags &= ~kMulByAlphaMask;
-            return SkNEW_ARGS(GrConvolutionEffect,
-                              (NULL,
-                               gKernelDirections[direction],
-                               kernelRadius,
-                               kernel));
-            }
-        case kErode_EffectType: {
-            int direction = random_int(random, 2);
-            int kernelRadius = random_int(random, 1, 4);
-            // does not work with perspective or mul-by-alpha-mask
-            stageDesc->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
-            stageDesc->fInConfigFlags &= ~kMulByAlphaMask;
-            return SkNEW_ARGS(GrMorphologyEffect,
-                              (NULL,
-                               gKernelDirections[direction],
-                               kernelRadius,
-                               GrContext::kErode_MorphologyType));
-            }
-        case kDilate_EffectType: {
-            int direction = random_int(random, 2);
-            int kernelRadius = random_int(random, 1, 4);
-            // does not work with perspective or mul-by-alpha-mask
-            stageDesc->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
-            stageDesc->fInConfigFlags &= ~kMulByAlphaMask;
-            return SkNEW_ARGS(GrMorphologyEffect,
-                              (NULL,
-                               gKernelDirections[direction],
-                               kernelRadius,
-                               GrContext::kDilate_MorphologyType));
-            }
-        /*
+/*    switch (effect) {
         case kDiffuseDistant_EffectType: {
             SkPoint3 direction = random_point3(random);
             direction.normalize();
@@ -230,14 +176,10 @@ const GrCustomStage* create_random_effect(StageDesc* stageDesc,
             SkASSERT(ok);
             return stage;
         }
-        */
-        case kColorTable_EffectType: {
-            GrTexture* alphaTexture = dummyTextures[GrCustomStageTestFactory::kAlphaTextureIdx];
-            return SkNEW_ARGS(GrColorTableEffect, (alphaTexture));
-        }
         default:
             GrCrash("Unexpected custom effect type");
     }
+    */
     return NULL;
 }
 }