| 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 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 if (bounds->fRight == before.fRight) { | 314 if (bounds->fRight == before.fRight) { |
| 315 bounds->fRight += 1; | 315 bounds->fRight += 1; |
| 316 } | 316 } |
| 317 if (bounds->fBottom == before.fBottom) { | 317 if (bounds->fBottom == before.fBottom) { |
| 318 bounds->fBottom += 1; | 318 bounds->fBottom += 1; |
| 319 } | 319 } |
| 320 } | 320 } |
| 321 } | 321 } |
| 322 } | 322 } |
| 323 | 323 |
| 324 static inline bool intersect(SkRect* out, const SkRect& a, const SkRect& b) { | |
| 325 SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom); | |
| 326 SkASSERT(b.fLeft <= b.fRight && b.fTop <= b.fBottom); | |
| 327 out->fLeft = SkTMax(a.fLeft, b.fLeft); | |
| 328 out->fTop = SkTMax(a.fTop, b.fTop); | |
| 329 out->fRight = SkTMin(a.fRight, b.fRight); | |
| 330 out->fBottom = SkTMin(a.fBottom, b.fBottom); | |
| 331 return (out->fLeft <= out->fRight && out->fTop <= out->fBottom); | |
| 332 } | |
| 333 | |
| 334 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, | 324 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, |
| 335 GrDrawContext* drawContext, | 325 GrDrawContext* drawContext, |
| 336 const GrClip& clip, | 326 const GrClip& clip, |
| 337 GrDrawBatch* batch) { | 327 GrDrawBatch* batch) { |
| 338 // Setup clip | 328 // Setup clip |
| 339 GrAppliedClip appliedClip; | |
| 340 SkRect bounds; | 329 SkRect bounds; |
| 341 batch_bounds(&bounds, batch); | 330 batch_bounds(&bounds, batch); |
| 342 if (!clip.apply(fContext, drawContext, &bounds, | 331 GrAppliedClip appliedClip(bounds); |
| 343 pipelineBuilder.isHWAntialias(), pipelineBuilder.hasUserSten
cilSettings(), | 332 if (!clip.apply(fContext, drawContext, pipelineBuilder.isHWAntialias(), |
| 344 &appliedClip)) { | 333 pipelineBuilder.hasUserStencilSettings(), &appliedClip)) { |
| 345 return; | 334 return; |
| 346 } | 335 } |
| 347 | 336 |
| 348 // TODO: this is the only remaining usage of the AutoRestoreFragmentProcesso
rState - remove it | 337 // TODO: this is the only remaining usage of the AutoRestoreFragmentProcesso
rState - remove it |
| 349 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | 338 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; |
| 350 if (appliedClip.getClipCoverageFragmentProcessor()) { | 339 if (appliedClip.clipCoverageFragmentProcessor()) { |
| 351 arfps.set(&pipelineBuilder); | 340 arfps.set(&pipelineBuilder); |
| 352 arfps.addCoverageFragmentProcessor(sk_ref_sp(appliedClip.getClipCoverage
FragmentProcessor())); | 341 arfps.addCoverageFragmentProcessor(sk_ref_sp(appliedClip.clipCoverageFra
gmentProcessor())); |
| 342 } |
| 343 |
| 344 if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()
) { |
| 345 if (!fResourceProvider->attachStencilAttachment(drawContext->accessRende
rTarget())) { |
| 346 SkDebugf("ERROR creating stencil attachment. Draw skipped.\n"); |
| 347 return; |
| 348 } |
| 353 } | 349 } |
| 354 | 350 |
| 355 GrPipeline::CreateArgs args; | 351 GrPipeline::CreateArgs args; |
| 356 args.fPipelineBuilder = &pipelineBuilder; | 352 args.fPipelineBuilder = &pipelineBuilder; |
| 357 args.fDrawContext = drawContext; | 353 args.fDrawContext = drawContext; |
| 358 args.fCaps = this->caps(); | 354 args.fCaps = this->caps(); |
| 359 args.fScissor = &appliedClip.scissorState(); | |
| 360 args.fHasStencilClip = appliedClip.hasStencilClip(); | |
| 361 if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()
) { | |
| 362 if (!fResourceProvider->attachStencilAttachment(drawContext->accessRende
rTarget())) { | |
| 363 SkDebugf("ERROR creating stencil attachment. Draw skipped.\n"); | |
| 364 return; | |
| 365 } | |
| 366 } | |
| 367 batch->getPipelineOptimizations(&args.fOpts); | 355 batch->getPipelineOptimizations(&args.fOpts); |
| 368 GrScissorState finalScissor; | |
| 369 if (args.fOpts.fOverrides.fUsePLSDstRead || fClipBatchToBounds) { | 356 if (args.fOpts.fOverrides.fUsePLSDstRead || fClipBatchToBounds) { |
| 370 GrGLIRect viewport; | 357 GrGLIRect viewport; |
| 371 viewport.fLeft = 0; | 358 viewport.fLeft = 0; |
| 372 viewport.fBottom = 0; | 359 viewport.fBottom = 0; |
| 373 viewport.fWidth = drawContext->width(); | 360 viewport.fWidth = drawContext->width(); |
| 374 viewport.fHeight = drawContext->height(); | 361 viewport.fHeight = drawContext->height(); |
| 375 SkIRect ibounds; | 362 SkIRect ibounds; |
| 376 ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewpo
rt.fLeft, | 363 ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewpo
rt.fLeft, |
| 377 viewport.fWidth); | 364 viewport.fWidth); |
| 378 ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport
.fBottom, | 365 ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport
.fBottom, |
| 379 viewport.fHeight); | 366 viewport.fHeight); |
| 380 ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewp
ort.fLeft, | 367 ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewp
ort.fLeft, |
| 381 viewport.fWidth); | 368 viewport.fWidth); |
| 382 ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), vie
wport.fBottom, | 369 ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), vie
wport.fBottom, |
| 383 viewport.fHeight); | 370 viewport.fHeight); |
| 384 if (appliedClip.scissorState().enabled()) { | 371 if (!appliedClip.addScissor(ibounds)) { |
| 385 const SkIRect& scissorRect = appliedClip.scissorState().rect(); | 372 return; |
| 386 if (!ibounds.intersect(scissorRect)) { | |
| 387 return; | |
| 388 } | |
| 389 } | 373 } |
| 390 finalScissor.set(ibounds); | |
| 391 args.fScissor = &finalScissor; | |
| 392 } | 374 } |
| 393 args.fOpts.fColorPOI.completeCalculations( | 375 args.fOpts.fColorPOI.completeCalculations( |
| 394 sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessor
s.begin()), | 376 sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessor
s.begin()), |
| 395 pipelineBuilder.numColorFragmentProcessors()); | 377 pipelineBuilder.numColorFragmentProcessors()); |
| 396 args.fOpts.fCoveragePOI.completeCalculations( | 378 args.fOpts.fCoveragePOI.completeCalculations( |
| 397 sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProces
sors.begin()), | 379 sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProces
sors.begin()), |
| 398 pipelineBuilder.numCoverageFragmentProcessors()); | 380 pipelineBuilder.numCoverageFragmentProcessors()); |
| 381 args.fScissor = &appliedClip.scissorState(); |
| 382 args.fHasStencilClip = appliedClip.hasStencilClip(); |
| 399 if (!this->setupDstReadIfNecessary(pipelineBuilder, drawContext->accessRende
rTarget(), | 383 if (!this->setupDstReadIfNecessary(pipelineBuilder, drawContext->accessRende
rTarget(), |
| 400 clip, args.fOpts, | 384 clip, args.fOpts, |
| 401 &args.fDstTexture, batch->bounds())) { | 385 &args.fDstTexture, batch->bounds())) { |
| 402 return; | 386 return; |
| 403 } | 387 } |
| 404 | 388 |
| 405 if (!batch->installPipeline(args)) { | 389 if (!batch->installPipeline(args)) { |
| 406 return; | 390 return; |
| 407 } | 391 } |
| 408 | 392 |
| 409 #ifdef ENABLE_MDB | 393 #ifdef ENABLE_MDB |
| 410 SkASSERT(fRenderTarget); | 394 SkASSERT(fRenderTarget); |
| 411 batch->pipeline()->addDependenciesTo(fRenderTarget); | 395 batch->pipeline()->addDependenciesTo(fRenderTarget); |
| 412 #endif | 396 #endif |
| 413 SkRect clippedBounds; | 397 this->recordBatch(batch, appliedClip.clippedDrawBounds()); |
| 414 SkAssertResult(intersect(&clippedBounds, bounds, appliedClip.deviceBounds())
); | |
| 415 this->recordBatch(batch, clippedBounds); | |
| 416 } | 398 } |
| 417 | 399 |
| 418 void GrDrawTarget::stencilPath(GrDrawContext* drawContext, | 400 void GrDrawTarget::stencilPath(GrDrawContext* drawContext, |
| 419 const GrClip& clip, | 401 const GrClip& clip, |
| 420 bool useHWAA, | 402 bool useHWAA, |
| 421 const SkMatrix& viewMatrix, | 403 const SkMatrix& viewMatrix, |
| 422 const GrPath* path) { | 404 const GrPath* path) { |
| 423 // TODO: extract portions of checkDraw that are relevant to path stenciling. | 405 // TODO: extract portions of checkDraw that are relevant to path stenciling. |
| 424 SkASSERT(path); | 406 SkASSERT(path); |
| 425 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); | 407 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); |
| 426 | 408 |
| 409 // FIXME: Use path bounds instead of this WAR once |
| 410 // https://bugs.chromium.org/p/skia/issues/detail?id=5640 is resolved. |
| 411 SkRect bounds = SkRect::MakeIWH(drawContext->width(), drawContext->height())
; |
| 412 |
| 427 // Setup clip | 413 // Setup clip |
| 428 GrAppliedClip appliedClip; | 414 GrAppliedClip appliedClip(bounds); |
| 429 if (!clip.apply(fContext, drawContext, nullptr, useHWAA, true, &appliedClip)
) { | 415 if (!clip.apply(fContext, drawContext, useHWAA, true, &appliedClip)) { |
| 430 return; | 416 return; |
| 431 } | 417 } |
| 432 // TODO: respect fClipBatchToBounds if we ever start computing bounds here. | 418 // TODO: respect fClipBatchToBounds if we ever start computing bounds here. |
| 433 | 419 |
| 434 // Coverage AA does not make sense when rendering to the stencil buffer. The
caller should never | 420 // Coverage AA does not make sense when rendering to the stencil buffer. The
caller should never |
| 435 // attempt this in a situation that would require coverage AA. | 421 // attempt this in a situation that would require coverage AA. |
| 436 SkASSERT(!appliedClip.getClipCoverageFragmentProcessor()); | 422 SkASSERT(!appliedClip.clipCoverageFragmentProcessor()); |
| 437 | 423 |
| 438 GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAtt
achment( | 424 GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAtt
achment( |
| 439 drawContext->accessRenderTarget(
)); | 425 drawContext->accessRenderTarget(
)); |
| 440 if (!stencilAttachment) { | 426 if (!stencilAttachment) { |
| 441 SkDebugf("ERROR creating stencil attachment. Draw skipped.\n"); | 427 SkDebugf("ERROR creating stencil attachment. Draw skipped.\n"); |
| 442 return; | 428 return; |
| 443 } | 429 } |
| 444 | 430 |
| 445 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, | 431 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, |
| 446 useHWAA, | 432 useHWAA, |
| 447 path->getFillType(), | 433 path->getFillType(), |
| 448 appliedClip.hasStencilClip(), | 434 appliedClip.hasStencilClip(), |
| 449 stencilAttachment->bits(), | 435 stencilAttachment->bits(), |
| 450 appliedClip.scissorState(), | 436 appliedClip.scissorState(), |
| 451 drawContext->accessRenderTarget(
), | 437 drawContext->accessRenderTarget(
), |
| 452 path); | 438 path); |
| 453 this->recordBatch(batch, appliedClip.deviceBounds()); | 439 this->recordBatch(batch, appliedClip.clippedDrawBounds()); |
| 454 batch->unref(); | 440 batch->unref(); |
| 455 } | 441 } |
| 456 | 442 |
| 457 void GrDrawTarget::addBatch(sk_sp<GrBatch> batch) { | 443 void GrDrawTarget::addBatch(sk_sp<GrBatch> batch) { |
| 458 this->recordBatch(batch.get(), batch->bounds()); | 444 this->recordBatch(batch.get(), batch->bounds()); |
| 459 } | 445 } |
| 460 | 446 |
| 461 void GrDrawTarget::fullClear(GrRenderTarget* renderTarget, GrColor color) { | 447 void GrDrawTarget::fullClear(GrRenderTarget* renderTarget, GrColor color) { |
| 462 // Currently this just inserts or updates the last clear batch. However, onc
e in MDB this can | 448 // Currently this just inserts or updates the last clear batch. However, onc
e in MDB this can |
| 463 // remove all the previously recorded batches and change the load op to clea
r with supplied | 449 // remove all the previously recorded batches and change the load op to clea
r with supplied |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 } | 611 } |
| 626 } | 612 } |
| 627 | 613 |
| 628 /////////////////////////////////////////////////////////////////////////////// | 614 /////////////////////////////////////////////////////////////////////////////// |
| 629 | 615 |
| 630 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { | 616 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { |
| 631 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); | 617 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); |
| 632 this->recordBatch(batch, batch->bounds()); | 618 this->recordBatch(batch, batch->bounds()); |
| 633 batch->unref(); | 619 batch->unref(); |
| 634 } | 620 } |
| OLD | NEW |