1a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com 2a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com/* 3a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com * Copyright 2011 Google Inc. 4a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com * 5a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 6a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com * found in the LICENSE file. 7a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com */ 8a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com 9d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com// This is a GPU-backend specific test. It relies on static intializers to work 10cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com 112a48c3adb7cf4fc754f99a41352210b4a99edf04bsalomon@google.com#include "SkTypes.h" 122a48c3adb7cf4fc754f99a41352210b4a99edf04bsalomon@google.com 132a48c3adb7cf4fc754f99a41352210b4a99edf04bsalomon@google.com#if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 142a48c3adb7cf4fc754f99a41352210b4a99edf04bsalomon@google.com 15b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrBackendProcessorFactory.h" 1667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com#include "GrContextFactory.h" 17c06482494d2be6481a3666a66254b6c66890f994egdaniel#include "GrOptDrawState.h" 18a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com#include "effects/GrConfigConversionEffect.h" 19ec56e4545477e30d4f165ca55ed99f90525c6c38kkinnunen#include "gl/GrGLPathRendering.h" 208f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "gl/GrGpuGL.h" 212db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com#include "SkChecksum.h" 22223137f49d1a4e805f5c1b1c20b7fd68719ac54btfarina@chromium.org#include "SkRandom.h" 23c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com#include "Test.h" 24c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com 25b0a8a377f832c59cee939ad721e1f87d378b7142joshualittstatic void get_stage_stats(const GrFragmentStage stage, bool* readsDst, 26a7dc0a83f0b59424a61e01bf3435cd7957e84e35egdaniel bool* readsFragPosition, bool* requiresVertexShader) { 27b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (stage.getFragmentProcessor()->willReadDstColor()) { 28a7dc0a83f0b59424a61e01bf3435cd7957e84e35egdaniel *readsDst = true; 29a7dc0a83f0b59424a61e01bf3435cd7957e84e35egdaniel } 30b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (stage.getProcessor()->willReadFragmentPosition()) { 31a7dc0a83f0b59424a61e01bf3435cd7957e84e35egdaniel *readsFragPosition = true; 32a7dc0a83f0b59424a61e01bf3435cd7957e84e35egdaniel } 33a7dc0a83f0b59424a61e01bf3435cd7957e84e35egdaniel} 34a7dc0a83f0b59424a61e01bf3435cd7957e84e35egdaniel 35848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomonbool GrGLProgramDesc::setRandom(SkRandom* random, 36ae444965c43ad16575730ce8e3abdcaded296d94egdaniel GrGpuGL* gpu, 372db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com const GrRenderTarget* dstRenderTarget, 382db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com const GrTexture* dstCopyTexture, 39b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGeometryStage* geometryProcessor, 40b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentStage* stages[], 412db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com int numColorStages, 422db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com int numCoverageStages, 43ae444965c43ad16575730ce8e3abdcaded296d94egdaniel int currAttribIndex, 44ae444965c43ad16575730ce8e3abdcaded296d94egdaniel GrGpu::DrawType drawType) { 45ae444965c43ad16575730ce8e3abdcaded296d94egdaniel bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType); 46ae444965c43ad16575730ce8e3abdcaded296d94egdaniel bool useLocalCoords = !isPathRendering && 47ae444965c43ad16575730ce8e3abdcaded296d94egdaniel random->nextBool() && 48ae444965c43ad16575730ce8e3abdcaded296d94egdaniel currAttribIndex < GrDrawState::kMaxVertexAttribCnt; 49848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon 50848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon int numStages = numColorStages + numCoverageStages; 51848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon fKey.reset(); 52848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon 53929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); 54848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon 55848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon // Make room for everything up to and including the array of offsets to effect keys. 56bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * (numStages + 57bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt (geometryProcessor ? 1 : 0))); 58848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon 59848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon bool dstRead = false; 60848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon bool fragPos = false; 6149f085dddff10473b6ebf832a974288300224e60bsalomon bool vertexShader = SkToBool(geometryProcessor); 62bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt int offset = 0; 6349f085dddff10473b6ebf832a974288300224e60bsalomon if (geometryProcessor) { 64b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGeometryStage* stage = geometryProcessor; 65929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() + 66929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon kEffectKeyOffsetsAndLengthOffset + 67bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt offset * 2 * sizeof(uint16_t)); 68929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon uint32_t effectKeyOffset = fKey.count(); 69929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon if (effectKeyOffset > SK_MaxU16) { 70929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon fKey.reset(); 71929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon return false; 72929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon } 73b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder b(&fKey); 74929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon uint16_t effectKeySize; 75b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (!GetProcessorKey(*stage, gpu->glCaps(), useLocalCoords, &b, &effectKeySize)) { 76bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt fKey.reset(); 77bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt return false; 78bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt } 79b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt vertexShader = true; 80b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fragPos = stage->getProcessor()->willReadFragmentPosition(); 81bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt offsetAndSize[0] = effectKeyOffset; 82bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt offsetAndSize[1] = effectKeySize; 83bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt offset++; 84bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt } 85bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt 86bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt for (int s = 0; s < numStages; ++s, ++offset) { 87b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentStage* stage = stages[s]; 88bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() + 89bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt kEffectKeyOffsetsAndLengthOffset + 90bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt offset * 2 * sizeof(uint16_t)); 91bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt uint32_t effectKeyOffset = fKey.count(); 92bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt if (effectKeyOffset > SK_MaxU16) { 93bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt fKey.reset(); 94bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt return false; 95bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt } 96b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder b(&fKey); 97bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt uint16_t effectKeySize; 98b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (!GetProcessorKey(*stages[s], gpu->glCaps(), useLocalCoords, &b, &effectKeySize)) { 99848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon fKey.reset(); 100848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon return false; 101848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon } 102a7dc0a83f0b59424a61e01bf3435cd7957e84e35egdaniel get_stage_stats(*stage, &dstRead, &fragPos, &vertexShader); 103929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon offsetAndSize[0] = effectKeyOffset; 104929f29a5c1bffa7f7c1b5a376351d0762b8ac561bsalomon offsetAndSize[1] = effectKeySize; 105848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon } 106054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com 1072db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com KeyHeader* header = this->header(); 108848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon memset(header, 0, kHeaderSize); 1092db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com header->fEmitsPointSize = random->nextBool(); 1102db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 1112db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com header->fPositionAttributeIndex = 0; 112054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com 11305a2ee052c9ef4c781b7b590b00b3d2da3b3449askia.committer@gmail.com // if the effects have used up all off the available attributes, 114054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com // don't try to use color or coverage attributes as input 115054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com do { 116ae444965c43ad16575730ce8e3abdcaded296d94egdaniel header->fColorInput = static_cast<GrGLProgramDesc::ColorInput>( 117ae444965c43ad16575730ce8e3abdcaded296d94egdaniel random->nextULessThan(kColorInputCnt)); 118ae444965c43ad16575730ce8e3abdcaded296d94egdaniel } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRendering) && 1192db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com kAttribute_ColorInput == header->fColorInput); 1202db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com header->fColorAttributeIndex = (header->fColorInput == kAttribute_ColorInput) ? 1212db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com currAttribIndex++ : 1222db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com -1; 123054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com 124054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com do { 125949eef0af2f5b47000e637347801cf2970092a38commit-bot@chromium.org header->fCoverageInput = static_cast<GrGLProgramDesc::ColorInput>( 126949eef0af2f5b47000e637347801cf2970092a38commit-bot@chromium.org random->nextULessThan(kColorInputCnt)); 127ae444965c43ad16575730ce8e3abdcaded296d94egdaniel } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRendering) && 1282db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com kAttribute_ColorInput == header->fCoverageInput); 1292db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com header->fCoverageAttributeIndex = (header->fCoverageInput == kAttribute_ColorInput) ? 1302db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com currAttribIndex++ : 1312db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com -1; 13243d361f7fa7d7b61168c7c2856bd0a7b1fddc862bsalomon bool useGS = random->nextBool(); 13391207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com#if GR_GL_EXPERIMENTAL_GS 13443d361f7fa7d7b61168c7c2856bd0a7b1fddc862bsalomon header->fExperimentalGS = gpu->caps()->geometryShaderSupport() && useGS; 13543d361f7fa7d7b61168c7c2856bd0a7b1fddc862bsalomon#else 13643d361f7fa7d7b61168c7c2856bd0a7b1fddc862bsalomon (void) useGS; 13791207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com#endif 13891207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com 1392db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com header->fLocalCoordAttributeIndex = useLocalCoords ? currAttribIndex++ : -1; 1402db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 1412db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com header->fColorEffectCnt = numColorStages; 1422db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com header->fCoverageEffectCnt = numCoverageStages; 143c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com 144b79d865f03456b67273b568fa5046b8ba01e365absalomon@google.com if (dstRead) { 14530ba436f04e61d4505fb854d5fc56079636e0788joshualitt header->fDstReadKey = SkToU8(GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture, 146848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon gpu->glCaps())); 1472db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } else { 1482db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com header->fDstReadKey = 0; 1492db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } 1502db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com if (fragPos) { 15130ba436f04e61d4505fb854d5fc56079636e0788joshualitt header->fFragPosKey = SkToU8(GrGLFragmentShaderBuilder::KeyForFragmentPosition(dstRenderTarget, 152848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon gpu->glCaps())); 1532db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com } else { 1542db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com header->fFragPosKey = 0; 155b79d865f03456b67273b568fa5046b8ba01e365absalomon@google.com } 1565920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com 157ae444965c43ad16575730ce8e3abdcaded296d94egdaniel header->fUseFragShaderOnly = isPathRendering && gpu->glPathRendering()->texturingMode() == 158ae444965c43ad16575730ce8e3abdcaded296d94egdaniel GrGLPathRendering::FixedFunction_TexturingMode; 159bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt header->fHasGeometryProcessor = vertexShader; 1606b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org 161c06482494d2be6481a3666a66254b6c66890f994egdaniel GrOptDrawState::PrimaryOutputType primaryOutput; 162c06482494d2be6481a3666a66254b6c66890f994egdaniel GrOptDrawState::SecondaryOutputType secondaryOutput; 163c06482494d2be6481a3666a66254b6c66890f994egdaniel if (!dstRead) { 164c06482494d2be6481a3666a66254b6c66890f994egdaniel primaryOutput = GrOptDrawState::kModulate_PrimaryOutputType; 165c06482494d2be6481a3666a66254b6c66890f994egdaniel } else { 166c06482494d2be6481a3666a66254b6c66890f994egdaniel primaryOutput = static_cast<GrOptDrawState::PrimaryOutputType>( 167c06482494d2be6481a3666a66254b6c66890f994egdaniel random->nextULessThan(GrOptDrawState::kPrimaryOutputTypeCnt)); 168c06482494d2be6481a3666a66254b6c66890f994egdaniel } 1695920ac276877b36624e07baf97c7768e80a07f98bsalomon@google.com 170c06482494d2be6481a3666a66254b6c66890f994egdaniel if (GrOptDrawState::kCombineWithDst_PrimaryOutputType == primaryOutput || 171c06482494d2be6481a3666a66254b6c66890f994egdaniel !gpu->caps()->dualSourceBlendingSupport()) { 172c06482494d2be6481a3666a66254b6c66890f994egdaniel secondaryOutput = GrOptDrawState::kNone_SecondaryOutputType; 173c06482494d2be6481a3666a66254b6c66890f994egdaniel } else { 174c06482494d2be6481a3666a66254b6c66890f994egdaniel secondaryOutput = static_cast<GrOptDrawState::SecondaryOutputType>( 175c06482494d2be6481a3666a66254b6c66890f994egdaniel random->nextULessThan(GrOptDrawState::kSecondaryOutputTypeCnt)); 176c06482494d2be6481a3666a66254b6c66890f994egdaniel } 177c06482494d2be6481a3666a66254b6c66890f994egdaniel 178c06482494d2be6481a3666a66254b6c66890f994egdaniel header->fPrimaryOutputType = primaryOutput; 179c06482494d2be6481a3666a66254b6c66890f994egdaniel header->fSecondaryOutputType = secondaryOutput; 1802db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 181848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon this->finalize(); 182848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon return true; 18391207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com} 18491207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com 185249af15fb82833d2274850c589812b6e69df0033joshualitt// TODO clean this up, we have to do this to test geometry processors but there has got to be 186249af15fb82833d2274850c589812b6e69df0033joshualitt// a better way. In the mean time, we actually fill out these generic vertex attribs below with 187249af15fb82833d2274850c589812b6e69df0033joshualitt// the correct vertex attribs from the GP. We have to ensure, however, we don't try to add more 188249af15fb82833d2274850c589812b6e69df0033joshualitt// than two attributes. 189249af15fb82833d2274850c589812b6e69df0033joshualittGrVertexAttrib genericVertexAttribs[] = { 190249af15fb82833d2274850c589812b6e69df0033joshualitt { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 191b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding }, 192b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } 193249af15fb82833d2274850c589812b6e69df0033joshualitt}; 194249af15fb82833d2274850c589812b6e69df0033joshualitt 195249af15fb82833d2274850c589812b6e69df0033joshualitt/* 196249af15fb82833d2274850c589812b6e69df0033joshualitt * convert sl type to vertexattrib type, not a complete implementation, only use for debugging 197249af15fb82833d2274850c589812b6e69df0033joshualitt */ 198249af15fb82833d2274850c589812b6e69df0033joshualittGrVertexAttribType convert_sltype_to_attribtype(GrSLType type) { 199249af15fb82833d2274850c589812b6e69df0033joshualitt switch (type) { 200249af15fb82833d2274850c589812b6e69df0033joshualitt case kFloat_GrSLType: 201249af15fb82833d2274850c589812b6e69df0033joshualitt return kFloat_GrVertexAttribType; 202249af15fb82833d2274850c589812b6e69df0033joshualitt case kVec2f_GrSLType: 203249af15fb82833d2274850c589812b6e69df0033joshualitt return kVec2f_GrVertexAttribType; 204249af15fb82833d2274850c589812b6e69df0033joshualitt case kVec3f_GrSLType: 205249af15fb82833d2274850c589812b6e69df0033joshualitt return kVec3f_GrVertexAttribType; 206249af15fb82833d2274850c589812b6e69df0033joshualitt case kVec4f_GrSLType: 207249af15fb82833d2274850c589812b6e69df0033joshualitt return kVec4f_GrVertexAttribType; 208249af15fb82833d2274850c589812b6e69df0033joshualitt default: 209249af15fb82833d2274850c589812b6e69df0033joshualitt SkFAIL("Type isn't convertible"); 210249af15fb82833d2274850c589812b6e69df0033joshualitt return kFloat_GrVertexAttribType; 211249af15fb82833d2274850c589812b6e69df0033joshualitt } 212249af15fb82833d2274850c589812b6e69df0033joshualitt} 213249af15fb82833d2274850c589812b6e69df0033joshualitt// TODO end test hack 214249af15fb82833d2274850c589812b6e69df0033joshualitt 215249af15fb82833d2274850c589812b6e69df0033joshualitt 216042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.combool GrGpuGL::programUnitTest(int maxStages) { 217042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.com 218d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com GrTextureDesc dummyDesc; 2192db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com dummyDesc.fFlags = kRenderTarget_GrTextureFlagBit; 220fec0bc3fc13481f5bcb341ab2d2d695911f39bd4bsalomon@google.com dummyDesc.fConfig = kSkia8888_GrPixelConfig; 221d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com dummyDesc.fWidth = 34; 222d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com dummyDesc.fHeight = 18; 223d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com SkAutoTUnref<GrTexture> dummyTexture1(this->createTexture(dummyDesc, NULL, 0)); 2242db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com dummyDesc.fFlags = kNone_GrTextureFlags; 225d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com dummyDesc.fConfig = kAlpha_8_GrPixelConfig; 226d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com dummyDesc.fWidth = 16; 227d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com dummyDesc.fHeight = 22; 228d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0)); 229d472620458e2383e6dd949f4e1aaf61160717ffebsalomon@google.com 230e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon if (!dummyTexture1 || ! dummyTexture2) { 231e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon return false; 232e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon } 233e904c09a3a9c701e8d91f2f6ee161feda7615d90bsalomon 234c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com static const int NUM_TESTS = 512; 235c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com 236e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom random; 237c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com for (int t = 0; t < NUM_TESTS; ++t) { 238c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com 239c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com#if 0 240c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com GrPrintf("\nTest Program %d\n-------------\n", t); 241c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com static const int stop = -1; 242c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com if (t == stop) { 243c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com int breakpointhere = 9; 244c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com } 245c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com#endif 246c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com 24731ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com GrGLProgramDesc pdesc; 248c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com 249054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com int currAttribIndex = 1; // we need to always leave room for position 2508e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org int currTextureCoordSet = 0; 251b79d865f03456b67273b568fa5046b8ba01e365absalomon@google.com GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()}; 2522db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 2532db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com int numStages = random.nextULessThan(maxStages + 1); 2542db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com int numColorStages = random.nextULessThan(numStages + 1); 2552db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com int numCoverageStages = numStages - numColorStages; 2562db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 257b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoSTMalloc<8, const GrFragmentStage*> stages(numStages); 2582db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 259ae444965c43ad16575730ce8e3abdcaded296d94egdaniel bool usePathRendering = this->glCaps().pathRenderingSupport() && random.nextBool(); 260c06482494d2be6481a3666a66254b6c66890f994egdaniel 261ae444965c43ad16575730ce8e3abdcaded296d94egdaniel GrGpu::DrawType drawType = usePathRendering ? GrGpu::kDrawPath_DrawType : 262ae444965c43ad16575730ce8e3abdcaded296d94egdaniel GrGpu::kDrawPoints_DrawType; 263bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt 264b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTDelete<GrGeometryStage> geometryProcessor; 265ae444965c43ad16575730ce8e3abdcaded296d94egdaniel bool hasGeometryProcessor = usePathRendering ? false : random.nextBool(); 266bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt if (hasGeometryProcessor) { 267bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt while (true) { 268b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<const GrGeometryProcessor> effect( 269b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(&random, this->getContext(), *this->caps(), 270b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt dummyTextures)); 271bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt SkASSERT(effect); 272bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt // Only geometryProcessor can use vertex shader 273b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGeometryStage* stage = SkNEW_ARGS(GrGeometryStage, (effect.get())); 274bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt geometryProcessor.reset(stage); 275249af15fb82833d2274850c589812b6e69df0033joshualitt 276249af15fb82833d2274850c589812b6e69df0033joshualitt // we have to set dummy vertex attribs 277b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrGeometryProcessor::VertexAttribArray& v = effect->getVertexAttribs(); 278249af15fb82833d2274850c589812b6e69df0033joshualitt int numVertexAttribs = v.count(); 279249af15fb82833d2274850c589812b6e69df0033joshualitt 280b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkASSERT(GrGeometryProcessor::kMaxVertexAttribs == 2 && 281b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGeometryProcessor::kMaxVertexAttribs >= numVertexAttribs); 282249af15fb82833d2274850c589812b6e69df0033joshualitt size_t runningStride = GrVertexAttribTypeSize(genericVertexAttribs[0].fType); 283249af15fb82833d2274850c589812b6e69df0033joshualitt for (int i = 0; i < numVertexAttribs; i++) { 284249af15fb82833d2274850c589812b6e69df0033joshualitt genericVertexAttribs[i + 1].fOffset = runningStride; 285249af15fb82833d2274850c589812b6e69df0033joshualitt genericVertexAttribs[i + 1].fType = 286249af15fb82833d2274850c589812b6e69df0033joshualitt convert_sltype_to_attribtype(v[i].getType()); 287249af15fb82833d2274850c589812b6e69df0033joshualitt runningStride += GrVertexAttribTypeSize(genericVertexAttribs[i + 1].fType); 288249af15fb82833d2274850c589812b6e69df0033joshualitt } 289249af15fb82833d2274850c589812b6e69df0033joshualitt 290249af15fb82833d2274850c589812b6e69df0033joshualitt // update the vertex attributes with the ds 291249af15fb82833d2274850c589812b6e69df0033joshualitt GrDrawState* ds = this->drawState(); 292249af15fb82833d2274850c589812b6e69df0033joshualitt ds->setVertexAttribs<genericVertexAttribs>(numVertexAttribs + 1, runningStride); 293249af15fb82833d2274850c589812b6e69df0033joshualitt currAttribIndex = numVertexAttribs + 1; 294bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt break; 295bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt } 296bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt } 2978e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org for (int s = 0; s < numStages;) { 298b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkAutoTUnref<const GrFragmentProcessor> effect( 299b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorTestFactory<GrFragmentProcessor>::CreateStage( 3002db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com &random, 3012db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com this->getContext(), 3022db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com *this->caps(), 3032db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com dummyTextures)); 30465ee5f424cb4dabd453268902c00086605d77c1dcommit-bot@chromium.org SkASSERT(effect); 3052db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com 3068e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org // If adding this effect would exceed the max texture coord set count then generate a 3078e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org // new random effect. 308ae444965c43ad16575730ce8e3abdcaded296d94egdaniel if (usePathRendering && this->glPathRendering()->texturingMode() == 309ae444965c43ad16575730ce8e3abdcaded296d94egdaniel GrGLPathRendering::FixedFunction_TexturingMode) {; 31097b9ab72cd5ee0cba4692082737266376425f27cbsalomon int numTransforms = effect->numTransforms(); 3118e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org if (currTextureCoordSet + numTransforms > this->glCaps().maxFixedFunctionTextureCoords()) { 3128e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org continue; 3138e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org } 3148e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org currTextureCoordSet += numTransforms; 3158e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org } 316b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentStage* stage = SkNEW_ARGS(GrFragmentStage, (effect.get())); 317bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt 3182db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com stages[s] = stage; 3198e919add406c5d20918a7f0ca811317312e6ce67commit-bot@chromium.org ++s; 320c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com } 321b79d865f03456b67273b568fa5046b8ba01e365absalomon@google.com const GrTexture* dstTexture = random.nextBool() ? dummyTextures[0] : dummyTextures[1]; 322848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon if (!pdesc.setRandom(&random, 323848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon this, 324848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon dummyTextures[0]->asRenderTarget(), 325848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon dstTexture, 326bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt geometryProcessor.get(), 327848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon stages.get(), 328848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon numColorStages, 329848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon numCoverageStages, 330ae444965c43ad16575730ce8e3abdcaded296d94egdaniel currAttribIndex, 331ae444965c43ad16575730ce8e3abdcaded296d94egdaniel drawType)) { 332848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon return false; 333848faf00ec33d39ab3e31e9a11d805cae6ac6562bsalomon } 33405a2ee052c9ef4c781b7b590b00b3d2da3b3449askia.committer@gmail.com 3359188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org SkAutoTUnref<GrGLProgram> program(GrGLProgram::Create(this, 336c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com pdesc, 337bd769d0f1c8cf6ccbb2738dfad1624a4c828e4ebjoshualitt geometryProcessor.get(), 3382c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com stages, 3392c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com stages + numColorStages)); 3402db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com for (int s = 0; s < numStages; ++s) { 341504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com SkDELETE(stages[s]); 342504976ef6f1b969c2ac13ff1140ea1067f085ffabsalomon@google.com } 343c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com if (NULL == program.get()) { 344c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com return false; 345c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com } 346249af15fb82833d2274850c589812b6e69df0033joshualitt 347249af15fb82833d2274850c589812b6e69df0033joshualitt // We have to reset the drawstate because we might have added a gp 348249af15fb82833d2274850c589812b6e69df0033joshualitt this->drawState()->reset(); 349c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com } 350c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com return true; 351c3841b927ba32237a540949c408f78ad7682aa60bsalomon@google.com} 352a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com 3534ee16bfaedb14aff8cf102f1f0722ff2529a9699tfarina@chromium.orgDEF_GPUTEST(GLPrograms, reporter, factory) { 35467b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { 35567b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(type)); 35649f085dddff10473b6ebf832a974288300224e60bsalomon if (context) { 357042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.com GrGpuGL* gpu = static_cast<GrGpuGL*>(context->getGpu()); 358eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com int maxStages = 6; 359042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.com#if SK_ANGLE 360042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.com // Some long shaders run out of temporary registers in the D3D compiler on ANGLE. 361042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.com if (type == GrContextFactory::kANGLE_GLContextType) { 362042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.com maxStages = 3; 363042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.com } 364042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.com#endif 365042a2861b2aa7a7a9fff12503a4b297d6ee1d335bsalomon@google.com REPORTER_ASSERT(reporter, gpu->programUnitTest(maxStages)); 36667b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 36767b915de99e6b89d476907930ac8c27afb64d10ebsalomon@google.com } 368a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com} 369a8e686eb6cadb74039d3b624ece0d3ccb0684dccbsalomon@google.com 370d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com// This is evil evil evil. The linker may throw away whole translation units as dead code if it 37167e78c9e47c38a51816412a24a10f4fe2db142a3bsalomon@google.com// thinks none of the functions are called. It will do this even if there are static initializers 372a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com// in the unit that could pass pointers to functions from the unit out to other translation units! 373a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com// We force some of the effects that would otherwise be discarded to link here. 374a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 37540eb3c100095c8573ddfdc553794b3182d7b18d1commit-bot@chromium.org#include "SkAlphaThresholdFilter.h" 3768f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkColorMatrixFilter.h" 377a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com#include "SkLightingImageFilter.h" 37882aa7482cbf55ce6d42c692550cadee5e23146e4bsalomon@google.com#include "SkMagnifierImageFilter.h" 379a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 380a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.comvoid forceLinking(); 381a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 382a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.comvoid forceLinking() { 383a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com SkLightingImageFilter::CreateDistantLitDiffuse(SkPoint3(0,0,0), 0, 0, 0); 3849109e188c77abfd2832767530d33fdec35290a84commit-bot@chromium.org SkAlphaThresholdFilter::Create(SkRegion(), .5f, .5f); 3859fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkAutoTUnref<SkImageFilter> mag(SkMagnifierImageFilter::Create( 386cac5fd597f6e2495f50aaa6bcbe3dadc56f0b977commit-bot@chromium.org SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1)); 387adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com GrConfigConversionEffect::Create(NULL, 388adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com false, 389adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com GrConfigConversionEffect::kNone_PMConversion, 390adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com SkMatrix::I()); 39167e78c9e47c38a51816412a24a10f4fe2db142a3bsalomon@google.com SkScalar matrix[20]; 392727a352f7412753d2a3e4d30eab6500a1a4de135commit-bot@chromium.org SkAutoTUnref<SkColorMatrixFilter> cmf(SkColorMatrixFilter::Create(matrix)); 393a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com} 394a1bf0fffff821d9c11809c89bd98d4ced480421absalomon@google.com 395cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif 396