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

Side by Side Diff: tests/GLProgramsTest.cpp

Issue 628633003: gl programs rewrite (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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
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 "GrBackendProcessorFactory.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/GrGLPathRendering.h" 19 #include "gl/GrGLPathRendering.h"
20 #include "gl/GrGpuGL.h" 20 #include "gl/GrGpuGL.h"
21 #include "SkChecksum.h" 21 #include "SkChecksum.h"
22 #include "SkRandom.h" 22 #include "SkRandom.h"
23 #include "Test.h" 23 #include "Test.h"
24 24
25 static void get_stage_stats(const GrFragmentStage stage, bool* readsDst, 25 static const int kRenderTargetHeight = 1;
26 bool* readsFragPosition, bool* requiresVertexShader) { 26 static const int kRenderTargetWidth = 1;
27 if (stage.getFragmentProcessor()->willReadDstColor()) { 27
28 *readsDst = true; 28 static GrRenderTarget* random_render_target(GrGpuGL* gpu,
29 const GrCacheID& cacheId,
egdaniel 2014/10/06 14:19:02 move param up and onto same line
30 SkRandom* random) {
31 // setup render target
32 GrTextureParams params;
33 GrTextureDesc texDesc;
34 texDesc.fWidth = kRenderTargetWidth;
35 texDesc.fHeight = kRenderTargetHeight;
36 texDesc.fFlags = kRenderTarget_GrTextureFlagBit;
37 texDesc.fConfig = kRGBA_8888_GrPixelConfig;
38 texDesc.fOrigin = random->nextBool() == true ? kTopLeft_GrSurfaceOrigin :
39 kBottomLeft_GrSurfaceOrigin;
40
41 GrTexture* texture = gpu->getContext()->findAndRefTexture(texDesc, cacheId, &params);
42 if (NULL == texture) {
43 texture = gpu->getContext()->createTexture(&params, texDesc, cacheId, 0, 0);
44 if (NULL == texture) {
45 SkDEBUGFAIL("Could not allocate render target");
bsalomon 2014/10/06 14:29:04 Maybe just SkDebugf? Hopefully this ripples up and
46 return NULL;
47 }
29 } 48 }
30 if (stage.getProcessor()->willReadFragmentPosition()) { 49 return texture->asRenderTarget();
31 *readsFragPosition = true;
32 }
33 }
34
35 bool GrGLProgramDesc::setRandom(SkRandom* random,
36 GrGpuGL* gpu,
37 const GrRenderTarget* dstRenderTarget,
38 const GrTexture* dstCopyTexture,
39 const GrGeometryStage* geometryProcessor,
40 const GrFragmentStage* stages[],
41 int numColorStages,
42 int numCoverageStages,
43 int currAttribIndex,
44 GrGpu::DrawType drawType) {
45 bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType);
46 bool useLocalCoords = !isPathRendering &&
47 random->nextBool() &&
48 currAttribIndex < GrDrawState::kMaxVertexAttribCnt;
49
50 int numStages = numColorStages + numCoverageStages;
51 fKey.reset();
52
53 GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t));
54
55 // Make room for everything up to and including the array of offsets to effe ct keys.
56 fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * ( numStages +
57 (geometryProcessor ? 1 : 0)));
58
59 bool dstRead = false;
60 bool fragPos = false;
61 bool vertexShader = SkToBool(geometryProcessor);
62 int offset = 0;
63 if (geometryProcessor) {
64 const GrGeometryStage* stage = geometryProcessor;
65 uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() +
66 kEffectKeyOffsetsA ndLengthOffset +
67 offset * 2 * sizeo f(uint16_t));
68 uint32_t effectKeyOffset = fKey.count();
69 if (effectKeyOffset > SK_MaxU16) {
70 fKey.reset();
71 return false;
72 }
73 GrProcessorKeyBuilder b(&fKey);
74 uint16_t effectKeySize;
75 if (!GetProcessorKey(*stage, gpu->glCaps(), useLocalCoords, &b, &effectK eySize)) {
76 fKey.reset();
77 return false;
78 }
79 vertexShader = true;
80 fragPos = stage->getProcessor()->willReadFragmentPosition();
81 offsetAndSize[0] = effectKeyOffset;
82 offsetAndSize[1] = effectKeySize;
83 offset++;
84 }
85
86 for (int s = 0; s < numStages; ++s, ++offset) {
87 const GrFragmentStage* stage = stages[s];
88 uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() +
89 kEffectKeyOffsetsA ndLengthOffset +
90 offset * 2 * sizeo f(uint16_t));
91 uint32_t effectKeyOffset = fKey.count();
92 if (effectKeyOffset > SK_MaxU16) {
93 fKey.reset();
94 return false;
95 }
96 GrProcessorKeyBuilder b(&fKey);
97 uint16_t effectKeySize;
98 if (!GetProcessorKey(*stages[s], gpu->glCaps(), useLocalCoords, &b, &eff ectKeySize)) {
99 fKey.reset();
100 return false;
101 }
102 get_stage_stats(*stage, &dstRead, &fragPos, &vertexShader);
103 offsetAndSize[0] = effectKeyOffset;
104 offsetAndSize[1] = effectKeySize;
105 }
106
107 KeyHeader* header = this->header();
108 memset(header, 0, kHeaderSize);
109 header->fEmitsPointSize = random->nextBool();
110
111 header->fPositionAttributeIndex = 0;
112
113 // if the effects have used up all off the available attributes,
114 // don't try to use color or coverage attributes as input
115 do {
116 header->fColorInput = static_cast<GrGLProgramDesc::ColorInput>(
117 random->nextULessThan(kColorInputCnt));
118 } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRende ring) &&
119 kAttribute_ColorInput == header->fColorInput);
120 header->fColorAttributeIndex = (header->fColorInput == kAttribute_ColorInput ) ?
121 currAttribIndex++ :
122 -1;
123
124 do {
125 header->fCoverageInput = static_cast<GrGLProgramDesc::ColorInput>(
126 random->nextULessThan(kColorInputCnt));
127 } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRende ring) &&
128 kAttribute_ColorInput == header->fCoverageInput);
129 header->fCoverageAttributeIndex = (header->fCoverageInput == kAttribute_Colo rInput) ?
130 currAttribIndex++ :
131 -1;
132 bool useGS = random->nextBool();
133 #if GR_GL_EXPERIMENTAL_GS
134 header->fExperimentalGS = gpu->caps()->geometryShaderSupport() && useGS;
135 #else
136 (void) useGS;
137 #endif
138
139 header->fLocalCoordAttributeIndex = useLocalCoords ? currAttribIndex++ : -1;
140
141 header->fColorEffectCnt = numColorStages;
142 header->fCoverageEffectCnt = numCoverageStages;
143
144 if (dstRead) {
145 header->fDstReadKey = SkToU8(GrGLFragmentShaderBuilder::KeyForDstRead(ds tCopyTexture,
146 gpu->glCap s()));
147 } else {
148 header->fDstReadKey = 0;
149 }
150 if (fragPos) {
151 header->fFragPosKey = SkToU8(GrGLFragmentShaderBuilder::KeyForFragmentPo sition(dstRenderTarget,
152 g pu->glCaps()));
153 } else {
154 header->fFragPosKey = 0;
155 }
156
157 header->fUseFragShaderOnly = isPathRendering && gpu->glPathRendering()->text uringMode() ==
158 GrGLPathRendering::FixedFunc tion_TexturingMode;
159 header->fHasGeometryProcessor = vertexShader;
160
161 GrOptDrawState::PrimaryOutputType primaryOutput;
162 GrOptDrawState::SecondaryOutputType secondaryOutput;
163 if (!dstRead) {
164 primaryOutput = GrOptDrawState::kModulate_PrimaryOutputType;
165 } else {
166 primaryOutput = static_cast<GrOptDrawState::PrimaryOutputType>(
167 random->nextULessThan(GrOptDrawState::kPrimaryOutputTypeCnt));
168 }
169
170 if (GrOptDrawState::kCombineWithDst_PrimaryOutputType == primaryOutput ||
171 !gpu->caps()->dualSourceBlendingSupport()) {
172 secondaryOutput = GrOptDrawState::kNone_SecondaryOutputType;
173 } else {
174 secondaryOutput = static_cast<GrOptDrawState::SecondaryOutputType>(
175 random->nextULessThan(GrOptDrawState::kSecondaryOutputTypeCnt));
176 }
177
178 header->fPrimaryOutputType = primaryOutput;
179 header->fSecondaryOutputType = secondaryOutput;
180
181 this->finalize();
182 return true;
183 } 50 }
184 51
185 // TODO clean this up, we have to do this to test geometry processors but there has got to be 52 // TODO clean this up, we have to do this to test geometry processors but there has got to be
186 // a better way. In the mean time, we actually fill out these generic vertex at tribs below with 53 // a better way. In the mean time, we actually fill out these generic vertex at tribs below with
187 // the correct vertex attribs from the GP. We have to ensure, however, we don't try to add more 54 // the correct vertex attribs from the GP. We have to ensure, however, we don't try to add more
188 // than two attributes. 55 // than two attributes. In addition, we 'pad' the below array with GPs up to 6 entries.
egdaniel 2014/10/06 14:19:02 add into comment that the 6 comes from 4 ff va's a
189 GrVertexAttrib genericVertexAttribs[] = { 56 GrVertexAttrib genericVertexAttribs[] = {
egdaniel 2014/10/06 14:19:02 kGenericVertexAttribs
190 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, 57 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding },
191 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } , 58 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } ,
59 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } ,
60 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } ,
61 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } ,
192 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding } 62 { kVec2f_GrVertexAttribType, 0, kGeometryProcessor_GrVertexAttribBinding }
193 }; 63 };
194 64
195 /* 65 /*
196 * convert sl type to vertexattrib type, not a complete implementation, only use for debugging 66 * convert sl type to vertexattrib type, not a complete implementation, only use for debugging
197 */ 67 */
198 GrVertexAttribType convert_sltype_to_attribtype(GrSLType type) { 68 static GrVertexAttribType convert_sltype_to_attribtype(GrSLType type) {
199 switch (type) { 69 switch (type) {
200 case kFloat_GrSLType: 70 case kFloat_GrSLType:
201 return kFloat_GrVertexAttribType; 71 return kFloat_GrVertexAttribType;
202 case kVec2f_GrSLType: 72 case kVec2f_GrSLType:
203 return kVec2f_GrVertexAttribType; 73 return kVec2f_GrVertexAttribType;
204 case kVec3f_GrSLType: 74 case kVec3f_GrSLType:
205 return kVec3f_GrVertexAttribType; 75 return kVec3f_GrVertexAttribType;
206 case kVec4f_GrSLType: 76 case kVec4f_GrSLType:
207 return kVec4f_GrVertexAttribType; 77 return kVec4f_GrVertexAttribType;
208 default: 78 default:
209 SkFAIL("Type isn't convertible"); 79 SkFAIL("Type isn't convertible");
210 return kFloat_GrVertexAttribType; 80 return kFloat_GrVertexAttribType;
211 } 81 }
212 } 82 }
213 // TODO end test hack 83 // TODO end test hack
egdaniel 2014/10/06 14:19:02 What is this TODO for?
214 84
85 static void setup_random_ff_attribute(GrVertexAttribBinding binding, GrVertexAtt ribType type,
86 SkRandom* random, int* attribIndex, int* r unningStride) {
87 if (random->nextBool()) {
88 genericVertexAttribs[*attribIndex].fType = type;
89 genericVertexAttribs[*attribIndex].fOffset = *runningStride;
90 genericVertexAttribs[*attribIndex].fBinding = binding;
91 *runningStride += GrVertexAttribTypeSize(genericVertexAttribs[(*attribIn dex)++].fType);
92 }
93 }
94
95 static void set_random_gp(GrGpuGL* gpu, SkRandom* random, GrTexture* dummyTextur es[]) {
96 GrProgramElementRef<const GrGeometryProcessor> gp(
97 GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(random,
98 gpu->getCon text(),
99 *gpu->caps( ),
100 dummyTextur es));
101 SkASSERT(gp);
102
103 // we have to set dummy vertex attributes, first we setup the fixed function attributes
104 // always leave the position attribute untouched in the array
105 int attribIndex = 1;
106 int runningStride = GrVertexAttribTypeSize(genericVertexAttribs[0].fType);
107
108 // local coords
109 setup_random_ff_attribute(kLocalCoord_GrVertexAttribBinding, kVec2f_GrVertex AttribType,
110 random, &attribIndex, &runningStride);
111
112 // color
113 setup_random_ff_attribute(kColor_GrVertexAttribBinding, kVec4f_GrVertexAttri bType,
114 random, &attribIndex, &runningStride);
115
116 // coverage
117 setup_random_ff_attribute(kCoverage_GrVertexAttribBinding, kVec4f_GrVertexAt tribType,
118 random, &attribIndex, &runningStride);
119
120 // Update the geometry processor attributes
121 const GrGeometryProcessor::VertexAttribArray& v = gp->getVertexAttribs();
122 int numGPAttribs = v.count();
123 SkASSERT(numGPAttribs <= GrGeometryProcessor::kMaxVertexAttribs &&
124 GrGeometryProcessor::kMaxVertexAttribs == 2);
125 for (int i = 0; i < numGPAttribs; i++) {
126 genericVertexAttribs[i + attribIndex].fType =
127 convert_sltype_to_attribtype(v[i].getType());
128 genericVertexAttribs[i + attribIndex].fOffset = runningStride;
129 genericVertexAttribs[i + attribIndex].fBinding = kGeometryProcessor_GrVe rtexAttribBinding;
130 runningStride += GrVertexAttribTypeSize(genericVertexAttribs[i + attribI ndex].fType);
131 }
132
133 // update the vertex attributes with the ds
134 GrDrawState* ds = gpu->drawState();
135 ds->setVertexAttribs<genericVertexAttribs>(attribIndex + numGPAttribs, runni ngStride);
136 ds->setGeometryProcessor(gp);
137 }
138
139 void set_random_color_coverage_stages(GrGpuGL* gpu,
egdaniel 2014/10/06 14:19:02 put some of these params on same line
bsalomon 2014/10/06 14:29:04 static?
bsalomon 2014/10/06 14:29:04 we definitely have mixed styles. In a lot of place
140 int maxStages,
141 bool usePathRendering,
142 SkRandom* random,
143 GrTexture* dummyTextures[]) {
144 int numProcs = random->nextULessThan(maxStages + 1);
145 int numColorProcs = random->nextULessThan(numProcs + 1);
146
147 int currTextureCoordSet = 0;
148 for (int s = 0; s < numProcs;) {
149 GrProgramElementRef<GrFragmentProcessor> fp(
150 GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(random,
151 gpu->ge tContext(),
152 *gpu->c aps(),
153 dummyTe xtures));
154 SkASSERT(fp);
155
156 // don't add dst color reads to coverage stage
157 if (s >= numColorProcs && fp->willReadDstColor()) {
158 continue;
159 }
160
161 // If adding this effect would exceed the max texture coord set count th en generate a
162 // new random effect.
163 if (usePathRendering && gpu->glPathRendering()->texturingMode() ==
164 GrGLPathRendering::FixedFunction_TexturingMode) {;
165 int numTransforms = fp->numTransforms();
166 if (currTextureCoordSet + numTransforms >
167 gpu->glCaps().maxFixedFunctionTextureCoords()) {
168 continue;
169 }
170 currTextureCoordSet += numTransforms;
171 }
172
173 // finally add the stage to the correct pipeline in the drawstate
174 GrDrawState* ds = gpu->drawState();
175 if (s < numColorProcs) {
176 ds->addColorProcessor(fp);
177 } else {
178 ds->addCoverageProcessor(fp);
179 }
180 ++s;
181 }
182 }
183
184 // There are only a few cases of random colors which interest us
185 enum ColorMode {
186 kAllOnes_ColorMode,
187 kAllZeros_ColorMode,
188 kAlphaOne_ColorMode,
189 kRandom_ColorMode,
190 kLast_ColorMode = kRandom_ColorMode
191 };
192
193 static void set_random_color(GrGpuGL* gpu, SkRandom* random) {
194 ColorMode colorMode = ColorMode(random->nextULessThan(kLast_ColorMode + 1));
195 GrColor color;
196 switch (colorMode) {
197 case kAllOnes_ColorMode:
198 color = GrColorPackRGBA(0xFF, 0xFF, 0xFF, 0xFF);
199 break;
200 case kAllZeros_ColorMode:
201 color = GrColorPackRGBA(0, 0, 0, 0);
202 break;
203 case kAlphaOne_ColorMode:
204 color = GrColorPackRGBA(random->nextULessThan(256),
205 random->nextULessThan(256),
206 random->nextULessThan(256),
207 0xFF);
208 break;
209 case kRandom_ColorMode:
210 uint8_t alpha = random->nextULessThan(256);
211 color = GrColorPackRGBA(random->nextRangeU(0, alpha),
212 random->nextRangeU(0, alpha),
213 random->nextRangeU(0, alpha),
214 alpha);
215 break;
216 }
217 GrColorIsPMAssert(color);
218 gpu->drawState()->setColor(color);
219 }
220
221 // There are only a few cases of random coverages which interest us
222 enum CoverageMode {
223 kZero_CoverageMode,
224 kFF_CoverageMode,
225 kRandom_CoverageMode,
226 kLast_CoverageMode = kRandom_CoverageMode
227 };
228
229 static void set_random_coverage(GrGpuGL* gpu, SkRandom* random) {
230 CoverageMode coverageMode = CoverageMode(random->nextULessThan(kLast_Coverag eMode + 1));
231 uint8_t coverage;
232 switch (coverageMode) {
233 case kZero_CoverageMode:
234 coverage = 0;
235 break;
236 case kFF_CoverageMode:
237 coverage = 0xFF;
238 break;
239 case kRandom_CoverageMode:
240 coverage = uint8_t(random->nextU());
241 break;
242 }
243 gpu->drawState()->setCoverage(coverage);
244 }
245
246 // there is only one hint right now, but we have to make sure more hints aren't added without
247 // testing them
248 static void set_random_hints(GrGpuGL* gpu, SkRandom* random) {
249 GR_STATIC_ASSERT(GrDrawState::kLast_Hint == GrDrawState::kVertexColorsAreOpa que_Hint);
250
251 gpu->drawState()->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, random-> nextBool());
bsalomon 2014/10/06 14:29:04 Maybe just go ahead with if (int i = 1, i <= kLa
252 }
253
254 #define SET_RANDOM_BIT(flag) \
255 (random->nextBool() << pow++) & (flag)
256
257 // similar to the above, we have to prevent random state bits from being added w ithout testing
258 static void set_random_state(GrGpuGL* gpu, SkRandom* random) {
259 GR_STATIC_ASSERT(GrDrawState::kLastPublicStateBit == GrDrawState::kCoverageD rawing_StateBit);
bsalomon 2014/10/06 14:29:04 loop?
260
261 uint32_t state = 0;
262 uint32_t pow = 0;
263 state |= SET_RANDOM_BIT(GrDrawState::kDither_StateBit);
264 state |= SET_RANDOM_BIT(GrDrawState::kHWAntialias_StateBit);
265 state |= SET_RANDOM_BIT(GrDrawState::kClip_StateBit);
266 state |= SET_RANDOM_BIT(GrDrawState::kNoColorWrites_StateBit);
267 state |= SET_RANDOM_BIT(GrDrawState::kCoverageDrawing_StateBit);
268 gpu->drawState()->enableState(state);
269 }
270
271 // this function will randomly pick non-self referencing blend modes
272 static void set_random_blend_func(GrGpuGL* gpu, SkRandom* random) {
273 GrBlendCoeff src;
274 do {
275 src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
276 } while (GrBlendCoeffRefsSrc(src));
277
278 GrBlendCoeff dst;
279 do {
280 dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub licGrBlendCoeff));
281 } while (GrBlendCoeffRefsDst(dst));
282
283 gpu->drawState()->setBlendFunc(src, dst);
284 }
285
286 // right now, the only thing we seem to care about in drawState's stencil is 'do esWrite()'
287 static void set_random_stencil(GrGpuGL* gpu, SkRandom* random) {
288 GR_STATIC_CONST_SAME_STENCIL(kDoesWriteStencil,
289 kReplace_StencilOp,
290 kReplace_StencilOp,
291 kAlways_StencilFunc,
292 0xffff,
293 0xffff,
294 0xffff);
295 GR_STATIC_CONST_SAME_STENCIL(kDoesNotWriteStencil,
296 kKeep_StencilOp,
297 kKeep_StencilOp,
298 kNever_StencilFunc,
299 0xffff,
300 0xffff,
301 0xffff);
302
303 if (random->nextBool()) {
304 gpu->drawState()->setStencil(kDoesWriteStencil);
305 } else {
306 gpu->drawState()->setStencil(kDoesNotWriteStencil);
307 }
308 }
215 309
216 bool GrGpuGL::programUnitTest(int maxStages) { 310 bool GrGpuGL::programUnitTest(int maxStages) {
217 311 // setup dummy textures
218 GrTextureDesc dummyDesc; 312 GrTextureDesc dummyDesc;
219 dummyDesc.fFlags = kRenderTarget_GrTextureFlagBit; 313 dummyDesc.fFlags = kRenderTarget_GrTextureFlagBit;
220 dummyDesc.fConfig = kSkia8888_GrPixelConfig; 314 dummyDesc.fConfig = kSkia8888_GrPixelConfig;
221 dummyDesc.fWidth = 34; 315 dummyDesc.fWidth = 34;
222 dummyDesc.fHeight = 18; 316 dummyDesc.fHeight = 18;
223 SkAutoTUnref<GrTexture> dummyTexture1(this->createTexture(dummyDesc, NULL, 0 )); 317 SkAutoTUnref<GrTexture> dummyTexture1(this->createTexture(dummyDesc, NULL, 0 ));
224 dummyDesc.fFlags = kNone_GrTextureFlags; 318 dummyDesc.fFlags = kNone_GrTextureFlags;
225 dummyDesc.fConfig = kAlpha_8_GrPixelConfig; 319 dummyDesc.fConfig = kAlpha_8_GrPixelConfig;
226 dummyDesc.fWidth = 16; 320 dummyDesc.fWidth = 16;
227 dummyDesc.fHeight = 22; 321 dummyDesc.fHeight = 22;
228 SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0 )); 322 SkAutoTUnref<GrTexture> dummyTexture2(this->createTexture(dummyDesc, NULL, 0 ));
229 323
230 if (!dummyTexture1 || ! dummyTexture2) { 324 if (!dummyTexture1 || ! dummyTexture2) {
231 return false; 325 return false;
232 } 326 }
233 327
234 static const int NUM_TESTS = 512; 328 GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
329
330 // Setup texture cache id key
331 const GrCacheID::Domain glProgramsDomain = GrCacheID::GenerateDomain();
332 GrCacheID::Key key;
333 memset(&key, 0, sizeof(key));
334 key.fData32[0] = kRenderTargetWidth;
335 key.fData32[1] = kRenderTargetHeight;
336 GrCacheID glProgramsCacheID(glProgramsDomain, key);
337
338 // setup clip
339 SkRect screen =
340 SkRect::MakeWH(SkIntToScalar(kRenderTargetWidth), SkIntToScalar(kRen derTargetHeight));
341
342 SkClipStack stack;
343 stack.clipDevRect(screen, SkRegion::kReplace_Op, false);
344
345 // wrap the SkClipStack in a GrClipData
346 GrClipData clipData;
347 clipData.fClipStack = &stack;
348 this->setClip(&clipData);
235 349
236 SkRandom random; 350 SkRandom random;
351 static const int NUM_TESTS = 512;
237 for (int t = 0; t < NUM_TESTS; ++t) { 352 for (int t = 0; t < NUM_TESTS; ++t) {
353 // setup random render target
354 GrTGpuResourceRef<GrRenderTarget> rt(
355 SkRef(random_render_target(this,
356 glProgramsCacheID,
357 &random)),
358 GrIORef::kWrite_IOType);
359 GrDrawState* ds = this->drawState();
360 ds->setRenderTarget(rt.get());
238 361
239 #if 0 362 // if path rendering we have to setup a couple of things like the draw t ype
240 GrPrintf("\nTest Program %d\n-------------\n", t);
241 static const int stop = -1;
242 if (t == stop) {
243 int breakpointhere = 9;
244 }
245 #endif
246
247 GrGLProgramDesc pdesc;
248
249 int currAttribIndex = 1; // we need to always leave room for position
250 int currTextureCoordSet = 0;
251 GrTexture* dummyTextures[] = {dummyTexture1.get(), dummyTexture2.get()};
252
253 int numStages = random.nextULessThan(maxStages + 1);
254 int numColorStages = random.nextULessThan(numStages + 1);
255 int numCoverageStages = numStages - numColorStages;
256
257 SkAutoSTMalloc<8, const GrFragmentStage*> stages(numStages);
258
259 bool usePathRendering = this->glCaps().pathRenderingSupport() && random. nextBool(); 363 bool usePathRendering = this->glCaps().pathRenderingSupport() && random. nextBool();
260 364
261 GrGpu::DrawType drawType = usePathRendering ? GrGpu::kDrawPath_DrawType : 365 GrGpu::DrawType drawType = usePathRendering ? GrGpu::kDrawPath_DrawType :
262 GrGpu::kDrawPoints_DrawTyp e; 366 GrGpu::kDrawPoints_DrawTyp e;
263 367
264 SkAutoTDelete<GrGeometryStage> geometryProcessor; 368 // twiddle drawstate knobs randomly
265 bool hasGeometryProcessor = usePathRendering ? false : random.nextBool() ; 369 bool hasGeometryProcessor = usePathRendering ? false : random.nextBool() ;
266 if (hasGeometryProcessor) { 370 if (hasGeometryProcessor) {
267 while (true) { 371 set_random_gp(this, &random, dummyTextures);
268 SkAutoTUnref<const GrGeometryProcessor> effect( 372 }
269 GrProcessorTestFactory<GrGeometryProcessor>::CreateStage (&random, this->getContext(), *this->caps(), 373 set_random_color_coverage_stages(this, maxStages, usePathRendering, &ran dom, dummyTextures);
270 dummyTextures)); 374 set_random_color(this, &random);
271 SkASSERT(effect); 375 set_random_coverage(this, &random);
272 // Only geometryProcessor can use vertex shader 376 set_random_hints(this, &random);
273 GrGeometryStage* stage = SkNEW_ARGS(GrGeometryStage, (effect.get ())); 377 set_random_state(this, &random);
274 geometryProcessor.reset(stage); 378 set_random_blend_func(this, &random);
379 set_random_stencil(this, &random);
275 380
276 // we have to set dummy vertex attribs 381 // create optimized draw state, setup readDst texture if required, and b uild a descriptor
277 const GrGeometryProcessor::VertexAttribArray& v = effect->getVer texAttribs(); 382 // and program
278 int numVertexAttribs = v.count(); 383 SkAutoTUnref<GrOptDrawState> ods(ds->createOptState(*this->caps()));
384 const GrGeometryStage* geometryProcessor = NULL;
385 SkSTArray<8, const GrFragmentStage*, true> colorStages;
386 SkSTArray<8, const GrFragmentStage*, true> coverageStages;
387 GrGLProgramDesc desc;
388 GrDeviceCoordTexture dstCopy;
279 389
280 SkASSERT(GrGeometryProcessor::kMaxVertexAttribs == 2 && 390 if (!this->setupDstReadIfNecessary(&dstCopy, NULL)) {
281 GrGeometryProcessor::kMaxVertexAttribs >= numVertexAttr ibs); 391 SkDEBUGFAIL("Couldn't setup dst read texture");
282 size_t runningStride = GrVertexAttribTypeSize(genericVertexAttri bs[0].fType);
283 for (int i = 0; i < numVertexAttribs; i++) {
284 genericVertexAttribs[i + 1].fOffset = runningStride;
285 genericVertexAttribs[i + 1].fType =
286 convert_sltype_to_attribtype(v[i].getType());
287 runningStride += GrVertexAttribTypeSize(genericVertexAttribs [i + 1].fType);
288 }
289
290 // update the vertex attributes with the ds
291 GrDrawState* ds = this->drawState();
292 ds->setVertexAttribs<genericVertexAttribs>(numVertexAttribs + 1, runningStride);
293 currAttribIndex = numVertexAttribs + 1;
294 break;
295 }
296 }
297 for (int s = 0; s < numStages;) {
298 SkAutoTUnref<const GrFragmentProcessor> effect(
299 GrProcessorTestFactory<GrFragmentProcessor>::CreateStage(
300 &ran dom,
301 this ->getContext(),
302 *thi s->caps(),
303 dumm yTextures));
304 SkASSERT(effect);
305
306 // If adding this effect would exceed the max texture coord set coun t then generate a
307 // new random effect.
308 if (usePathRendering && this->glPathRendering()->texturingMode() ==
309 GrGLPathRendering::FixedFunction_TexturingMo de) {;
310 int numTransforms = effect->numTransforms();
311 if (currTextureCoordSet + numTransforms > this->glCaps().maxFixe dFunctionTextureCoords()) {
312 continue;
313 }
314 currTextureCoordSet += numTransforms;
315 }
316 GrFragmentStage* stage = SkNEW_ARGS(GrFragmentStage, (effect.get())) ;
317
318 stages[s] = stage;
319 ++s;
320 }
321 const GrTexture* dstTexture = random.nextBool() ? dummyTextures[0] : dum myTextures[1];
322 if (!pdesc.setRandom(&random,
323 this,
324 dummyTextures[0]->asRenderTarget(),
325 dstTexture,
326 geometryProcessor.get(),
327 stages.get(),
328 numColorStages,
329 numCoverageStages,
330 currAttribIndex,
331 drawType)) {
332 return false; 392 return false;
333 } 393 }
334 394 if (!GrGLProgramDesc::Build(*ods,
335 SkAutoTUnref<GrGLProgram> program(GrGLProgram::Create(this, 395 drawType,
336 pdesc, 396 ods->getSrcBlendCoeff(),
337 geometryProcessor. get(), 397 ods->getDstBlendCoeff(),
338 stages, 398 this,
339 stages + numColorS tages)); 399 dstCopy.texture() ? &dstCopy : NULL,
340 for (int s = 0; s < numStages; ++s) { 400 &geometryProcessor,
341 SkDELETE(stages[s]); 401 &colorStages,
402 &coverageStages,
403 &desc)) {
404 SkDEBUGFAIL("Failed to generate GL program descriptor");
405 return false;
342 } 406 }
407 SkAutoTUnref<GrGLProgram> program(SkSafeRef(GrGLProgram::Create(this,
408 desc,
409 geometry Processor,
410 colorSta ges.begin(),
411 coverage Stages.begin())));
343 if (NULL == program.get()) { 412 if (NULL == program.get()) {
413 SkDEBUGFAIL("Failed to create program!");
344 return false; 414 return false;
345 } 415 }
346 416
347 // We have to reset the drawstate because we might have added a gp 417 // We have to reset the drawstate because we might have added a gp
348 this->drawState()->reset(); 418 ds->reset();
349 } 419 }
350 return true; 420 return true;
351 } 421 }
352 422
353 DEF_GPUTEST(GLPrograms, reporter, factory) { 423 DEF_GPUTEST(GLPrograms, reporter, factory) {
354 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) { 424 for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
355 GrContext* context = factory->get(static_cast<GrContextFactory::GLContex tType>(type)); 425 GrContext* context = factory->get(static_cast<GrContextFactory::GLContex tType>(type));
356 if (context) { 426 if (context) {
357 GrGpuGL* gpu = static_cast<GrGpuGL*>(context->getGpu()); 427 GrGpuGL* gpu = static_cast<GrGpuGL*>(context->getGpu());
358 int maxStages = 6; 428 int maxStages = 6;
(...skipping 27 matching lines...) Expand all
386 SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1)); 456 SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1));
387 GrConfigConversionEffect::Create(NULL, 457 GrConfigConversionEffect::Create(NULL,
388 false, 458 false,
389 GrConfigConversionEffect::kNone_PMConversio n, 459 GrConfigConversionEffect::kNone_PMConversio n,
390 SkMatrix::I()); 460 SkMatrix::I());
391 SkScalar matrix[20]; 461 SkScalar matrix[20];
392 SkAutoTUnref<SkColorMatrixFilter> cmf(SkColorMatrixFilter::Create(matrix)); 462 SkAutoTUnref<SkColorMatrixFilter> cmf(SkColorMatrixFilter::Create(matrix));
393 } 463 }
394 464
395 #endif 465 #endif
OLDNEW
« src/gpu/gl/GrGpuGL_program.cpp ('K') | « src/gpu/gl/GrGpuGL_program.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698