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 |