Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: tests/GLProgramsTest.cpp

Issue 628633003: gl programs rewrite (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: build fix Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/gl/GrGpuGL_program.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 // This is a GPU-backend specific test. It relies on static intializers to work 9 // This is a GPU-backend specific test. It relies on static intializers to work
10 10
11 #include "SkTypes.h" 11 #include "SkTypes.h"
12 12
13 #if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 13 #if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
14 14
15 #include "GrBackendProcessorFactory.h" 15 #include "GrTBackendProcessorFactory.h"
16 #include "GrContextFactory.h" 16 #include "GrContextFactory.h"
17 #include "GrOptDrawState.h" 17 #include "GrOptDrawState.h"
18 #include "effects/GrConfigConversionEffect.h" 18 #include "effects/GrConfigConversionEffect.h"
19 #include "gl/builders/GrGLProgramBuilder.h" 19 #include "gl/builders/GrGLProgramBuilder.h"
20 #include "gl/GrGLPathRendering.h" 20 #include "gl/GrGLPathRendering.h"
21 #include "gl/GrGpuGL.h" 21 #include "gl/GrGpuGL.h"
22 #include "SkChecksum.h" 22 #include "SkChecksum.h"
23 #include "SkRandom.h" 23 #include "SkRandom.h"
24 #include "Test.h" 24 #include "Test.h"
25 25
26 static void get_stage_stats(const GrFragmentStage stage, bool* readsDst, 26 /*
27 bool* readsFragPosition, bool* requiresVertexShader) { 27 * A dummy effect which just tries to insert a massive key and verify that it ca n retrieve the
28 if (stage.getProcessor()->willReadDstColor()) { 28 * whole thing correctly
29 *readsDst = true; 29 */
30 static const uint32_t kMaxKeySize = 1024;
31
32 class GLBigKeyProcessor;
33
34 class BigKeyProcessor : public GrFragmentProcessor {
35 public:
36 static GrFragmentProcessor* Create() {
37 GR_CREATE_STATIC_FRAGMENT_PROCESSOR(gBigKeyProcessor, BigKeyProcessor, ( ))
38 return SkRef(gBigKeyProcessor);
30 } 39 }
31 if (stage.getProcessor()->willReadFragmentPosition()) { 40
32 *readsFragPosition = true; 41 static const char* Name() { return "Big ol' Key"; }
42
43 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR IDE {
44 return GrTBackendFragmentProcessorFactory<BigKeyProcessor>::getInstance( );
33 } 45 }
46
47 typedef GLBigKeyProcessor GLProcessor;
48
49 private:
50 BigKeyProcessor() { }
51 virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE { return true; }
52 virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERR IDE { }
53
54 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
55
56 typedef GrFragmentProcessor INHERITED;
57 };
58
59 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(BigKeyProcessor);
60
61 GrFragmentProcessor* BigKeyProcessor::TestCreate(SkRandom*,
62 GrContext*,
63 const GrDrawTargetCaps&,
64 GrTexture*[]) {
65 return BigKeyProcessor::Create();
34 } 66 }
35 67
36 bool GrGLProgramDesc::setRandom(SkRandom* random, 68 class GLBigKeyProcessor : public GrGLFragmentProcessor {
37 GrGpuGL* gpu, 69 public:
38 const GrRenderTarget* dstRenderTarget, 70 GLBigKeyProcessor(const GrBackendProcessorFactory& factory, const GrProcesso r&)
39 const GrTexture* dstCopyTexture, 71 : INHERITED(factory) {}
40 const GrGeometryStage* geometryProcessor,
41 const GrFragmentStage* stages[],
42 int numColorStages,
43 int numCoverageStages,
44 int currAttribIndex,
45 GrGpu::DrawType drawType) {
46 bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType);
47 bool useLocalCoords = !isPathRendering &&
48 random->nextBool() &&
49 currAttribIndex < GrDrawState::kMaxVertexAttribCnt;
50 72
51 int numStages = numColorStages + numCoverageStages; 73 virtual void emitCode(GrGLProgramBuilder* builder,
52 fKey.reset(); 74 const GrFragmentProcessor& fp,
53 75 const GrProcessorKey& key,
54 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t)); 76 const char* outputColor,
55 77 const char* inputColor,
56 // Make room for everything up to and including the array of offsets to effe ct keys. 78 const TransformedCoordsArray&,
57 fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * ( numStages + 79 const TextureSamplerArray&) {
58 (geometryProcessor ? 1 : 0))); 80 for (uint32_t i = 0; i < kMaxKeySize; i++) {
59 81 SkASSERT(key.get32(i) == i);
60 bool dstRead = false;
61 bool fragPos = false;
62 bool vertexShader = SkToBool(geometryProcessor);
63 int offset = 0;
64 if (geometryProcessor) {
65 const GrGeometryStage* stage = geometryProcessor;
66 uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() +
67 kEffectKeyOffsetsA ndLengthOffset +
68 offset * 2 * sizeo f(uint16_t));
69 uint32_t effectKeyOffset = fKey.count();
70 if (effectKeyOffset > SK_MaxU16) {
71 fKey.reset();
72 return false;
73 } 82 }
74 GrProcessorKeyBuilder b(&fKey);
75 uint16_t effectKeySize;
76 if (!GetProcessorKey(*stage, gpu->glCaps(), useLocalCoords, &b, &effectK eySize)) {
77 fKey.reset();
78 return false;
79 }
80 vertexShader = true;
81 fragPos = stage->getProcessor()->willReadFragmentPosition();
82 offsetAndSize[0] = effectKeyOffset;
83 offsetAndSize[1] = effectKeySize;
84 offset++;
85 } 83 }
86 84
87 for (int s = 0; s < numStages; ++s, ++offset) { 85 static void GenKey(const GrProcessor& processor, const GrGLCaps&, GrProcesso rKeyBuilder* b) {
88 const GrFragmentStage* stage = stages[s]; 86 for (uint32_t i = 0; i < kMaxKeySize; i++) {
89 uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() + 87 b->add32(i);
90 kEffectKeyOffsetsA ndLengthOffset +
91 offset * 2 * sizeo f(uint16_t));
92 uint32_t effectKeyOffset = fKey.count();
93 if (effectKeyOffset > SK_MaxU16) {
94 fKey.reset();
95 return false;
96 } 88 }
97 GrProcessorKeyBuilder b(&fKey);
98 uint16_t effectKeySize;
99 if (!GetProcessorKey(*stages[s], gpu->glCaps(), useLocalCoords, &b, &eff ectKeySize)) {
100 fKey.reset();
101 return false;
102 }
103 get_stage_stats(*stage, &dstRead, &fragPos, &vertexShader);
104 offsetAndSize[0] = effectKeyOffset;
105 offsetAndSize[1] = effectKeySize;
106 } 89 }
107 90
108 KeyHeader* header = this->header(); 91 private:
109 memset(header, 0, kHeaderSize); 92 typedef GrGLFragmentProcessor INHERITED;
110 header->fEmitsPointSize = random->nextBool(); 93 };
111 94
112 header->fPositionAttributeIndex = 0; 95 /*
96 * Begin test code
97 */
98 static const int kRenderTargetHeight = 1;
99 static const int kRenderTargetWidth = 1;
113 100
114 // if the effects have used up all off the available attributes, 101 static GrRenderTarget* random_render_target(GrGpuGL* gpu,
115 // don't try to use color or coverage attributes as input 102 const GrCacheID& cacheId,
116 do { 103 SkRandom* random) {
117 header->fColorInput = static_cast<GrGLProgramDesc::ColorInput>( 104 // setup render target
118 random->nextULessThan(kColorInputCnt)); 105 GrTextureParams params;
119 } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRende ring) && 106 GrTextureDesc texDesc;
120 kAttribute_ColorInput == header->fColorInput); 107 texDesc.fWidth = kRenderTargetWidth;
121 header->fColorAttributeIndex = (header->fColorInput == kAttribute_ColorInput ) ? 108 texDesc.fHeight = kRenderTargetHeight;
122 currAttribIndex++ : 109 texDesc.fFlags = kRenderTarget_GrTextureFlagBit;
123 -1; 110 texDesc.fConfig = kRGBA_8888_GrPixelConfig;
111 texDesc.fOrigin = random->nextBool() == true ? kTopLeft_GrSurfaceOrigin :
112 kBottomLeft_GrSurfaceOrigin;
124 113
125 do { 114 GrTexture* texture = gpu->getContext()->findAndRefTexture(texDesc, cacheId, &params);
126 header->fCoverageInput = static_cast<GrGLProgramDesc::ColorInput>( 115 if (NULL == texture) {
127 random->nextULessThan(kColorInputCnt)); 116 texture = gpu->getContext()->createTexture(&params, texDesc, cacheId, 0, 0);
128 } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRende ring) && 117 if (NULL == texture) {
129 kAttribute_ColorInput == header->fCoverageInput); 118 return NULL;
130 header->fCoverageAttributeIndex = (header->fCoverageInput == kAttribute_Colo rInput) ? 119 }
131 currAttribIndex++ :
132 -1;
133 bool useGS = random->nextBool();
134 #if GR_GL_EXPERIMENTAL_GS
135 header->fExperimentalGS = gpu->caps()->geometryShaderSupport() && useGS;
136 #else
137 (void) useGS;
138 #endif
139
140 header->fLocalCoordAttributeIndex = useLocalCoords ? currAttribIndex++ : -1;
141
142 header->fColorEffectCnt = numColorStages;
143 header->fCoverageEffectCnt = numCoverageStages;
144
145 if (dstRead) {
146 header->fDstReadKey = SkToU8(GrGLFragmentShaderBuilder::KeyForDstRead(ds tCopyTexture,
147 gpu->glCap s()));
148 } else {
149 header->fDstReadKey = 0;
150 } 120 }
151 if (fragPos) { 121 return texture->asRenderTarget();
152 header->fFragPosKey = SkToU8(GrGLFragmentShaderBuilder::KeyForFragmentPo sition(dstRenderTarget,
153 g pu->glCaps()));
154 } else {
155 header->fFragPosKey = 0;
156 }
157
158 header->fUseFragShaderOnly = isPathRendering && gpu->glPathRendering()->text uringMode() ==
159 GrGLPathRendering::FixedFunc tion_TexturingMode;
160 header->fHasGeometryProcessor = vertexShader;
161
162 GrOptDrawState::PrimaryOutputType primaryOutput;
163 GrOptDrawState::SecondaryOutputType secondaryOutput;
164 if (!dstRead) {
165 primaryOutput = GrOptDrawState::kModulate_PrimaryOutputType;
166 } else {
167 primaryOutput = static_cast<GrOptDrawState::PrimaryOutputType>(
168 random->nextULessThan(GrOptDrawState::kPrimaryOutputTypeCnt));
169 }
170
171 if (GrOptDrawState::kCombineWithDst_PrimaryOutputType == primaryOutput ||
172 !gpu->caps()->dualSourceBlendingSupport()) {
173 secondaryOutput = GrOptDrawState::kNone_SecondaryOutputType;
174 } else {
175 secondaryOutput = static_cast<GrOptDrawState::SecondaryOutputType>(
176 random->nextULessThan(GrOptDrawState::kSecondaryOutputTypeCnt));
177 }
178
179 header->fPrimaryOutputType = primaryOutput;
180 header->fSecondaryOutputType = secondaryOutput;
181
182 this->finalize();
183 return true;
184 } 122 }
185 123
186 // TODO clean this up, we have to do this to test geometry processors but there has got to be 124 // TODO clean this up, we have to do this to test geometry processors but there has got to be
187 // a better way. In the mean time, we actually fill out these generic vertex at tribs below with 125 // a better way. In the mean time, we actually fill out these generic vertex at tribs below with
188 // the correct vertex attribs from the GP. We have to ensure, however, we don't try to add more 126 // the correct vertex attribs from the GP. We have to ensure, however, we don't try to add more
189 // than two attributes. 127 // than two attributes. In addition, we 'pad' the below array with GPs up to 6 entries, 4 fixed
190 GrVertexAttrib genericVertexAttribs[] = { 128 // function vertex attributes and 2 GP custom attributes.
129 GrVertexAttrib kGenericVertexAttribs[] = {
191 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 130 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
192 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } , 131 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } ,
132 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } ,
133 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } ,
134 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } ,
193 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } 135 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding }
194 }; 136 };
195 137
196 /* 138 /*
197 * convert sl type to vertexattrib type, not a complete implementation, only use for debugging 139 * convert sl type to vertexattrib type, not a complete implementation, only use for debugging
198 */ 140 */
199 GrVertexAttribType convert_sltype_to_attribtype(GrSLType type) { 141 static GrVertexAttribType convert_sltype_to_attribtype(GrSLType type) {
200 switch (type) { 142 switch (type) {
201 case kFloat_GrSLType: 143 case kFloat_GrSLType:
202 return kFloat_GrVertexAttribType; 144 return kFloat_GrVertexAttribType;
203 case kVec2f_GrSLType: 145 case kVec2f_GrSLType:
204 return kVec2f_GrVertexAttribType; 146 return kVec2f_GrVertexAttribType;
205 case kVec3f_GrSLType: 147 case kVec3f_GrSLType:
206 return kVec3f_GrVertexAttribType; 148 return kVec3f_GrVertexAttribType;
207 case kVec4f_GrSLType: 149 case kVec4f_GrSLType:
208 return kVec4f_GrVertexAttribType; 150 return kVec4f_GrVertexAttribType;
209 default: 151 default:
210 SkFAIL("Type isn't convertible"); 152 SkFAIL("Type isn't convertible");
211 return kFloat_GrVertexAttribType; 153 return kFloat_GrVertexAttribType;
212 } 154 }
213 } 155 }
214 // TODO end test hack 156 // end test hack
215 157
158 static void setup_random_ff_attribute(GrVertexAttribBinding binding, GrVertexAtt ribType type,
159 SkRandom* random, int* attribIndex, int* r unningStride) {
160 if (random->nextBool()) {
161 kGenericVertexAttribs[*attribIndex].fType = type;
162 kGenericVertexAttribs[*attribIndex].fOffset = *runningStride;
163 kGenericVertexAttribs[*attribIndex].fBinding = binding;
164 *runningStride += GrVertexAttribTypeSize(kGenericVertexAttribs[(*attribI ndex)++].fType);
165 }
166 }
167
168 static void set_random_gp(GrGpuGL* gpu, SkRandom* random, GrTexture* dummyTextur es[]) {
169 GrProgramElementRef<const GrGeometryProcessor> gp(
170 GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(random,
171 gpu->getCon text(),
172 *gpu->caps( ),
173 dummyTextur es));
174 SkASSERT(gp);
175
176 // we have to set dummy vertex attributes, first we setup the fixed function attributes
177 // always leave the position attribute untouched in the array
178 int attribIndex = 1;
179 int runningStride = GrVertexAttribTypeSize(kGenericVertexAttribs[0].fType);
180
181 // local coords
182 setup_random_ff_attribute(kLocalCoord_GrVertexAttribBinding, kVec2f_GrVertex AttribType,
183 random, &attribIndex, &runningStride);
184
185 // color
186 setup_random_ff_attribute(kColor_GrVertexAttribBinding, kVec4f_GrVertexAttri bType,
187 random, &attribIndex, &runningStride);
188
189 // coverage
190 setup_random_ff_attribute(kCoverage_GrVertexAttribBinding, kVec4f_GrVertexAt tribType,
191 random, &attribIndex, &runningStride);
192
193 // Update the geometry processor attributes
194 const GrGeometryProcessor::VertexAttribArray& v = gp->getVertexAttribs();
195 int numGPAttribs = v.count();
196 SkASSERT(numGPAttribs <= GrGeometryProcessor::kMaxVertexAttribs &&
197 GrGeometryProcessor::kMaxVertexAttribs == 2);
198
199 // we actually can't overflow if kMaxVertexAttribs == 2, but GCC 4.8 wants m ore proof
200 int maxIndex = SK_ARRAY_COUNT(kGenericVertexAttribs);
201 for (int i = 0; i < numGPAttribs && i + attribIndex < maxIndex; i++) {
202 kGenericVertexAttribs[i + attribIndex].fType =
203 convert_sltype_to_attribtype(v[i].getType());
204 kGenericVertexAttribs[i + attribIndex].fOffset = runningStride;
205 kGenericVertexAttribs[i + attribIndex].fBinding = kGeometryProcessor_GrV ertexAttribBinding;
206 runningStride += GrVertexAttribTypeSize(kGenericVertexAttribs[i + attrib Index].fType);
207 }
208
209 // update the vertex attributes with the ds
210 GrDrawState* ds = gpu->drawState();
211 ds->setVertexAttribs<kGenericVertexAttribs>(attribIndex + numGPAttribs, runn ingStride);
212 ds->setGeometryProcessor(gp);
213 }
214
215 static void set_random_color_coverage_stages(GrGpuGL* gpu,
216 int maxStages,
217 bool usePathRendering,
218 SkRandom* random,
219 GrTexture* dummyTextures[]) {
220 int numProcs = random->nextULessThan(maxStages + 1);
221 int numColorProcs = random->nextULessThan(numProcs + 1);
222
223 int currTextureCoordSet = 0;
224 for (int s = 0; s < numProcs;) {
225 GrProgramElementRef<GrFragmentProcessor> fp(
226 GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(random,
227 gpu->ge tContext(),
228 *gpu->c aps(),
229 dummyTe xtures));
230 SkASSERT(fp);
231
232 // don't add dst color reads to coverage stage
233 if (s >= numColorProcs && fp->willReadDstColor()) {
234 continue;
235 }
236
237 // If adding this effect would exceed the max texture coord set count th en generate a
238 // new random effect.
239 if (usePathRendering && gpu->glPathRendering()->texturingMode() ==
240 GrGLPathRendering::FixedFunction_TexturingMode) {;
241 int numTransforms = fp->numTransforms();
242 if (currTextureCoordSet + numTransforms >
243 gpu->glCaps().maxFixedFunctionTextureCoords()) {
244 continue;
245 }
246 currTextureCoordSet += numTransforms;
247 }
248
249 // finally add the stage to the correct pipeline in the drawstate
250 GrDrawState* ds = gpu->drawState();
251 if (s < numColorProcs) {
252 ds->addColorProcessor(fp);
253 } else {
254 ds->addCoverageProcessor(fp);
255 }
256 ++s;
257 }
258 }
259
260 // There are only a few cases of random colors which interest us
261 enum ColorMode {
262 kAllOnes_ColorMode,
263 kAllZeros_ColorMode,
264 kAlphaOne_ColorMode,
265 kRandom_ColorMode,
266 kLast_ColorMode = kRandom_ColorMode
267 };
268
269 static void set_random_color(GrGpuGL* gpu, SkRandom* random) {
270 ColorMode colorMode = ColorMode(random->nextULessThan(kLast_ColorMode + 1));
271 GrColor color;
272 switch (colorMode) {
273 case kAllOnes_ColorMode:
274 color = GrColorPackRGBA(0xFF, 0xFF, 0xFF, 0xFF);
275 break;
276 case kAllZeros_ColorMode:
277 color = GrColorPackRGBA(0, 0, 0, 0);
278 break;
279 case kAlphaOne_ColorMode:
280 color = GrColorPackRGBA(random->nextULessThan(256),
281 random->nextULessThan(256),
282 random->nextULessThan(256),
283 0xFF);
284 break;
285 case kRandom_ColorMode:
286 uint8_t alpha = random->nextULessThan(256);
287 color = GrColorPackRGBA(random->nextRangeU(0, alpha),
288 random->nextRangeU(0, alpha),
289 random->nextRangeU(0, alpha),
290 alpha);
291 break;
292 }
293 GrColorIsPMAssert(color);
294 gpu->drawState()->setColor(color);
295 }
296
297 // There are only a few cases of random coverages which interest us
298 enum CoverageMode {
299 kZero_CoverageMode,
300 kFF_CoverageMode,
301 kRandom_CoverageMode,
302 kLast_CoverageMode = kRandom_CoverageMode
303 };
304
305 static void set_random_coverage(GrGpuGL* gpu, SkRandom* random) {
306 CoverageMode coverageMode = CoverageMode(random->nextULessThan(kLast_Coverag eMode + 1));
307 uint8_t coverage;
308 switch (coverageMode) {
309 case kZero_CoverageMode:
310 coverage = 0;
311 break;
312 case kFF_CoverageMode:
313 coverage = 0xFF;
314 break;
315 case kRandom_CoverageMode:
316 coverage = uint8_t(random->nextU());
317 break;
318 }
319 gpu->drawState()->setCoverage(coverage);
320 }
321
322 static void set_random_hints(GrGpuGL* gpu, SkRandom* random) {
323 for (int i = 1; i <= GrDrawState::kLast_Hint; i <<= 1) {
324 gpu->drawState()->setHint(GrDrawState::Hints(i), random->nextBool());
325 }
326 }
327
328 static void set_random_state(GrGpuGL* gpu, SkRandom* random) {
329 int state = 0;
330 for (int i = 1; i <= GrDrawState::kLastPublicStateBit; i <<= 1) {
331 state |= random->nextBool() * i;
332 }
333 gpu->drawState()->enableState(state);
334 }
335
336 // this function will randomly pick non-self referencing blend modes
337 static void set_random_blend_func(GrGpuGL* gpu, SkRandom* random) {
338 GrBlendCoeff src;
339 do {
340 src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
341 } while (GrBlendCoeffRefsSrc(src));
342
343 GrBlendCoeff dst;
344 do {
345 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
346 } while (GrBlendCoeffRefsDst(dst));
347
348 gpu->drawState()->setBlendFunc(src, dst);
349 }
350
351 // right now, the only thing we seem to care about in drawState's stencil is 'do esWrite()'
352 static void set_random_stencil(GrGpuGL* gpu, SkRandom* random) {
353 GR_STATIC_CONST_SAME_STENCIL(kDoesWriteStencil,
354 kReplace_StencilOp,
355 kReplace_StencilOp,
356 kAlways_StencilFunc,
357 0xffff,
358 0xffff,
359 0xffff);
360 GR_STATIC_CONST_SAME_STENCIL(kDoesNotWriteStencil,
361 kKeep_StencilOp,
362 kKeep_StencilOp,
363 kNever_StencilFunc,
364 0xffff,
365 0xffff,
366 0xffff);
367
368 if (random->nextBool()) {
369 gpu->drawState()->setStencil(kDoesWriteStencil);
370 } else {
371 gpu->drawState()->setStencil(kDoesNotWriteStencil);
372 }
373 }
216 374
217 bool GrGpuGL::programUnitTest(int maxStages) { 375 bool GrGpuGL::programUnitTest(int maxStages) {
218 376 // setup dummy textures
219 GrTextureDesc dummyDesc; 377 GrTextureDesc dummyDesc;
220 dummyDesc.fFlags = kRenderTarget_GrTextureFlagBit; 378 dummyDesc.fFlags = kRenderTarget_GrTextureFlagBit;
221 dummyDesc.fConfig = kSkia8888_GrPixelConfig; 379 dummyDesc.fConfig = kSkia8888_GrPixelConfig;
222 dummyDesc.fWidth = 34; 380 dummyDesc.fWidth = 34;
223 dummyDesc.fHeight = 18; 381 dummyDesc.fHeight = 18;
224 SkAutoTUnref<GrTexture> dummyTexture1(this->createTexture(dummyDesc, NULL, 0 )); 382 SkAutoTUnref<GrTexture> dummyTexture1(this->createTexture(dummyDesc, NULL, 0 ));
225 dummyDesc.fFlags = kNone_GrTextureFlags; 383 dummyDesc.fFlags = kNone_GrTextureFlags;
226 dummyDesc.fConfig = kAlpha_8_GrPixelConfig; 384 dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
227 dummyDesc.fWidth = 16; 385 dummyDesc.fWidth = 16;
228 dummyDesc.fHeight = 22; 386 dummyDesc.fHeight = 22;
229 SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0 )); 387 SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0 ));
230 388
231 if (!dummyTexture1 || ! dummyTexture2) { 389 if (!dummyTexture1 || ! dummyTexture2) {
390 SkDebugf("Could not allocate dummy textures");
232 return false; 391 return false;
233 } 392 }
234 393
235 static const int NUM_TESTS = 512; 394 GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
395
396 // Setup texture cache id key
397 const GrCacheID::Domain glProgramsDomain = GrCacheID::GenerateDomain();
398 GrCacheID::Key key;
399 memset(&key, 0, sizeof(key));
400 key.fData32[0] = kRenderTargetWidth;
401 key.fData32[1] = kRenderTargetHeight;
402 GrCacheID glProgramsCacheID(glProgramsDomain, key);
403
404 // setup clip
405 SkRect screen =
406 SkRect::MakeWH(SkIntToScalar(kRenderTargetWidth), SkIntToScalar(kRen derTargetHeight));
407
408 SkClipStack stack;
409 stack.clipDevRect(screen, SkRegion::kReplace_Op, false);
410
411 // wrap the SkClipStack in a GrClipData
412 GrClipData clipData;
413 clipData.fClipStack = &stack;
414 this->setClip(&clipData);
236 415
237 SkRandom random; 416 SkRandom random;
238 for (int t = 0; t < NUM_TESTS; ++t) { 417 static const int NUM_TESTS = 512;
418 for (int t = 0; t < NUM_TESTS;) {
419 // setup random render target(can fail)
420 GrRenderTarget* rtPtr = random_render_target(this, glProgramsCacheID, &r andom);
421 if (!rtPtr) {
422 SkDebugf("Could not allocate render target");
423 return false;
424 }
425 GrTGpuResourceRef<GrRenderTarget> rt(SkRef(rtPtr), kWrite_GrIOType);
239 426
240 #if 0 427 GrDrawState* ds = this->drawState();
241 GrPrintf("\nTest Program %d\n-------------\n", t); 428 ds->setRenderTarget(rt.get());
242 static const int stop = -1;
243 if (t == stop) {
244 int breakpointhere = 9;
245 }
246 #endif
247 429
248 GrGLProgramDesc pdesc; 430 // if path rendering we have to setup a couple of things like the draw t ype
249
250 int currAttribIndex = 1; // we need to always leave room for position
251 int currTextureCoordSet = 0;
252 GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
253
254 int numStages = random.nextULessThan(maxStages + 1);
255 int numColorStages = random.nextULessThan(numStages + 1);
256 int numCoverageStages = numStages - numColorStages;
257
258 SkAutoSTMalloc<8, const GrFragmentStage*> stages(numStages);
259
260 bool usePathRendering = this->glCaps().pathRenderingSupport() && random. nextBool(); 431 bool usePathRendering = this->glCaps().pathRenderingSupport() && random. nextBool();
261 432
262 GrGpu::DrawType drawType = usePathRendering ? GrGpu::kDrawPath_DrawType : 433 GrGpu::DrawType drawType = usePathRendering ? GrGpu::kDrawPath_DrawType :
263 GrGpu::kDrawPoints_DrawTyp e; 434 GrGpu::kDrawPoints_DrawTyp e;
264 435
265 SkAutoTDelete<GrGeometryStage> geometryProcessor; 436 // twiddle drawstate knobs randomly
266 bool hasGeometryProcessor = usePathRendering ? false : random.nextBool() ; 437 bool hasGeometryProcessor = usePathRendering ? false : random.nextBool() ;
267 if (hasGeometryProcessor) { 438 if (hasGeometryProcessor) {
268 while (true) { 439 set_random_gp(this, &random, dummyTextures);
269 SkAutoTUnref<const GrGeometryProcessor> effect( 440 }
270 GrProcessorTestFactory<GrGeometryProcessor>::CreateStage (&random, this->getContext(), *this->caps(), 441 set_random_color_coverage_stages(this, maxStages - hasGeometryProcessor, usePathRendering,
271 dummyTextures)); 442 &random, dummyTextures);
272 SkASSERT(effect); 443 set_random_color(this, &random);
273 // Only geometryProcessor can use vertex shader 444 set_random_coverage(this, &random);
274 GrGeometryStage* stage = SkNEW_ARGS(GrGeometryStage, (effect.get ())); 445 set_random_hints(this, &random);
275 geometryProcessor.reset(stage); 446 set_random_state(this, &random);
447 set_random_blend_func(this, &random);
448 set_random_stencil(this, &random);
276 449
277 // we have to set dummy vertex attribs 450 // create optimized draw state, setup readDst texture if required, and b uild a descriptor
278 const GrGeometryProcessor::VertexAttribArray& v = effect->getVer texAttribs(); 451 // and program. ODS creation can fail, so we have to check
279 int numVertexAttribs = v.count(); 452 SkAutoTUnref<GrOptDrawState> ods(GrOptDrawState::Create(this->getDrawSta te(),
453 *this->caps(),
454 drawType));
455 if (!ods.get()) {
456 ds->reset();
457 continue;
458 }
459 const GrGeometryStage* geometryProcessor = NULL;
460 SkSTArray<8, const GrFragmentStage*, true> colorStages;
461 SkSTArray<8, const GrFragmentStage*, true> coverageStages;
462 GrGLProgramDesc desc;
463 GrDeviceCoordTexture dstCopy;
280 464
281 SkASSERT(GrGeometryProcessor::kMaxVertexAttribs == 2 && 465 if (!this->setupDstReadIfNecessary(&dstCopy, NULL)) {
282 GrGeometryProcessor::kMaxVertexAttribs >= numVertexAttr ibs); 466 SkDebugf("Couldn't setup dst read texture");
283 size_t runningStride = GrVertexAttribTypeSize(genericVertexAttri bs[0].fType);
284 for (int i = 0; i < numVertexAttribs; i++) {
285 genericVertexAttribs[i + 1].fOffset = runningStride;
286 genericVertexAttribs[i + 1].fType =
287 convert_sltype_to_attribtype(v[i].getType());
288 runningStride += GrVertexAttribTypeSize(genericVertexAttribs [i + 1].fType);
289 }
290
291 // update the vertex attributes with the ds
292 GrDrawState* ds = this->drawState();
293 ds->setVertexAttribs<genericVertexAttribs>(numVertexAttribs + 1, runningStride);
294 currAttribIndex = numVertexAttribs + 1;
295 break;
296 }
297 }
298 for (int s = 0; s < numStages;) {
299 SkAutoTUnref<const GrFragmentProcessor> effect(
300 GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(
301 &ran dom,
302 this ->getContext(),
303 *thi s->caps(),
304 dumm yTextures));
305 SkASSERT(effect);
306
307 // If adding this effect would exceed the max texture coord set coun t then generate a
308 // new random effect.
309 if (usePathRendering && this->glPathRendering()->texturingMode() ==
310 GrGLPathRendering::FixedFunction_TexturingMo de) {;
311 int numTransforms = effect->numTransforms();
312 if (currTextureCoordSet + numTransforms > this->glCaps().maxFixe dFunctionTextureCoords()) {
313 continue;
314 }
315 currTextureCoordSet += numTransforms;
316 }
317 GrFragmentStage* stage = SkNEW_ARGS(GrFragmentStage, (effect.get())) ;
318
319 stages[s] = stage;
320 ++s;
321 }
322 const GrTexture* dstTexture = random.nextBool() ? dummyTextures[0] : dum myTextures[1];
323 if (!pdesc.setRandom(&random,
324 this,
325 dummyTextures[0]->asRenderTarget(),
326 dstTexture,
327 geometryProcessor.get(),
328 stages.get(),
329 numColorStages,
330 numCoverageStages,
331 currAttribIndex,
332 drawType)) {
333 return false; 467 return false;
334 } 468 }
335 469 if (!GrGLProgramDesc::Build(*ods,
336 SkAutoTUnref<GrOptDrawState> optState(GrOptDrawState::Create(this->getDr awState(), 470 drawType,
337 *this->caps (), 471 ods->getSrcBlendCoeff(),
338 drawType)); 472 ods->getDstBlendCoeff(),
339 SkAutoTUnref<GrGLProgram> program( 473 this,
340 GrGLProgramBuilder::CreateProgram(*optState, 474 dstCopy.texture() ? &dstCopy : NULL,
341 pdesc, 475 &geometryProcessor,
342 drawType, 476 &colorStages,
343 geometryProcessor, 477 &coverageStages,
344 stages, 478 &desc)) {
345 stages + numColorStage s, 479 SkDebugf("Failed to generate GL program descriptor");
346 this)); 480 return false;
347 for (int s = 0; s < numStages; ++s) {
348 SkDELETE(stages[s]);
349 } 481 }
482 SkAutoTUnref<GrGLProgram> program(GrGLProgramBuilder::CreateProgram(*ods ,
483 desc ,
484 draw Type,
485 geom etryProcessor,
486 colo rStages.begin(),
487 cove rageStages.begin(),
488 this ));
350 if (NULL == program.get()) { 489 if (NULL == program.get()) {
490 SkDebugf("Failed to create program!");
351 return false; 491 return false;
352 } 492 }
353 493
354 // We have to reset the drawstate because we might have added a gp 494 // We have to reset the drawstate because we might have added a gp
355 this->drawState()->reset(); 495 ds->reset();
496
497 // because occasionally optimized drawstate creation will fail for valid reasons, we only
498 // want to increment on success
499 ++t;
356 } 500 }
357 return true; 501 return true;
358 } 502 }
359 503
360 DEF_GPUTEST(GLPrograms, reporter, factory) { 504 DEF_GPUTEST(GLPrograms, reporter, factory) {
361 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { 505 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
362 GrContext* context = factory->get(static_cast<GrContextFactory::GLContex tType>(type)); 506 GrContext* context = factory->get(static_cast<GrContextFactory::GLContex tType>(type));
363 if (context) { 507 if (context) {
364 GrGpuGL* gpu = static_cast<GrGpuGL*>(context->getGpu()); 508 GrGpuGL* gpu = static_cast<GrGpuGL*>(context->getGpu());
365 int maxStages = 6; 509 int maxStages = 6;
(...skipping 27 matching lines...) Expand all
393 SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1)); 537 SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1));
394 GrConfigConversionEffect::Create(NULL, 538 GrConfigConversionEffect::Create(NULL,
395 false, 539 false,
396 GrConfigConversionEffect::kNone_PMConversio n, 540 GrConfigConversionEffect::kNone_PMConversio n,
397 SkMatrix::I()); 541 SkMatrix::I());
398 SkScalar matrix[20]; 542 SkScalar matrix[20];
399 SkAutoTUnref<SkColorMatrixFilter> cmf(SkColorMatrixFilter::Create(matrix)); 543 SkAutoTUnref<SkColorMatrixFilter> cmf(SkColorMatrixFilter::Create(matrix));
400 } 544 }
401 545
402 #endif 546 #endif
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGpuGL_program.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698