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" |
11 #include "GrCaps.h" | 11 #include "GrCaps.h" |
12 #include "GrGpu.h" | 12 #include "GrGpu.h" |
13 #include "GrPath.h" | 13 #include "GrPath.h" |
14 #include "GrPipeline.h" | 14 #include "GrPipeline.h" |
15 #include "GrMemoryPool.h" | 15 #include "GrMemoryPool.h" |
16 #include "GrRenderTarget.h" | 16 #include "GrRenderTarget.h" |
17 #include "GrResourceProvider.h" | 17 #include "GrResourceProvider.h" |
18 #include "GrRenderTargetPriv.h" | 18 #include "GrRenderTargetPriv.h" |
| 19 #include "GrStencilAttachment.h" |
19 #include "GrSurfacePriv.h" | 20 #include "GrSurfacePriv.h" |
20 #include "GrTexture.h" | 21 #include "GrTexture.h" |
21 #include "gl/GrGLRenderTarget.h" | 22 #include "gl/GrGLRenderTarget.h" |
22 | 23 |
23 #include "SkStrokeRec.h" | 24 #include "SkStrokeRec.h" |
24 | 25 |
25 #include "batches/GrClearBatch.h" | 26 #include "batches/GrClearBatch.h" |
26 #include "batches/GrCopySurfaceBatch.h" | 27 #include "batches/GrCopySurfaceBatch.h" |
27 #include "batches/GrDiscardBatch.h" | 28 #include "batches/GrDiscardBatch.h" |
28 #include "batches/GrDrawBatch.h" | 29 #include "batches/GrDrawBatch.h" |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 } | 229 } |
229 | 230 |
230 void GrDrawTarget::reset() { | 231 void GrDrawTarget::reset() { |
231 fBatches.reset(); | 232 fBatches.reset(); |
232 } | 233 } |
233 | 234 |
234 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, | 235 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, |
235 GrDrawBatch* batch, | 236 GrDrawBatch* batch, |
236 const SkIRect* scissorRect) { | 237 const SkIRect* scissorRect) { |
237 // Setup clip | 238 // Setup clip |
238 GrPipelineBuilder::AutoRestoreStencil ars; | |
239 GrAppliedClip clip; | 239 GrAppliedClip clip; |
240 | 240 |
241 if (scissorRect) { | 241 if (scissorRect) { |
242 SkASSERT(GrClip::kWideOpen_ClipType == pipelineBuilder.clip().clipType()
); | 242 SkASSERT(GrClip::kWideOpen_ClipType == pipelineBuilder.clip().clipType()
); |
243 if (!fClipMaskManager->setupScissorClip(pipelineBuilder, &ars, *scissorR
ect, | 243 if (!fClipMaskManager->setupScissorClip(pipelineBuilder, *scissorRect, |
244 &batch->bounds(), &clip)) { | 244 &batch->bounds(), &clip)) { |
245 return; | 245 return; |
246 } | 246 } |
247 } else { | 247 } else { |
248 if (!fClipMaskManager->setupClipping(pipelineBuilder, &ars, &batch->boun
ds(), &clip)) { | 248 if (!fClipMaskManager->setupClipping(pipelineBuilder, &batch->bounds(),
&clip)) { |
249 return; | 249 return; |
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()
, batch)) { | 260 if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState()
, |
| 261 clip.hasStencilClip(), batch)) { |
261 return; | 262 return; |
262 } | 263 } |
263 | 264 |
264 #ifdef ENABLE_MDB | 265 #ifdef ENABLE_MDB |
265 SkASSERT(fRenderTarget); | 266 SkASSERT(fRenderTarget); |
266 batch->pipeline()->addDependenciesTo(fRenderTarget); | 267 batch->pipeline()->addDependenciesTo(fRenderTarget); |
267 #endif | 268 #endif |
268 | 269 |
269 this->recordBatch(batch); | 270 this->recordBatch(batch); |
270 } | 271 } |
271 | 272 |
272 void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType f
ill, | 273 inline static const GrUserStencilSettings& get_path_stencil_settings_for_fill( |
273 const GrStencilAttachment*
sb, | 274 GrPathRendering::FillType fill) { |
274 GrStencilSettings* outStenc
ilSettings) { | 275 static constexpr GrUserStencilSettings kWindingStencilSettings( |
275 static constexpr GrStencilSettings kWindingStencilSettings( | 276 GrUserStencilSettings::StaticInit< |
276 kIncClamp_StencilOp, | 277 0xffff, |
277 kIncClamp_StencilOp, | 278 GrUserStencilTest::kAlwaysIfInClip, |
278 kAlwaysIfInClip_StencilFunc, | 279 0xffff, |
279 0xFFFF, 0xFFFF, 0xFFFF | 280 GrUserStencilOp::kIncMaybeClamp, // TODO: Use wrap ops for NVPR. |
| 281 GrUserStencilOp::kIncMaybeClamp, |
| 282 0xffff>() |
280 ); | 283 ); |
281 | 284 |
282 static constexpr GrStencilSettings kEvenODdStencilSettings( | 285 static constexpr GrUserStencilSettings kEvenOddStencilSettings( |
283 kInvert_StencilOp, | 286 GrUserStencilSettings::StaticInit< |
284 kInvert_StencilOp, | 287 0xffff, |
285 kAlwaysIfInClip_StencilFunc, | 288 GrUserStencilTest::kAlwaysIfInClip, |
286 0xFFFF, 0xFFFF, 0xFFFF | 289 0xffff, |
| 290 GrUserStencilOp::kInvert, |
| 291 GrUserStencilOp::kInvert, |
| 292 0xffff>() |
287 ); | 293 ); |
288 | 294 |
289 switch (fill) { | 295 switch (fill) { |
290 default: | 296 default: |
291 SkFAIL("Unexpected path fill."); | 297 SkFAIL("Unexpected path fill."); |
292 case GrPathRendering::kWinding_FillType: | 298 case GrPathRendering::kWinding_FillType: |
293 *outStencilSettings = kWindingStencilSettings; | 299 return kWindingStencilSettings; |
294 break; | |
295 case GrPathRendering::kEvenOdd_FillType: | 300 case GrPathRendering::kEvenOdd_FillType: |
296 *outStencilSettings = kEvenODdStencilSettings; | 301 return kEvenOddStencilSettings; |
297 break; | |
298 } | 302 } |
299 fClipMaskManager->adjustPathStencilParams(sb, outStencilSettings); | |
300 } | 303 } |
301 | 304 |
302 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, | 305 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder, |
303 const SkMatrix& viewMatrix, | 306 const SkMatrix& viewMatrix, |
304 const GrPath* path, | 307 const GrPath* path, |
305 GrPathRendering::FillType fill) { | 308 GrPathRendering::FillType fill) { |
306 // TODO: extract portions of checkDraw that are relevant to path stenciling. | 309 // TODO: extract portions of checkDraw that are relevant to path stenciling. |
307 SkASSERT(path); | 310 SkASSERT(path); |
308 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); | 311 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); |
309 | 312 |
310 // Setup clip | 313 // Setup clip |
311 GrPipelineBuilder::AutoRestoreStencil ars; | |
312 GrAppliedClip clip; | 314 GrAppliedClip clip; |
313 if (!fClipMaskManager->setupClipping(pipelineBuilder, &ars, nullptr, &clip))
{ | 315 if (!fClipMaskManager->setupClipping(pipelineBuilder, nullptr, &clip)) { |
314 return; | 316 return; |
315 } | 317 } |
316 | 318 |
317 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | 319 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; |
318 if (clip.clipCoverageFragmentProcessor()) { | 320 if (clip.clipCoverageFragmentProcessor()) { |
319 arfps.set(&pipelineBuilder); | 321 arfps.set(&pipelineBuilder); |
320 arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor())
; | 322 arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor())
; |
321 } | 323 } |
322 | 324 |
323 // set stencil settings for path | |
324 GrStencilSettings stencilSettings; | |
325 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 325 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
326 GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt); | 326 GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAtt
achment(rt); |
327 this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings); | |
328 | 327 |
329 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, | 328 GrBatch* batch = GrStencilPathBatch::Create(viewMatrix, |
330 pipelineBuilder.isHWAntialias(), | 329 pipelineBuilder.isHWAntialias(), |
331 stencilSettings, clip.scissorSta
te(), | 330 get_path_stencil_settings_for_fi
ll(fill), |
| 331 clip.hasStencilClip(), |
| 332 stencilAttachment->bits(), |
| 333 clip.scissorState(), |
332 pipelineBuilder.getRenderTarget(
), | 334 pipelineBuilder.getRenderTarget(
), |
333 path); | 335 path); |
334 this->recordBatch(batch); | 336 this->recordBatch(batch); |
335 batch->unref(); | 337 batch->unref(); |
336 } | 338 } |
337 | 339 |
338 void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder, | 340 void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder, |
339 GrDrawPathBatchBase* batch) { | 341 GrDrawPathBatchBase* batch) { |
340 // This looks like drawBatch() but there is an added wrinkle that stencil se
ttings get inserted | 342 // This looks like drawBatch() but there is an added wrinkle that stencil se
ttings get inserted |
341 // after setting up clipping but before onDrawBatch(). TODO: Figure out a be
tter model for | 343 // after setting up clipping but before onDrawBatch(). TODO: Figure out a be
tter model for |
342 // handling stencil settings WRT interactions between pipeline(builder), cli
pmaskmanager, and | 344 // handling stencil settings WRT interactions between pipeline(builder), cli
pmaskmanager, and |
343 // batches. | 345 // batches. |
344 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); | 346 SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); |
345 | 347 |
346 GrPipelineBuilder::AutoRestoreStencil ars; | |
347 GrAppliedClip clip; | 348 GrAppliedClip clip; |
348 if (!fClipMaskManager->setupClipping(pipelineBuilder, &ars, &batch->bounds()
, &clip)) { | 349 if (!fClipMaskManager->setupClipping(pipelineBuilder, &batch->bounds(), &cli
p)) { |
349 return; | 350 return; |
350 } | 351 } |
351 | 352 |
352 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; | 353 GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; |
353 if (clip.clipCoverageFragmentProcessor()) { | 354 if (clip.clipCoverageFragmentProcessor()) { |
354 arfps.set(&pipelineBuilder); | 355 arfps.set(&pipelineBuilder); |
355 arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor())
; | 356 arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor())
; |
356 } | 357 } |
357 | 358 |
358 // Ensure the render target has a stencil buffer and get the stencil setting
s. | 359 // Ensure the render target has a stencil buffer and get the stencil setting
s. |
359 GrStencilSettings stencilSettings; | |
360 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); | 360 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); |
361 GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt); | 361 GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt); |
362 this->getPathStencilSettingsForFilltype(batch->fillType(), sb, &stencilSetti
ngs); | 362 // TODO: Move this step into GrDrawPathPath::onPrepare(). |
363 batch->setStencilSettings(stencilSettings); | 363 batch->setStencilSettings(get_path_stencil_settings_for_fill(batch->fillType
()), |
| 364 clip.hasStencilClip(), |
| 365 sb->bits()); |
364 | 366 |
365 GrPipeline::CreateArgs args; | 367 GrPipeline::CreateArgs args; |
366 if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState()
, batch)) { | 368 if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState()
, |
| 369 clip.hasStencilClip(), batch)) { |
367 return; | 370 return; |
368 } | 371 } |
369 | 372 |
370 this->recordBatch(batch); | 373 this->recordBatch(batch); |
371 } | 374 } |
372 | 375 |
373 void GrDrawTarget::clear(const SkIRect* rect, | 376 void GrDrawTarget::clear(const SkIRect* rect, |
374 GrColor color, | 377 GrColor color, |
375 bool canIgnoreRect, | 378 bool canIgnoreRect, |
376 GrRenderTarget* renderTarget) { | 379 GrRenderTarget* renderTarget) { |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 break; | 543 break; |
541 } | 544 } |
542 } | 545 } |
543 } | 546 } |
544 } | 547 } |
545 | 548 |
546 /////////////////////////////////////////////////////////////////////////////// | 549 /////////////////////////////////////////////////////////////////////////////// |
547 | 550 |
548 bool GrDrawTarget::installPipelineInDrawBatch(const GrPipelineBuilder* pipelineB
uilder, | 551 bool GrDrawTarget::installPipelineInDrawBatch(const GrPipelineBuilder* pipelineB
uilder, |
549 const GrScissorState* scissor, | 552 const GrScissorState* scissor, |
| 553 bool hasStencilClip, |
550 GrDrawBatch* batch) { | 554 GrDrawBatch* batch) { |
551 GrPipeline::CreateArgs args; | 555 GrPipeline::CreateArgs args; |
552 args.fPipelineBuilder = pipelineBuilder; | 556 args.fPipelineBuilder = pipelineBuilder; |
553 args.fCaps = this->caps(); | 557 args.fCaps = this->caps(); |
554 args.fScissor = scissor; | 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; |
555 batch->getPipelineOptimizations(&args.fOpts); | 567 batch->getPipelineOptimizations(&args.fOpts); |
556 GrScissorState finalScissor; | 568 GrScissorState finalScissor; |
557 if (args.fOpts.fOverrides.fUsePLSDstRead) { | 569 if (args.fOpts.fOverrides.fUsePLSDstRead) { |
558 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); | 570 GrRenderTarget* rt = pipelineBuilder->getRenderTarget(); |
559 GrGLIRect viewport; | 571 GrGLIRect viewport; |
560 viewport.fLeft = 0; | 572 viewport.fLeft = 0; |
561 viewport.fBottom = 0; | 573 viewport.fBottom = 0; |
562 viewport.fWidth = rt->width(); | 574 viewport.fWidth = rt->width(); |
563 viewport.fHeight = rt->height(); | 575 viewport.fHeight = rt->height(); |
564 SkIRect ibounds; | 576 SkIRect ibounds; |
(...skipping 28 matching lines...) Expand all Loading... |
593 } | 605 } |
594 | 606 |
595 return true; | 607 return true; |
596 } | 608 } |
597 | 609 |
598 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { | 610 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRend
erTarget* rt) { |
599 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); | 611 GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt); |
600 this->recordBatch(batch); | 612 this->recordBatch(batch); |
601 batch->unref(); | 613 batch->unref(); |
602 } | 614 } |
OLD | NEW |