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