GLProgramsTest.cpp revision b9086a026844e4cfd08b219e49ce3f12294cba98
1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9// This is a GPU-backend specific test. It relies on static intializers to work 10 11#include "SkTypes.h" 12 13#if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 14 15#include "gl/GrGpuGL.h" 16#include "GrBackendEffectFactory.h" 17#include "effects/GrConfigConversionEffect.h" 18 19#include "GrRandom.h" 20#include "Test.h" 21 22namespace { 23 24// GrRandoms nextU() values have patterns in the low bits 25// So using nextU() % array_count might never take some values. 26int random_int(GrRandom* r, int count) { 27 return (int)(r->nextF() * count); 28} 29 30bool random_bool(GrRandom* r) { 31 return r->nextF() > .5f; 32} 33 34typedef GrGLProgram::StageDesc StageDesc; 35 36const GrEffect* create_random_effect(GrRandom* random, 37 GrContext* context, 38 GrTexture* dummyTextures[]) { 39 40 // The new code uses SkRandom not GrRandom. 41 // TODO: Remove GrRandom. 42 SkRandom sk_random; 43 sk_random.setSeed(random->nextU()); 44 GrEffect* effect = GrEffectTestFactory::CreateStage(&sk_random, context, dummyTextures); 45 GrAssert(effect); 46 return effect; 47} 48} 49 50bool GrGpuGL::programUnitTest() { 51 52 GrTextureDesc dummyDesc; 53 dummyDesc.fConfig = kSkia8888_PM_GrPixelConfig; 54 dummyDesc.fWidth = 34; 55 dummyDesc.fHeight = 18; 56 SkAutoTUnref<GrTexture> dummyTexture1(this->createTexture(dummyDesc, NULL, 0)); 57 dummyDesc.fConfig = kAlpha_8_GrPixelConfig; 58 dummyDesc.fWidth = 16; 59 dummyDesc.fHeight = 22; 60 SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0)); 61 62 // GrGLSLGeneration glslGeneration = 63 GrGetGLSLGeneration(this->glBinding(), this->glInterface()); 64 static const int STAGE_OPTS[] = { 65 0, 66 StageDesc::kNoPerspective_OptFlagBit, 67 }; 68 69 static const int NUM_TESTS = 512; 70 71 GrRandom random; 72 for (int t = 0; t < NUM_TESTS; ++t) { 73 74#if 0 75 GrPrintf("\nTest Program %d\n-------------\n", t); 76 static const int stop = -1; 77 if (t == stop) { 78 int breakpointhere = 9; 79 } 80#endif 81 82 ProgramDesc pdesc; 83 pdesc.fVertexLayout = 0; 84 pdesc.fEmitsPointSize = random.nextF() > .5f; 85 pdesc.fColorInput = random_int(&random, ProgramDesc::kColorInputCnt); 86 pdesc.fCoverageInput = random_int(&random, ProgramDesc::kColorInputCnt); 87 88 pdesc.fColorFilterXfermode = random_int(&random, SkXfermode::kCoeffModesCnt); 89 90 pdesc.fFirstCoverageStage = random_int(&random, GrDrawState::kNumStages); 91 92 pdesc.fVertexLayout |= random_bool(&random) ? 93 GrDrawTarget::kCoverage_VertexLayoutBit : 94 0; 95 96#if GR_GL_EXPERIMENTAL_GS 97 pdesc.fExperimentalGS = this->getCaps().geometryShaderSupport() && 98 random_bool(&random); 99#endif 100 101 bool edgeAA = random_bool(&random); 102 if (edgeAA) { 103 pdesc.fVertexLayout |= GrDrawTarget::kEdge_VertexLayoutBit; 104 if (this->getCaps().shaderDerivativeSupport()) { 105 pdesc.fVertexEdgeType = (GrDrawState::VertexEdgeType) random_int(&random, GrDrawState::kVertexEdgeTypeCnt); 106 } else { 107 pdesc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType; 108 } 109 } else { 110 } 111 112 if (this->getCaps().dualSourceBlendingSupport()) { 113 pdesc.fDualSrcOutput = random_int(&random, ProgramDesc::kDualSrcOutputCnt); 114 } else { 115 pdesc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput; 116 } 117 118 GrEffectStage stages[GrDrawState::kNumStages]; 119 120 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 121 StageDesc& stageDesc = pdesc.fStages[s]; 122 // enable the stage? 123 if (random_bool(&random)) { 124 // use separate tex coords? 125 if (random_bool(&random)) { 126 int t = random_int(&random, GrDrawState::kMaxTexCoords); 127 pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t); 128 } 129 stageDesc.setEnabled(true); 130 } 131 // use text-formatted verts? 132 if (random_bool(&random)) { 133 pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit; 134 } 135 136 stageDesc.fEffectKey = 0; 137 stageDesc.fOptFlags |= STAGE_OPTS[random_int(&random, GR_ARRAY_COUNT(STAGE_OPTS))]; 138 139 if (stageDesc.isEnabled()) { 140 GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()}; 141 SkAutoTUnref<const GrEffect> effect(create_random_effect(&random, 142 getContext(), 143 dummyTextures)); 144 stages[s].setEffect(effect.get()); 145 if (NULL != stages[s].getEffect()) { 146 stageDesc.fEffectKey = 147 stages[s].getEffect()->getFactory().glEffectKey(stages[s], this->glCaps()); 148 } 149 } 150 } 151 const GrEffectStage* stagePtrs[GrDrawState::kNumStages]; 152 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 153 stagePtrs[s] = &stages[s]; 154 } 155 SkAutoTUnref<GrGLProgram> program(GrGLProgram::Create(this->glContextInfo(), 156 pdesc, 157 stagePtrs)); 158 if (NULL == program.get()) { 159 return false; 160 } 161 } 162 return true; 163} 164 165static void GLProgramsTest(skiatest::Reporter* reporter, GrContext* context) { 166 GrGpuGL* shadersGpu = static_cast<GrGpuGL*>(context->getGpu()); 167 REPORTER_ASSERT(reporter, shadersGpu->programUnitTest()); 168} 169 170#include "TestClassDef.h" 171DEFINE_GPUTESTCLASS("GLPrograms", GLProgramsTestClass, GLProgramsTest) 172 173// This is evil evil evil. The linker may throw away whole translation units as dead code if it 174// thinks none of the functions are called. It will do this even if there are static initializers 175// in the unit that could pass pointers to functions from the unit out to other translation units! 176// We force some of the effects that would otherwise be discarded to link here. 177 178#include "SkLightingImageFilter.h" 179#include "SkMagnifierImageFilter.h" 180#include "SkColorMatrixFilter.h" 181 182void forceLinking(); 183 184void forceLinking() { 185 SkLightingImageFilter::CreateDistantLitDiffuse(SkPoint3(0,0,0), 0, 0, 0); 186 SkMagnifierImageFilter mag(SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1); 187 GrEffectStage dummyStage; 188 GrConfigConversionEffect::InstallEffect(NULL, 189 false, 190 GrConfigConversionEffect::kNone_PMConversion, 191 SkMatrix::I(), 192 &dummyStage); 193 SkScalar matrix[20]; 194 SkColorMatrixFilter cmf(matrix); 195} 196 197#endif 198