| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrDrawTarget.h" | 8 #include "GrDrawTarget.h" |
| 9 | 9 |
| 10 #include "GrAuditTrail.h" | 10 #include "GrAuditTrail.h" |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 } | 250 } |
| 251 } | 251 } |
| 252 | 252 |
| 253 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | 253 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; |
| 254 if (clip.clipCoverageFragmentProcessor()) { | 254 if (clip.clipCoverageFragmentProcessor()) { |
| 255 arfps.set(&pipelineBuilder); | 255 arfps.set(&pipelineBuilder); |
| 256 arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor())
; | 256 arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor())
; |
| 257 } | 257 } |
| 258 | 258 |
| 259 GrPipeline::CreateArgs args; | 259 GrPipeline::CreateArgs args; |
| 260 if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState()
, | 260 args.fPipelineBuilder = &pipelineBuilder; |
| 261 clip.hasStencilClip(), batch)) { | 261 args.fCaps = this->caps(); |
| 262 args.fScissor = &clip.scissorState(); |
| 263 args.fHasStencilClip = clip.hasStencilClip(); |
| 264 if (pipelineBuilder.hasUserStencilSettings() || clip.hasStencilClip()) { |
| 265 fResourceProvider->attachStencilAttachment(pipelineBuilder.getRenderTarg
et()); |
| 266 } |
| 267 batch->getPipelineOptimizations(&args.fOpts); |
| 268 GrScissorState finalScissor; |
| 269 if (args.fOpts.fOverrides.fUsePLSDstRead) { |
| 270 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
| 271 GrGLIRect viewport; |
| 272 viewport.fLeft = 0; |
| 273 viewport.fBottom = 0; |
| 274 viewport.fWidth = rt->width(); |
| 275 viewport.fHeight = rt->height(); |
| 276 SkIRect ibounds; |
| 277 ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewpo
rt.fLeft, |
| 278 viewport.fWidth); |
| 279 ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport
.fBottom, |
| 280 viewport.fHeight); |
| 281 ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewp
ort.fLeft, |
| 282 viewport.fWidth); |
| 283 ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), vie
wport.fBottom, |
| 284 viewport.fHeight); |
| 285 if (clip.scissorState().enabled()) { |
| 286 const SkIRect& scissorRect = clip.scissorState().rect(); |
| 287 if (!ibounds.intersect(scissorRect)) { |
| 288 ibounds = scissorRect; |
| 289 } |
| 290 } |
| 291 finalScissor.set(ibounds); |
| 292 args.fScissor = &finalScissor; |
| 293 } |
| 294 args.fOpts.fColorPOI.completeCalculations(pipelineBuilder.fColorFragmentProc
essors.begin(), |
| 295 pipelineBuilder.numColorFragmentPr
ocessors()); |
| 296 args.fOpts.fCoveragePOI.completeCalculations( |
| 297 pipelineBuilder.fCoverageFragment
Processors.begin(), |
| 298 pipelineBuilder.numCoverageFragme
ntProcessors()); |
| 299 if (!this->setupDstReadIfNecessary(pipelineBuilder, args.fOpts, &args.fDstTe
xture, |
| 300 batch->bounds())) { |
| 262 return; | 301 return; |
| 263 } | 302 } |
| 264 | 303 |
| 304 if (!batch->installPipeline(args)) { |
| 305 return; |
| 306 } |
| 307 |
| 265 #ifdef ENABLE_MDB | 308 #ifdef ENABLE_MDB |
| 266 SkASSERT(fRenderTarget); | 309 SkASSERT(fRenderTarget); |
| 267 batch->pipeline()->addDependenciesTo(fRenderTarget); | 310 batch->pipeline()->addDependenciesTo(fRenderTarget); |
| 268 #endif | 311 #endif |
| 269 | 312 |
| 270 this->recordBatch(batch); | 313 this->recordBatch(batch); |
| 271 } | 314 } |
| 272 | 315 |
| 273 inline static const GrUserStencilSettings& get_path_stencil_settings_for_fill( | |
| 274 GrPathRendering::FillType fill) { | |
| 275 static constexpr GrUserStencilSettings kWindingStencilSettings( | |
| 276 GrUserStencilSettings::StaticInit< | |
| 277 0xffff, | |
| 278 GrUserStencilTest::kAlwaysIfInClip, | |
| 279 0xffff, | |
| 280 GrUserStencilOp::kIncMaybeClamp, // TODO: Use wrap ops for NVPR. | |
| 281 GrUserStencilOp::kIncMaybeClamp, | |
| 282 0xffff>() | |
| 283 ); | |
| 284 | |
| 285 static constexpr GrUserStencilSettings kEvenOddStencilSettings( | |
| 286 GrUserStencilSettings::StaticInit< | |
| 287 0xffff, | |
| 288 GrUserStencilTest::kAlwaysIfInClip, | |
| 289 0xffff, | |
| 290 GrUserStencilOp::kInvert, | |
| 291 GrUserStencilOp::kInvert, | |
| 292 0xffff>() | |
| 293 ); | |
| 294 | |
| 295 switch (fill) { | |
| 296 default: | |
| 297 SkFAIL("Unexpected path fill."); | |
| 298 case GrPathRendering::kWinding_FillType: | |
| 299 return kWindingStencilSettings; | |
| 300 case GrPathRendering::kEvenOdd_FillType: | |
| 301 return kEvenOddStencilSettings; | |
| 302 } | |
| 303 } | |
| 304 | |
| 305 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, | 316 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, |
| 306 const SkMatrix& viewMatrix, | 317 const SkMatrix& viewMatrix, |
| 307 const GrPath* path, | 318 const GrPath* path, |
| 308 GrPathRendering::FillType fill) { | 319 GrPathRendering::FillType fill) { |
| 309 // TODO: extract portions of checkDraw that are relevant to path stenciling. | 320 // TODO: extract portions of checkDraw that are relevant to path stenciling. |
| 310 SkASSERT(path); | 321 SkASSERT(path); |
| 311 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); | 322 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); |
| 312 | 323 |
| 313 // Setup clip | 324 // Setup clip |
| 314 GrAppliedClip clip; | 325 GrAppliedClip clip; |
| 315 if (!fClipMaskManager->setupClipping(pipelineBuilder, nullptr, &clip)) { | 326 if (!fClipMaskManager->setupClipping(pipelineBuilder, nullptr, &clip)) { |
| 316 return; | 327 return; |
| 317 } | 328 } |
| 318 | 329 |
| 319 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | 330 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; |
| 320 if (clip.clipCoverageFragmentProcessor()) { | 331 if (clip.clipCoverageFragmentProcessor()) { |
| 321 arfps.set(&pipelineBuilder); | 332 arfps.set(&pipelineBuilder); |
| 322 arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor())
; | 333 arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor())
; |
| 323 } | 334 } |
| 324 | 335 |
| 325 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 336 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
| 326 GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAtt
achment(rt); | 337 GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAtt
achment(rt); |
| 327 | 338 |
| 328 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, | 339 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, |
| 329 pipelineBuilder.isHWAntialias(), | 340 pipelineBuilder.isHWAntialias(), |
| 330 get_path_stencil_settings_for_fi
ll(fill), | 341 fill, |
| 331 clip.hasStencilClip(), | 342 clip.hasStencilClip(), |
| 332 stencilAttachment->bits(), | 343 stencilAttachment->bits(), |
| 333 clip.scissorState(), | 344 clip.scissorState(), |
| 334 pipelineBuilder.getRenderTarget(
), | 345 pipelineBuilder.getRenderTarget(
), |
| 335 path); | 346 path); |
| 336 this->recordBatch(batch); | 347 this->recordBatch(batch); |
| 337 batch->unref(); | 348 batch->unref(); |
| 338 } | 349 } |
| 339 | 350 |
| 340 void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder, | |
| 341 GrDrawPathBatchBase* batch) { | |
| 342 // This looks like drawBatch() but there is an added wrinkle that stencil se
ttings get inserted | |
| 343 // after setting up clipping but before onDrawBatch(). TODO: Figure out a be
tter model for | |
| 344 // handling stencil settings WRT interactions between pipeline(builder), cli
pmaskmanager, and | |
| 345 // batches. | |
| 346 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); | |
| 347 | |
| 348 GrAppliedClip clip; | |
| 349 if (!fClipMaskManager->setupClipping(pipelineBuilder, &batch->bounds(), &cli
p)) { | |
| 350 return; | |
| 351 } | |
| 352 | |
| 353 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | |
| 354 if (clip.clipCoverageFragmentProcessor()) { | |
| 355 arfps.set(&pipelineBuilder); | |
| 356 arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor())
; | |
| 357 } | |
| 358 | |
| 359 // Ensure the render target has a stencil buffer and get the stencil setting
s. | |
| 360 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | |
| 361 GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt); | |
| 362 // TODO: Move this step into GrDrawPathPath::onPrepare(). | |
| 363 batch->setStencilSettings(get_path_stencil_settings_for_fill(batch->fillType
()), | |
| 364 clip.hasStencilClip(), | |
| 365 sb->bits()); | |
| 366 | |
| 367 GrPipeline::CreateArgs args; | |
| 368 if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState()
, | |
| 369 clip.hasStencilClip(), batch)) { | |
| 370 return; | |
| 371 } | |
| 372 | |
| 373 this->recordBatch(batch); | |
| 374 } | |
| 375 | |
| 376 void GrDrawTarget::clear(const SkIRect* rect, | 351 void GrDrawTarget::clear(const SkIRect* rect, |
| 377 GrColor color, | 352 GrColor color, |
| 378 bool canIgnoreRect, | 353 bool canIgnoreRect, |
| 379 GrRenderTarget* renderTarget) { | 354 GrRenderTarget* renderTarget) { |
| 380 SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height
()); | 355 SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height
()); |
| 381 SkIRect clippedRect; | 356 SkIRect clippedRect; |
| 382 if (!rect || | 357 if (!rect || |
| 383 (canIgnoreRect && this->caps()->fullClearIsFree()) || | 358 (canIgnoreRect && this->caps()->fullClearIsFree()) || |
| 384 rect->contains(rtRect)) { | 359 rect->contains(rtRect)) { |
| 385 rect = &rtRect; | 360 rect = &rtRect; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 if (j > maxCandidateIdx) { | 516 if (j > maxCandidateIdx) { |
| 542 GrBATCH_INFO("\t\tReached max lookahead or end of batch array %d
\n", i); | 517 GrBATCH_INFO("\t\tReached max lookahead or end of batch array %d
\n", i); |
| 543 break; | 518 break; |
| 544 } | 519 } |
| 545 } | 520 } |
| 546 } | 521 } |
| 547 } | 522 } |
| 548 | 523 |
| 549 /////////////////////////////////////////////////////////////////////////////// | 524 /////////////////////////////////////////////////////////////////////////////// |
| 550 | 525 |
| 551 bool GrDrawTarget::installPipelineInDrawBatch(const GrPipelineBuilder* pipelineB
uilder, | |
| 552 const GrScissorState* scissor, | |
| 553 bool hasStencilClip, | |
| 554 GrDrawBatch* batch) { | |
| 555 GrPipeline::CreateArgs args; | |
| 556 args.fPipelineBuilder = pipelineBuilder; | |
| 557 args.fCaps = this->caps(); | |
| 558 args.fScissor = scissor; | |
| 559 if (pipelineBuilder->hasUserStencilSettings() || hasStencilClip) { | |
| 560 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); | |
| 561 GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt)
; | |
| 562 args.fNumStencilBits = sb->bits(); | |
| 563 } else { | |
| 564 args.fNumStencilBits = 0; | |
| 565 } | |
| 566 args.fHasStencilClip = hasStencilClip; | |
| 567 batch->getPipelineOptimizations(&args.fOpts); | |
| 568 GrScissorState finalScissor; | |
| 569 if (args.fOpts.fOverrides.fUsePLSDstRead) { | |
| 570 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); | |
| 571 GrGLIRect viewport; | |
| 572 viewport.fLeft = 0; | |
| 573 viewport.fBottom = 0; | |
| 574 viewport.fWidth = rt->width(); | |
| 575 viewport.fHeight = rt->height(); | |
| 576 SkIRect ibounds; | |
| 577 ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewpo
rt.fLeft, | |
| 578 viewport.fWidth); | |
| 579 ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport
.fBottom, | |
| 580 viewport.fHeight); | |
| 581 ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewp
ort.fLeft, | |
| 582 viewport.fWidth); | |
| 583 ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), vie
wport.fBottom, | |
| 584 viewport.fHeight); | |
| 585 if (scissor != nullptr && scissor->enabled()) { | |
| 586 if (!ibounds.intersect(scissor->rect())) { | |
| 587 ibounds = scissor->rect(); | |
| 588 } | |
| 589 } | |
| 590 finalScissor.set(ibounds); | |
| 591 args.fScissor = &finalScissor; | |
| 592 } | |
| 593 args.fOpts.fColorPOI.completeCalculations(pipelineBuilder->fColorFragmentPro
cessors.begin(), | |
| 594 pipelineBuilder->numColorFragmentP
rocessors()); | |
| 595 args.fOpts.fCoveragePOI.completeCalculations( | |
| 596 pipelineBuilder->fCoverageFragmen
tProcessors.begin(), | |
| 597 pipelineBuilder->numCoverageFragm
entProcessors()); | |
| 598 if (!this->setupDstReadIfNecessary(*pipelineBuilder, args.fOpts, &args.fDstT
exture, | |
| 599 batch->bounds())) { | |
| 600 return false; | |
| 601 } | |
| 602 | |
| 603 if (!batch->installPipeline(args)) { | |
| 604 return false; | |
| 605 } | |
| 606 | |
| 607 return true; | |
| 608 } | |
| 609 | |
| 610 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { | 526 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { |
| 611 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); | 527 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); |
| 612 this->recordBatch(batch); | 528 this->recordBatch(batch); |
| 613 batch->unref(); | 529 batch->unref(); |
| 614 } | 530 } |
| OLD | NEW |