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 |