180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// This is a GPU-backend specific test. It relies on static intializers to work 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTypes.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGpuGL.h" 16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrBackendEffectFactory.h" 17096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "GrContextFactory.h" 18e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger#include "GrDrawEffect.h" 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "effects/GrConfigConversionEffect.h" 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger#include "SkChecksum.h" 22363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkRandom.h" 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "Test.h" 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergervoid GrGLProgramDesc::setRandom(SkRandom* random, 267839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const GrGpuGL* gpu, 27779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger const GrRenderTarget* dstRenderTarget, 28779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger const GrTexture* dstCopyTexture, 29779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger const GrEffectStage* stages[], 30779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numColorStages, 31779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numCoverageStages, 327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int currAttribIndex) { 33779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numEffects = numColorStages + numCoverageStages; 34779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger size_t keyLength = KeyLength(numEffects); 35779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger fKey.reset(keyLength); 36779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger *this->atOffset<uint32_t, kLengthOffset>() = static_cast<uint32_t>(keyLength); 37779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger memset(this->header(), 0, kHeaderSize); 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger KeyHeader* header = this->header(); 40779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fEmitsPointSize = random->nextBool(); 41779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 42779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fPositionAttributeIndex = 0; 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // if the effects have used up all off the available attributes, 457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger // don't try to use color or coverage attributes as input 467839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger do { 470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger header->fColorInput = static_cast<GrGLProgramDesc::ColorInput>( 480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger random->nextULessThan(kColorInputCnt)); 497839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } while (GrDrawState::kMaxVertexAttribCnt <= currAttribIndex && 50779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger kAttribute_ColorInput == header->fColorInput); 51779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fColorAttributeIndex = (header->fColorInput == kAttribute_ColorInput) ? 52779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger currAttribIndex++ : 53779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger -1; 547839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger do { 560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger header->fCoverageInput = static_cast<GrGLProgramDesc::ColorInput>( 570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger random->nextULessThan(kColorInputCnt)); 587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } while (GrDrawState::kMaxVertexAttribCnt <= currAttribIndex && 59779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger kAttribute_ColorInput == header->fCoverageInput); 60779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fCoverageAttributeIndex = (header->fCoverageInput == kAttribute_ColorInput) ? 61779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger currAttribIndex++ : 62779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger -1; 637839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 64096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#if GR_GL_EXPERIMENTAL_GS 65779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fExperimentalGS = gpu->caps()->geometryShaderSupport() && random->nextBool(); 66096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#endif 67096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 68779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fDiscardIfZeroCoverage = random->nextBool(); 69096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 707839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool useLocalCoords = random->nextBool() && currAttribIndex < GrDrawState::kMaxVertexAttribCnt; 71779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fLocalCoordAttributeIndex = useLocalCoords ? currAttribIndex++ : -1; 72779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 73779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fColorEffectCnt = numColorStages; 74779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fCoverageEffectCnt = numCoverageStages; 75e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger 767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool dstRead = false; 77779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger bool fragPos = false; 780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger bool vertexCode = false; 79779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numStages = numColorStages + numCoverageStages; 80779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger for (int s = 0; s < numStages; ++s) { 81779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger const GrBackendEffectFactory& factory = (*stages[s]->getEffect())->getFactory(); 82779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger GrDrawEffect drawEffect(*stages[s], useLocalCoords); 83779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger this->effectKeys()[s] = factory.glEffectKey(drawEffect, gpu->glCaps()); 84779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger if ((*stages[s]->getEffect())->willReadDstColor()) { 85779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger dstRead = true; 86779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 87779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger if ((*stages[s]->getEffect())->willReadFragmentPosition()) { 88779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger fragPos = true; 89096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if ((*stages[s]->getEffect())->hasVertexCode()) { 910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger vertexCode = true; 920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 93096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 94096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger if (dstRead) { 96779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fDstReadKey = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps()); 97779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } else { 98779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fDstReadKey = 0; 99779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 100779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger if (fragPos) { 101779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fFragPosKey = GrGLShaderBuilder::KeyForFragmentPosition(dstRenderTarget, 102779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger gpu->glCaps()); 103779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } else { 104779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fFragPosKey = 0; 105096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 1067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger header->fHasVertexCode = vertexCode || 1080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger useLocalCoords || 1090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kAttribute_ColorInput == header->fColorInput || 1100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger kAttribute_ColorInput == header->fCoverageInput; 1110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger CoverageOutput coverageOutput; 1137839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger bool illegalCoverageOutput; 1147839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger do { 1157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger coverageOutput = static_cast<CoverageOutput>(random->nextULessThan(kCoverageOutputCnt)); 1167839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger illegalCoverageOutput = (!gpu->caps()->dualSourceBlendingSupport() && 1177839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger CoverageOutputUsesSecondaryOutput(coverageOutput)) || 1187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger (!dstRead && kCombineWithDst_CoverageOutput == coverageOutput); 1197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } while (illegalCoverageOutput); 1207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger 121779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger header->fCoverageOutput = coverageOutput; 122779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 123779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger *this->checksum() = 0; 124779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger *this->checksum() = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.get()), keyLength); 125779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger fInitialized = true; 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 128096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerbool GrGpuGL::programUnitTest(int maxStages) { 129096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrTextureDesc dummyDesc; 131779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger dummyDesc.fFlags = kRenderTarget_GrTextureFlagBit; 132096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger dummyDesc.fConfig = kSkia8888_GrPixelConfig; 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyDesc.fWidth = 34; 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyDesc.fHeight = 18; 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoTUnref<GrTexture> dummyTexture1(this->createTexture(dummyDesc, NULL, 0)); 136779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger dummyDesc.fFlags = kNone_GrTextureFlags; 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyDesc.fConfig = kAlpha_8_GrPixelConfig; 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyDesc.fWidth = 16; 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dummyDesc.fHeight = 22; 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0)); 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int NUM_TESTS = 512; 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkRandom random; 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int t = 0; t < NUM_TESTS; ++t) { 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrPrintf("\nTest Program %d\n-------------\n", t); 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int stop = -1; 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (t == stop) { 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int breakpointhere = 9; 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1557839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrGLProgramDesc pdesc; 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger int currAttribIndex = 1; // we need to always leave room for position 1580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger int currTextureCoordSet = 0; 159096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger int attribIndices[2]; 1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()}; 161779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 162779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numStages = random.nextULessThan(maxStages + 1); 163779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numColorStages = random.nextULessThan(numStages + 1); 164779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numCoverageStages = numStages - numColorStages; 165779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 166779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkAutoSTMalloc<8, const GrEffectStage*> stages(numStages); 167779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 1680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger bool useFixedFunctionTexturing = this->shouldUseFixedFunctionTexturing(); 1690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger for (int s = 0; s < numStages;) { 171779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger SkAutoTUnref<const GrEffectRef> effect(GrEffectTestFactory::CreateStage( 172779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger &random, 173779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger this->getContext(), 174779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger *this->caps(), 175779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger dummyTextures)); 176779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger int numAttribs = (*effect)->numVertexAttribs(); 177779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger 178779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // If adding this effect would exceed the max attrib count then generate a 179779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger // new random effect. 180779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger if (currAttribIndex + numAttribs > GrDrawState::kMaxVertexAttribCnt) { 181779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger continue; 182779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger } 1830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // If adding this effect would exceed the max texture coord set count then generate a 1860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger // new random effect. 1870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (useFixedFunctionTexturing && !(*effect)->hasVertexCode()) { 1880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger int numTransforms = (*effect)->numTransforms(); 1890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger if (currTextureCoordSet + numTransforms > this->glCaps().maxFixedFunctionTextureCoords()) { 1900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger continue; 1910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 1920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger currTextureCoordSet += numTransforms; 1930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger } 1940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 1950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger useFixedFunctionTexturing = useFixedFunctionTexturing && !(*effect)->hasVertexCode(); 1960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger 197779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger for (int i = 0; i < numAttribs; ++i) { 198779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger attribIndices[i] = currAttribIndex++; 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrEffectStage* stage = SkNEW_ARGS(GrEffectStage, 20158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger (effect.get(), attribIndices[0], attribIndices[1])); 202779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger stages[s] = stage; 2030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger ++s; 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger const GrTexture* dstTexture = random.nextBool() ? dummyTextures[0] : dummyTextures[1]; 206779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger pdesc.setRandom(&random, 207779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger this, 208779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger dummyTextures[0]->asRenderTarget(), 209779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger dstTexture, 210779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger stages.get(), 211779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger numColorStages, 212779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger numCoverageStages, 213779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger currAttribIndex); 214096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger 2150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkAutoTUnref<GrGLProgram> program(GrGLProgram::Create(this, 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pdesc, 21758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger stages, 21858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger stages + numColorStages)); 219779bf8a99dc7f03e5c43b26d4b85d7920ce89aeeDerek Sollenberger for (int s = 0; s < numStages; ++s) { 2207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger SkDELETE(stages[s]); 2217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger } 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == program.get()) { 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 229096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerstatic void GLProgramsTest(skiatest::Reporter* reporter, GrContextFactory* factory) { 230096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { 231096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(type)); 232096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (NULL != context) { 233096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger GrGpuGL* gpu = static_cast<GrGpuGL*>(context->getGpu()); 23458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger int maxStages = 6; 235096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#if SK_ANGLE 236096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger // Some long shaders run out of temporary registers in the D3D compiler on ANGLE. 237096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger if (type == GrContextFactory::kANGLE_GLContextType) { 238096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger maxStages = 3; 239096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 240096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#endif 241096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger REPORTER_ASSERT(reporter, gpu->programUnitTest(maxStages)); 242096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 243096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger } 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "TestClassDef.h" 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruDEFINE_GPUTESTCLASS("GLPrograms", GLProgramsTestClass, GLProgramsTest) 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// This is evil evil evil. The linker may throw away whole translation units as dead code if it 250363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// thinks none of the functions are called. It will do this even if there are static initializers 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// in the unit that could pass pointers to functions from the unit out to other translation units! 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// We force some of the effects that would otherwise be discarded to link here. 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkLightingImageFilter.h" 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMagnifierImageFilter.h" 256363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "SkColorMatrixFilter.h" 2570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkBitmapAlphaThresholdShader.h" 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid forceLinking(); 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid forceLinking() { 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkLightingImageFilter::CreateDistantLitDiffuse(SkPoint3(0,0,0), 0, 0, 0); 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMagnifierImageFilter mag(SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1); 264d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrConfigConversionEffect::Create(NULL, 265d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger false, 266d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrConfigConversionEffect::kNone_PMConversion, 267d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkMatrix::I()); 268363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkScalar matrix[20]; 269363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkColorMatrixFilter cmf(matrix); 2700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger SkBitmapAlphaThresholdShader::Create(SkBitmap(), SkRegion(), 0x80); 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 274