OLD | NEW |
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 "GrContextFactory.h" | 15 #include "GrContextFactory.h" |
16 #include "GrInvariantOutput.h" | 16 #include "GrInvariantOutput.h" |
17 #include "GrOptDrawState.h" | 17 #include "GrPipeline.h" |
18 #include "GrTest.h" | 18 #include "GrTest.h" |
19 #include "GrXferProcessor.h" | 19 #include "GrXferProcessor.h" |
20 #include "SkChecksum.h" | 20 #include "SkChecksum.h" |
21 #include "SkRandom.h" | 21 #include "SkRandom.h" |
22 #include "Test.h" | 22 #include "Test.h" |
23 #include "effects/GrConfigConversionEffect.h" | 23 #include "effects/GrConfigConversionEffect.h" |
24 #include "effects/GrPorterDuffXferProcessor.h" | 24 #include "effects/GrPorterDuffXferProcessor.h" |
25 #include "gl/GrGLGpu.h" | 25 #include "gl/GrGLGpu.h" |
26 #include "gl/GrGLPathRendering.h" | 26 #include "gl/GrGLPathRendering.h" |
27 #include "gl/builders/GrGLProgramBuilder.h" | 27 #include "gl/builders/GrGLProgramBuilder.h" |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 SkAutoTUnref<GrTexture> texture(context->findAndRefTexture(texDesc, cacheId,
¶ms)); | 114 SkAutoTUnref<GrTexture> texture(context->findAndRefTexture(texDesc, cacheId,
¶ms)); |
115 if (!texture) { | 115 if (!texture) { |
116 texture.reset(context->createTexture(¶ms, texDesc, cacheId, 0, 0)); | 116 texture.reset(context->createTexture(¶ms, texDesc, cacheId, 0, 0)); |
117 if (!texture) { | 117 if (!texture) { |
118 return NULL; | 118 return NULL; |
119 } | 119 } |
120 } | 120 } |
121 return SkRef(texture->asRenderTarget()); | 121 return SkRef(texture->asRenderTarget()); |
122 } | 122 } |
123 | 123 |
124 static void set_random_xpf(GrContext* context, const GrDrawTargetCaps& caps, GrD
rawState* ds, | 124 static void set_random_xpf(GrContext* context, const GrDrawTargetCaps& caps, |
125 SkRandom* random, GrTexture* dummyTextures[]) { | 125 GrPipelineBuilder* pipelineBuilder, SkRandom* random, |
| 126 GrTexture* dummyTextures[]) { |
126 SkAutoTUnref<const GrXPFactory> xpf( | 127 SkAutoTUnref<const GrXPFactory> xpf( |
127 GrProcessorTestFactory<GrXPFactory>::CreateStage(random, context, caps,
dummyTextures)); | 128 GrProcessorTestFactory<GrXPFactory>::CreateStage(random, context, caps,
dummyTextures)); |
128 SkASSERT(xpf); | 129 SkASSERT(xpf); |
129 ds->setXPFactory(xpf.get()); | 130 pipelineBuilder->setXPFactory(xpf.get()); |
130 } | 131 } |
131 | 132 |
132 static const GrGeometryProcessor* get_random_gp(GrContext* context, | 133 static const GrGeometryProcessor* get_random_gp(GrContext* context, |
133 const GrDrawTargetCaps& caps, | 134 const GrDrawTargetCaps& caps, |
134 SkRandom* random, | 135 SkRandom* random, |
135 GrTexture* dummyTextures[]) { | 136 GrTexture* dummyTextures[]) { |
136 return GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(random, | 137 return GrProcessorTestFactory<GrGeometryProcessor>::CreateStage(random, |
137 context, | 138 context, |
138 caps, | 139 caps, |
139 dummyTexture
s); | 140 dummyTexture
s); |
140 } | 141 } |
141 | 142 |
142 static void set_random_color_coverage_stages(GrGLGpu* gpu, | 143 static void set_random_color_coverage_stages(GrGLGpu* gpu, |
143 GrDrawState* ds, | 144 GrPipelineBuilder* pipelineBuilder, |
144 int maxStages, | 145 int maxStages, |
145 bool usePathRendering, | 146 bool usePathRendering, |
146 SkRandom* random, | 147 SkRandom* random, |
147 GrTexture* dummyTextures[]) { | 148 GrTexture* dummyTextures[]) { |
148 int numProcs = random->nextULessThan(maxStages + 1); | 149 int numProcs = random->nextULessThan(maxStages + 1); |
149 int numColorProcs = random->nextULessThan(numProcs + 1); | 150 int numColorProcs = random->nextULessThan(numProcs + 1); |
150 | 151 |
151 int currTextureCoordSet = 0; | 152 int currTextureCoordSet = 0; |
152 for (int s = 0; s < numProcs;) { | 153 for (int s = 0; s < numProcs;) { |
153 SkAutoTUnref<const GrFragmentProcessor> fp( | 154 SkAutoTUnref<const GrFragmentProcessor> fp( |
(...skipping 10 matching lines...) Expand all Loading... |
164 int numTransforms = fp->numTransforms(); | 165 int numTransforms = fp->numTransforms(); |
165 if (currTextureCoordSet + numTransforms > | 166 if (currTextureCoordSet + numTransforms > |
166 gpu->glCaps().maxFixedFunctionTextureCoords()) { | 167 gpu->glCaps().maxFixedFunctionTextureCoords()) { |
167 continue; | 168 continue; |
168 } | 169 } |
169 currTextureCoordSet += numTransforms; | 170 currTextureCoordSet += numTransforms; |
170 } | 171 } |
171 | 172 |
172 // finally add the stage to the correct pipeline in the drawstate | 173 // finally add the stage to the correct pipeline in the drawstate |
173 if (s < numColorProcs) { | 174 if (s < numColorProcs) { |
174 ds->addColorProcessor(fp); | 175 pipelineBuilder->addColorProcessor(fp); |
175 } else { | 176 } else { |
176 ds->addCoverageProcessor(fp); | 177 pipelineBuilder->addCoverageProcessor(fp); |
177 } | 178 } |
178 ++s; | 179 ++s; |
179 } | 180 } |
180 } | 181 } |
181 | 182 |
182 static void set_random_state(GrDrawState* ds, SkRandom* random) { | 183 static void set_random_state(GrPipelineBuilder* pipelineBuilder, SkRandom* rando
m) { |
183 int state = 0; | 184 int state = 0; |
184 for (int i = 1; i <= GrDrawState::kLast_StateBit; i <<= 1) { | 185 for (int i = 1; i <= GrPipelineBuilder::kLast_StateBit; i <<= 1) { |
185 state |= random->nextBool() * i; | 186 state |= random->nextBool() * i; |
186 } | 187 } |
187 ds->enableState(state); | 188 pipelineBuilder->enableState(state); |
188 } | 189 } |
189 | 190 |
190 // right now, the only thing we seem to care about in drawState's stencil is 'do
esWrite()' | 191 // right now, the only thing we seem to care about in drawState's stencil is 'do
esWrite()' |
191 static void set_random_stencil(GrDrawState* ds, SkRandom* random) { | 192 static void set_random_stencil(GrPipelineBuilder* pipelineBuilder, SkRandom* ran
dom) { |
192 GR_STATIC_CONST_SAME_STENCIL(kDoesWriteStencil, | 193 GR_STATIC_CONST_SAME_STENCIL(kDoesWriteStencil, |
193 kReplace_StencilOp, | 194 kReplace_StencilOp, |
194 kReplace_StencilOp, | 195 kReplace_StencilOp, |
195 kAlways_StencilFunc, | 196 kAlways_StencilFunc, |
196 0xffff, | 197 0xffff, |
197 0xffff, | 198 0xffff, |
198 0xffff); | 199 0xffff); |
199 GR_STATIC_CONST_SAME_STENCIL(kDoesNotWriteStencil, | 200 GR_STATIC_CONST_SAME_STENCIL(kDoesNotWriteStencil, |
200 kKeep_StencilOp, | 201 kKeep_StencilOp, |
201 kKeep_StencilOp, | 202 kKeep_StencilOp, |
202 kNever_StencilFunc, | 203 kNever_StencilFunc, |
203 0xffff, | 204 0xffff, |
204 0xffff, | 205 0xffff, |
205 0xffff); | 206 0xffff); |
206 | 207 |
207 if (random->nextBool()) { | 208 if (random->nextBool()) { |
208 ds->setStencil(kDoesWriteStencil); | 209 pipelineBuilder->setStencil(kDoesWriteStencil); |
209 } else { | 210 } else { |
210 ds->setStencil(kDoesNotWriteStencil); | 211 pipelineBuilder->setStencil(kDoesNotWriteStencil); |
211 } | 212 } |
212 } | 213 } |
213 | 214 |
214 bool GrDrawTarget::programUnitTest(int maxStages) { | 215 bool GrDrawTarget::programUnitTest(int maxStages) { |
215 GrGLGpu* gpu = static_cast<GrGLGpu*>(fContext->getGpu()); | 216 GrGLGpu* gpu = static_cast<GrGLGpu*>(fContext->getGpu()); |
216 // setup dummy textures | 217 // setup dummy textures |
217 GrSurfaceDesc dummyDesc; | 218 GrSurfaceDesc dummyDesc; |
218 dummyDesc.fFlags = kRenderTarget_GrSurfaceFlag; | 219 dummyDesc.fFlags = kRenderTarget_GrSurfaceFlag; |
219 dummyDesc.fConfig = kSkia8888_GrPixelConfig; | 220 dummyDesc.fConfig = kSkia8888_GrPixelConfig; |
220 dummyDesc.fWidth = 34; | 221 dummyDesc.fWidth = 34; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 SkRandom random; | 260 SkRandom random; |
260 static const int NUM_TESTS = 512; | 261 static const int NUM_TESTS = 512; |
261 for (int t = 0; t < NUM_TESTS;) { | 262 for (int t = 0; t < NUM_TESTS;) { |
262 // setup random render target(can fail) | 263 // setup random render target(can fail) |
263 SkAutoTUnref<GrRenderTarget> rt(random_render_target(fContext, glProgram
sCacheID, &random)); | 264 SkAutoTUnref<GrRenderTarget> rt(random_render_target(fContext, glProgram
sCacheID, &random)); |
264 if (!rt.get()) { | 265 if (!rt.get()) { |
265 SkDebugf("Could not allocate render target"); | 266 SkDebugf("Could not allocate render target"); |
266 return false; | 267 return false; |
267 } | 268 } |
268 | 269 |
269 GrDrawState ds; | 270 GrPipelineBuilder pipelineBuilder; |
270 ds.setRenderTarget(rt.get()); | 271 pipelineBuilder.setRenderTarget(rt.get()); |
271 | 272 |
272 // if path rendering we have to setup a couple of things like the draw t
ype | 273 // if path rendering we have to setup a couple of things like the draw t
ype |
273 bool usePathRendering = gpu->glCaps().pathRenderingSupport() && random.n
extBool(); | 274 bool usePathRendering = gpu->glCaps().pathRenderingSupport() && random.n
extBool(); |
274 | 275 |
275 // twiddle drawstate knobs randomly | 276 // twiddle drawstate knobs randomly |
276 bool hasGeometryProcessor = !usePathRendering; | 277 bool hasGeometryProcessor = !usePathRendering; |
277 SkAutoTUnref<const GrGeometryProcessor> gp; | 278 SkAutoTUnref<const GrGeometryProcessor> gp; |
278 SkAutoTUnref<const GrPathProcessor> pathProc; | 279 SkAutoTUnref<const GrPathProcessor> pathProc; |
279 if (hasGeometryProcessor) { | 280 if (hasGeometryProcessor) { |
280 gp.reset(get_random_gp(fContext, gpu->glCaps(), &random, dummyTextur
es)); | 281 gp.reset(get_random_gp(fContext, gpu->glCaps(), &random, dummyTextur
es)); |
281 } else { | 282 } else { |
282 pathProc.reset(GrPathProcessor::Create(GrColor_WHITE)); | 283 pathProc.reset(GrPathProcessor::Create(GrColor_WHITE)); |
283 } | 284 } |
284 set_random_color_coverage_stages(gpu, | 285 set_random_color_coverage_stages(gpu, |
285 &ds, | 286 &pipelineBuilder, |
286 maxStages - hasGeometryProcessor, | 287 maxStages - hasGeometryProcessor, |
287 usePathRendering, | 288 usePathRendering, |
288 &random, | 289 &random, |
289 dummyTextures); | 290 dummyTextures); |
290 | 291 |
291 // creates a random xfer processor factory on the draw state | 292 // creates a random xfer processor factory on the draw state |
292 set_random_xpf(fContext, gpu->glCaps(), &ds, &random, dummyTextures); | 293 set_random_xpf(fContext, gpu->glCaps(), &pipelineBuilder, &random, dummy
Textures); |
293 | 294 |
294 set_random_state(&ds, &random); | 295 set_random_state(&pipelineBuilder, &random); |
295 set_random_stencil(&ds, &random); | 296 set_random_stencil(&pipelineBuilder, &random); |
296 | 297 |
297 GrDeviceCoordTexture dstCopy; | 298 GrDeviceCoordTexture dstCopy; |
298 | 299 |
299 const GrPrimitiveProcessor* primProc; | 300 const GrPrimitiveProcessor* primProc; |
300 if (hasGeometryProcessor) { | 301 if (hasGeometryProcessor) { |
301 primProc = gp.get(); | 302 primProc = gp.get(); |
302 } else { | 303 } else { |
303 primProc = pathProc.get(); | 304 primProc = pathProc.get(); |
304 } | 305 } |
305 if (!this->setupDstReadIfNecessary(&ds, &dstCopy, NULL)) { | 306 if (!this->setupDstReadIfNecessary(&pipelineBuilder, &dstCopy, NULL)) { |
306 SkDebugf("Couldn't setup dst read texture"); | 307 SkDebugf("Couldn't setup dst read texture"); |
307 return false; | 308 return false; |
308 } | 309 } |
309 | 310 |
310 // create optimized draw state, setup readDst texture if required, and b
uild a descriptor | 311 // create optimized draw state, setup readDst texture if required, and b
uild a descriptor |
311 // and program. ODS creation can fail, so we have to check | 312 // and program. ODS creation can fail, so we have to check |
312 GrOptDrawState ods(ds, primProc, *gpu->caps(), scissor, &dstCopy); | 313 GrPipeline pipeline(pipelineBuilder, primProc, *gpu->caps(), scissor, &d
stCopy); |
313 if (ods.mustSkip()) { | 314 if (pipeline.mustSkip()) { |
314 continue; | 315 continue; |
315 } | 316 } |
316 GrBatchTracker bt; | 317 GrBatchTracker bt; |
317 primProc->initBatchTracker(&bt, ods.getInitBatchTracker()); | 318 primProc->initBatchTracker(&bt, pipeline.getInitBatchTracker()); |
318 | 319 |
319 GrProgramDesc desc; | 320 GrProgramDesc desc; |
320 gpu->buildProgramDesc(&desc, *primProc, ods, ods.descInfo(), bt); | 321 gpu->buildProgramDesc(&desc, *primProc, pipeline, pipeline.descInfo(), b
t); |
321 | 322 |
322 GrGpu::DrawArgs args(primProc, &ods, &desc, &bt); | 323 GrGpu::DrawArgs args(primProc, &pipeline, &desc, &bt); |
323 SkAutoTUnref<GrGLProgram> program(GrGLProgramBuilder::CreateProgram(args
, gpu)); | 324 SkAutoTUnref<GrGLProgram> program(GrGLProgramBuilder::CreateProgram(args
, gpu)); |
324 | 325 |
325 if (NULL == program.get()) { | 326 if (NULL == program.get()) { |
326 SkDebugf("Failed to create program!"); | 327 SkDebugf("Failed to create program!"); |
327 return false; | 328 return false; |
328 } | 329 } |
329 | 330 |
330 // because occasionally optimized drawstate creation will fail for valid
reasons, we only | 331 // because occasionally optimized drawstate creation will fail for valid
reasons, we only |
331 // want to increment on success | 332 // want to increment on success |
332 ++t; | 333 ++t; |
(...skipping 29 matching lines...) Expand all Loading... |
362 } | 363 } |
363 #endif | 364 #endif |
364 GrTestTarget target; | 365 GrTestTarget target; |
365 context->getTestTarget(&target); | 366 context->getTestTarget(&target); |
366 REPORTER_ASSERT(reporter, target.target()->programUnitTest(maxStages
)); | 367 REPORTER_ASSERT(reporter, target.target()->programUnitTest(maxStages
)); |
367 } | 368 } |
368 } | 369 } |
369 } | 370 } |
370 | 371 |
371 #endif | 372 #endif |
OLD | NEW |