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