| 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 |