Registry-based unit test for custom effects
Review URL: http://codereview.appspot.com/6447085/
git-svn-id: http://skia.googlecode.com/svn/trunk@4946 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index d7aea98..a43ad83 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -6,23 +6,19 @@
* found in the LICENSE file.
*/
-// This is a GPU-backend specific test
-#if SK_SUPPORT_GPU
+// This is a GPU-backend specific test. It relies on static intializers to work
#include "gl/GrGpuGL.h"
#include "effects/GrColorTableEffect.h"
#include "effects/GrConvolutionEffect.h"
-#include "../effects/gradients/SkLinearGradient.h"
-#include "../effects/gradients/SkRadialGradient.h"
-#include "../effects/gradients/SkTwoPointRadialGradient.h"
-#include "../effects/gradients/SkTwoPointConicalGradient.h"
-#include "../effects/gradients/SkSweepGradient.h"
#include "effects/GrMorphologyEffect.h"
#include "SkLightingImageFilter.h"
#include "GrProgramStageFactory.h"
#include "GrRandom.h"
#include "Test.h"
+#if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
namespace {
// GrRandoms nextU() values have patterns in the low bits
@@ -44,47 +40,32 @@
return SkPoint3(r->nextF(), r->nextF(), r->nextF());
}
-// populate a pair of arrays with colors and stop info, colorCount indicates
-// the max number of colors, and is set to the actual number on return
-void random_gradient(GrRandom* r, int* colorCount, SkColor* colors,
- SkScalar** stops) {
- int outColors = random_int(r, 1, *colorCount);
-
- // if one color, omit stops, if two colors, randomly decide whether or not to
- if (outColors == 1 || (outColors == 2 && random_bool(r))) *stops = NULL;
-
- GrScalar stop = 0.f;
- for (int i = 0; i < outColors; ++i) {
- colors[i] = static_cast<SkColor>(r->nextF() * 0xffffffff);
- if (*stops) {
- (*stops)[i] = stop;
- stop = i < outColors - 1 ? stop + r->nextF() * (1.f - stop) : 1.f;
- }
- }
-
- *colorCount = outColors;
-}
-
typedef GrGLProgram::StageDesc StageDesc;
// TODO: Effects should be able to register themselves for inclusion in the
// randomly generated shaders. They should be able to configure themselves
// randomly.
-const GrCustomStage* create_random_effect(StageDesc* stageDesc, GrRandom* random,
- GrContext* context) {
+const GrCustomStage* create_random_effect(StageDesc* stageDesc,
+ GrRandom* random,
+ GrContext* context,
+ GrTexture* dummyTextures[]) {
enum EffectType {
kConvolution_EffectType,
kErode_EffectType,
kDilate_EffectType,
- kRadialGradient_EffectType,
- kRadial2Gradient_EffectType,
- kConical2Gradient_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
+ * shader.
+ */
+ /*
kDiffuseDistant_EffectType,
kDiffusePoint_EffectType,
kDiffuseSpot_EffectType,
kSpecularDistant_EffectType,
kSpecularPoint_EffectType,
kSpecularSpot_EffectType,
- kSweepGradient_EffectType,
+ */
+
kColorTable_EffectType,
kEffectCount
@@ -101,7 +82,20 @@
Gr1DKernelEffect::kY_Direction
};
- static const int kMaxGradientStops = 4;
+ // The new code uses SkRandom not GrRandom.
+ // TODO: Remove GrRandom.
+ SkRandom sk_random;
+ sk_random.setSeed(random->nextU());
+
+ bool useFactory = random_bool(random);
+ if (useFactory) {
+ GrCustomStage* stage = GrCustomStageTestFactory::CreateStage(&sk_random,
+ context,
+ dummyTextures);
+ GrAssert(stage);
+ return stage;
+ }
+
// TODO: When matrices are property of the custom-stage then remove the
// no-persp flag code below.
@@ -147,89 +141,7 @@
kernelRadius,
GrContext::kDilate_MorphologyType));
}
- case kRadialGradient_EffectType: {
- SkPoint center = {random->nextF(), random->nextF()};
- SkScalar radius = random->nextF();
- int colorCount = kMaxGradientStops;
- SkColor colors[kMaxGradientStops];
- SkScalar stops[kMaxGradientStops];
- SkScalar* stopsPtr = stops;
- random_gradient(random, &colorCount, colors, &stopsPtr);
- SkShader::TileMode tileMode = static_cast<SkShader::TileMode>(
- random_int(random, SkShader::kTileModeCount));
- SkAutoTUnref<SkGradientShaderBase> gradient(
- static_cast<SkGradientShaderBase*>(SkGradientShader::CreateRadial(
- center, radius, colors, stopsPtr, colorCount, tileMode, NULL)));
- GrSamplerState sampler;
- GrCustomStage* stage = gradient->asNewCustomStage(context, &sampler);
- GrAssert(NULL != stage);
- return stage;
- }
- case kRadial2Gradient_EffectType: {
- SkPoint center1 = {random->nextF(), random->nextF()};
- SkPoint center2 = {random->nextF(), random->nextF()};
- SkScalar radius1 = random->nextF();
- SkScalar radius2;
- do {
- radius2 = random->nextF();
- } while (radius1 == radius2);
- int colorCount = kMaxGradientStops;
- SkColor colors[kMaxGradientStops];
- SkScalar stops[kMaxGradientStops];
- SkScalar* stopsPtr = stops;
- random_gradient(random, &colorCount, colors, &stopsPtr);
- SkShader::TileMode tileMode = static_cast<SkShader::TileMode>(
- random_int(random, SkShader::kTileModeCount));
- SkAutoTUnref<SkGradientShaderBase> gradient(
- static_cast<SkGradientShaderBase*>(SkGradientShader::
- CreateTwoPointRadial(center1, radius1, center2, radius2,
- colors, stopsPtr, colorCount, tileMode, NULL)));
- GrSamplerState sampler;
- GrCustomStage* stage = gradient->asNewCustomStage(context, &sampler);
- GrAssert(NULL != stage);
- return stage;
- }
- case kConical2Gradient_EffectType: {
- SkPoint center1 = {random->nextF(), random->nextF()};
- SkScalar radius1 = random->nextF();
- SkPoint center2;
- SkScalar radius2;
- do {
- center1.set(random->nextF(), random->nextF());
- radius2 = random->nextF();
- } while (radius1 == radius2 && center1 == center2);
- int colorCount = kMaxGradientStops;
- SkColor colors[kMaxGradientStops];
- SkScalar stops[kMaxGradientStops];
- SkScalar* stopsPtr = stops;
- random_gradient(random, &colorCount, colors, &stopsPtr);
- SkShader::TileMode tileMode = static_cast<SkShader::TileMode>(
- random_int(random, SkShader::kTileModeCount));
- SkAutoTUnref<SkGradientShaderBase> gradient(
- static_cast<SkGradientShaderBase*>(SkGradientShader::
- CreateTwoPointConical(center1, radius1, center2, radius2,
- colors, stopsPtr, colorCount, tileMode, NULL)));
- GrSamplerState sampler;
- GrCustomStage* stage = gradient->asNewCustomStage(context, &sampler);
- GrAssert(NULL != stage);
- return stage;
- }
- case kSweepGradient_EffectType: {
- SkPoint center = {random->nextF(), random->nextF()};
- SkScalar radius = random->nextF();
- int colorCount = kMaxGradientStops;
- SkColor colors[kMaxGradientStops];
- SkScalar stops[kMaxGradientStops];
- SkScalar* stopsPtr = stops;
- random_gradient(random, &colorCount, colors, &stopsPtr);
- SkAutoTUnref<SkGradientShaderBase> gradient(
- static_cast<SkGradientShaderBase*>(SkGradientShader::CreateSweep(
- center.fX, center.fY, colors, stopsPtr, colorCount, NULL)));
- GrSamplerState sampler;
- GrCustomStage* stage = gradient->asNewCustomStage(context, &sampler);
- GrAssert(NULL != stage);
- return stage;
- }
+ /*
case kDiffuseDistant_EffectType: {
SkPoint3 direction = random_point3(random);
direction.normalize();
@@ -316,8 +228,10 @@
SkASSERT(ok);
return stage;
}
+ */
case kColorTable_EffectType: {
- return SkNEW_ARGS(GrColorTableEffect, (NULL));
+ GrTexture* alphaTexture = dummyTextures[GrCustomStageTestFactory::kAlphaTextureIdx];
+ return SkNEW_ARGS(GrColorTableEffect, (alphaTexture));
}
default:
GrCrash("Unexpected custom effect type");
@@ -328,6 +242,16 @@
bool GrGpuGL::programUnitTest() {
+ GrTextureDesc dummyDesc;
+ dummyDesc.fConfig = kSkia8888_PM_GrPixelConfig;
+ dummyDesc.fWidth = 34;
+ dummyDesc.fHeight = 18;
+ SkAutoTUnref<GrTexture> dummyTexture1(this->createTexture(dummyDesc, NULL, 0));
+ dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
+ dummyDesc.fWidth = 16;
+ dummyDesc.fHeight = 22;
+ SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0));
+
// GrGLSLGeneration glslGeneration =
GrGetGLSLGeneration(this->glBinding(), this->glInterface());
static const int STAGE_OPTS[] = {
@@ -416,12 +340,15 @@
stage.fCustomStageKey = 0;
- stage.fOptFlags = STAGE_OPTS[random_int(&random, GR_ARRAY_COUNT(STAGE_OPTS))];
+ stage.fOptFlags |= STAGE_OPTS[random_int(&random, GR_ARRAY_COUNT(STAGE_OPTS))];
stage.fInConfigFlags = IN_CONFIG_FLAGS[random_int(&random, GR_ARRAY_COUNT(IN_CONFIG_FLAGS))];
- bool useCustomEffect = random_bool(&random);
- if (useCustomEffect) {
- customStages[s].reset(create_random_effect(&stage, &random, getContext()));
+ if (stage.isEnabled()) {
+ GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
+ customStages[s].reset(create_random_effect(&stage,
+ &random,
+ getContext(),
+ dummyTextures));
if (NULL != customStages[s]) {
stage.fCustomStageKey =
customStages[s]->getFactory().glStageKey(*customStages[s], this->glCaps());