GLProgramsTest.cpp revision ae81d5c4aa1716756b2cfb4c44f27f4dce2716ef
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 "GrContextFactory.h" 18#include "GrDrawEffect.h" 19#include "effects/GrConfigConversionEffect.h" 20 21#include "SkRandom.h" 22#include "Test.h" 23 24void GrGLProgram::Desc::setRandom(SkMWCRandom* random, 25 const GrGpuGL* gpu, 26 const GrEffectStage stages[GrDrawState::kNumStages]) { 27 fAttribBindings = 0; 28 fEmitsPointSize = random->nextBool(); 29 fColorInput = random->nextULessThan(kColorInputCnt); 30 fCoverageInput = random->nextULessThan(kColorInputCnt); 31 32 fColorFilterXfermode = random->nextULessThan(SkXfermode::kCoeffModesCnt); 33 34 fFirstCoverageStage = random->nextULessThan(GrDrawState::kNumStages); 35 36 fAttribBindings |= random->nextBool() ? GrDrawState::kCoverage_AttribBindingsBit : 0; 37 38#if GR_GL_EXPERIMENTAL_GS 39 fExperimentalGS = gpu->getCaps().geometryShaderSupport() && random->nextBool(); 40#endif 41 42 bool edgeAA = random->nextBool(); 43 if (edgeAA) { 44 fAttribBindings |= GrDrawState::kEdge_AttribBindingsBit; 45 if (gpu->getCaps().shaderDerivativeSupport()) { 46 fVertexEdgeType = (GrDrawState::VertexEdgeType) 47 random->nextULessThan(GrDrawState::kVertexEdgeTypeCnt); 48 fDiscardIfOutsideEdge = random->nextBool(); 49 } else { 50 fVertexEdgeType = GrDrawState::kHairLine_EdgeType; 51 fDiscardIfOutsideEdge = false; 52 } 53 } 54 55 if (gpu->getCaps().dualSourceBlendingSupport()) { 56 fDualSrcOutput = random->nextULessThan(kDualSrcOutputCnt); 57 } else { 58 fDualSrcOutput = kNone_DualSrcOutput; 59 } 60 61 // use separate tex coords? 62 if (random->nextBool()) { 63 fAttribBindings |= GrDrawState::kLocalCoords_AttribBindingsBit; 64 } 65 66 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 67 if (NULL != stages[s].getEffect()) { 68 const GrBackendEffectFactory& factory = (*stages[s].getEffect())->getFactory(); 69 bool explicitLocalCoords = (fAttribBindings & 70 GrDrawState::kLocalCoords_AttribBindingsBit); 71 GrDrawEffect drawEffect(stages[s], explicitLocalCoords); 72 fEffectKeys[s] = factory.glEffectKey(drawEffect, gpu->glCaps()); 73 } 74 } 75 76 int attributeIndex = 0; 77 fPositionAttributeIndex = attributeIndex; 78 ++attributeIndex; 79 if (fColorInput || (fAttribBindings & GrDrawState::kColor_AttribBindingsBit)) { 80 fColorAttributeIndex = attributeIndex; 81 ++attributeIndex; 82 } 83 if (fCoverageInput || (fAttribBindings & GrDrawState::kCoverage_AttribBindingsBit)) { 84 fCoverageAttributeIndex = attributeIndex; 85 ++attributeIndex; 86 } 87 if (fAttribBindings & GrDrawState::kEdge_AttribBindingsBit) { 88 fEdgeAttributeIndex = attributeIndex; 89 ++attributeIndex; 90 } 91 if (fAttribBindings & GrDrawState::kLocalCoords_AttribBindingsBit) { 92 fLocalCoordsAttributeIndex = attributeIndex; 93 ++attributeIndex; 94 } 95} 96 97bool GrGpuGL::programUnitTest(int maxStages) { 98 99 maxStages = GrMin(maxStages, (int)GrDrawState::kNumStages); 100 101 GrTextureDesc dummyDesc; 102 dummyDesc.fConfig = kSkia8888_GrPixelConfig; 103 dummyDesc.fWidth = 34; 104 dummyDesc.fHeight = 18; 105 SkAutoTUnref<GrTexture> dummyTexture1(this->createTexture(dummyDesc, NULL, 0)); 106 dummyDesc.fConfig = kAlpha_8_GrPixelConfig; 107 dummyDesc.fWidth = 16; 108 dummyDesc.fHeight = 22; 109 SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0)); 110 111 static const int NUM_TESTS = 512; 112 113 SkMWCRandom random; 114 for (int t = 0; t < NUM_TESTS; ++t) { 115 116#if 0 117 GrPrintf("\nTest Program %d\n-------------\n", t); 118 static const int stop = -1; 119 if (t == stop) { 120 int breakpointhere = 9; 121 } 122#endif 123 124 GrGLProgram::Desc pdesc; 125 GrEffectStage stages[GrDrawState::kNumStages]; 126 127 int currAttribIndex = GrDrawState::kAttribIndexCount; 128 int attribIndices[2]; 129 for (int s = 0; s < maxStages; ++s) { 130 // enable the stage? 131 if (random.nextBool()) { 132 GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()}; 133 SkAutoTUnref<const GrEffectRef> effect(GrEffectTestFactory::CreateStage( 134 &random, 135 this->getContext(), 136 dummyTextures)); 137 for (int i = 0; i < effect.get()->get()->numVertexAttribs(); ++i) { 138 attribIndices[i] = currAttribIndex++; 139 } 140 stages[s].setEffect(effect.get(), attribIndices[0], attribIndices[1]); 141 } 142 } 143 pdesc.setRandom(&random, this, stages); 144 145 const GrEffectStage* stagePtrs[GrDrawState::kNumStages]; 146 for (int s = 0; s < GrDrawState::kNumStages; ++s) { 147 stagePtrs[s] = &stages[s]; 148 } 149 SkAutoTUnref<GrGLProgram> program(GrGLProgram::Create(this->glContext(), 150 pdesc, 151 stagePtrs)); 152 if (NULL == program.get()) { 153 return false; 154 } 155 } 156 return true; 157} 158 159static void GLProgramsTest(skiatest::Reporter* reporter, GrContextFactory* factory) { 160 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { 161 GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(type)); 162 if (NULL != context) { 163 GrGpuGL* gpu = static_cast<GrGpuGL*>(context->getGpu()); 164 int maxStages = GrDrawState::kNumStages; 165#if SK_ANGLE 166 // Some long shaders run out of temporary registers in the D3D compiler on ANGLE. 167 if (type == GrContextFactory::kANGLE_GLContextType) { 168 maxStages = 3; 169 } 170#endif 171 REPORTER_ASSERT(reporter, gpu->programUnitTest(maxStages)); 172 } 173 } 174} 175 176#include "TestClassDef.h" 177DEFINE_GPUTESTCLASS("GLPrograms", GLProgramsTestClass, GLProgramsTest) 178 179// This is evil evil evil. The linker may throw away whole translation units as dead code if it 180// thinks none of the functions are called. It will do this even if there are static initializers 181// in the unit that could pass pointers to functions from the unit out to other translation units! 182// We force some of the effects that would otherwise be discarded to link here. 183 184#include "SkLightingImageFilter.h" 185#include "SkMagnifierImageFilter.h" 186#include "SkColorMatrixFilter.h" 187 188void forceLinking(); 189 190void forceLinking() { 191 SkLightingImageFilter::CreateDistantLitDiffuse(SkPoint3(0,0,0), 0, 0, 0); 192 SkMagnifierImageFilter mag(SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1); 193 GrConfigConversionEffect::Create(NULL, 194 false, 195 GrConfigConversionEffect::kNone_PMConversion, 196 SkMatrix::I()); 197 SkScalar matrix[20]; 198 SkColorMatrixFilter cmf(matrix); 199} 200 201#endif 202