OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrBatchTest.h" | 9 #include "GrBatchTest.h" |
10 #include "GrColor.h" | 10 #include "GrColor.h" |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 } | 241 } |
242 | 242 |
243 static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) { | 243 static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) { |
244 return viewMatrix.preservesRightAngles(); | 244 return viewMatrix.preservesRightAngles(); |
245 } | 245 } |
246 | 246 |
247 static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt) { | 247 static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt) { |
248 return paint.isAntiAlias() && !rt->isUnifiedMultisampled(); | 248 return paint.isAntiAlias() && !rt->isUnifiedMultisampled(); |
249 } | 249 } |
250 | 250 |
| 251 GrDrawBatch* GrDrawContext::getFillRectBatch(const GrPaint& paint, |
| 252 const SkMatrix& viewMatrix, |
| 253 const SkRect& rect) { |
| 254 |
| 255 GrDrawBatch* batch = nullptr; |
| 256 if (should_apply_coverage_aa(paint, fRenderTarget)) { |
| 257 // The fill path can handle rotation but not skew. |
| 258 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
| 259 SkRect devBoundRect; |
| 260 viewMatrix.mapRect(&devBoundRect, rect); |
| 261 batch = GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatri
x, |
| 262 rect, devBoundRect); |
| 263 } |
| 264 } else { |
| 265 // filled BW rect |
| 266 batch = GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix
, rect, |
| 267 nullptr, nullptr); |
| 268 } |
| 269 |
| 270 return batch; |
| 271 } |
| 272 |
251 void GrDrawContext::drawRect(const GrClip& clip, | 273 void GrDrawContext::drawRect(const GrClip& clip, |
252 const GrPaint& paint, | 274 const GrPaint& paint, |
253 const SkMatrix& viewMatrix, | 275 const SkMatrix& viewMatrix, |
254 const SkRect& rect, | 276 const SkRect& rect, |
255 const GrStrokeInfo* strokeInfo) { | 277 const GrStrokeInfo* strokeInfo) { |
256 ASSERT_SINGLE_OWNER | 278 ASSERT_SINGLE_OWNER |
257 RETURN_IF_ABANDONED | 279 RETURN_IF_ABANDONED |
258 SkDEBUGCODE(this->validate();) | 280 SkDEBUGCODE(this->validate();) |
259 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect"); | 281 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect"); |
260 | 282 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 // Will it blend? | 314 // Will it blend? |
293 GrColor clearColor; | 315 GrColor clearColor; |
294 if (paint.isConstantBlendedColor(&clearColor)) { | 316 if (paint.isConstantBlendedColor(&clearColor)) { |
295 this->getDrawTarget()->clear(nullptr, clearColor, true, fRen
derTarget); | 317 this->getDrawTarget()->clear(nullptr, clearColor, true, fRen
derTarget); |
296 return; | 318 return; |
297 } | 319 } |
298 } | 320 } |
299 } | 321 } |
300 } | 322 } |
301 | 323 |
| 324 bool snapToPixelCenters = false; |
| 325 SkAutoTUnref<GrDrawBatch> batch; |
| 326 if (width < 0) { |
| 327 batch.reset(this->getFillRectBatch(paint, viewMatrix, rect)); |
| 328 } else { |
| 329 GrColor color = paint.getColor(); |
| 330 |
| 331 if (should_apply_coverage_aa(paint, fRenderTarget)) { |
| 332 // The stroke path needs the rect to remain axis aligned (no rotatio
n or skew). |
| 333 if (viewMatrix.rectStaysRect()) { |
| 334 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix
, rect, |
| 335 *strokeInfo)); |
| 336 } |
| 337 } else { |
| 338 // Non-AA hairlines are snapped to pixel centers to make which pixel
s are hit |
| 339 // deterministic |
| 340 snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultisa
mpled()); |
| 341 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix,
rect, width, |
| 342 snapToPixelCenters
)); |
| 343 |
| 344 // Depending on sub-pixel coordinates and the particular GPU, we may
lose a corner of |
| 345 // hairline rects. We jam all the vertices to pixel centers to avoid
this, but not |
| 346 // when MSAA is enabled because it can cause ugly artifacts. |
| 347 } |
| 348 } |
| 349 |
302 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | 350 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
303 GrColor color = paint.getColor(); | 351 if (snapToPixelCenters) { |
304 | |
305 SkAutoTUnref<GrDrawBatch> batch; | |
306 if (should_apply_coverage_aa(paint, fRenderTarget)) { | |
307 if (width >= 0) { | |
308 // The stroke path needs the rect to remain axis aligned (no rotatio
n or skew). | |
309 if (viewMatrix.rectStaysRect()) { | |
310 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix
, rect, | |
311 *strokeInfo)); | |
312 } | |
313 } else { | |
314 // The fill path can handle rotation but not skew. | |
315 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { | |
316 SkRect devBoundRect; | |
317 viewMatrix.mapRect(&devBoundRect, rect); | |
318 batch.reset(GrRectBatchFactory::CreateAAFill(color, viewMatrix,
rect, | |
319 devBoundRect)); | |
320 } | |
321 } | |
322 if (!batch) { | |
323 SkPath path; | |
324 path.setIsVolatile(true); | |
325 path.addRect(rect); | |
326 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, true, pa
th, *strokeInfo); | |
327 SkASSERT(paint.isAntiAlias()); | |
328 return; | |
329 } | |
330 } else if (width >= 0) { | |
331 // Non-AA hairlines are snapped to pixel centers to make which pixels ar
e hit deterministic | |
332 bool snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultis
ampled()); | |
333 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rec
t, width, | |
334 snapToPixelCenters)); | |
335 | |
336 // Depending on sub-pixel coordinates and the particular GPU, we may los
e a corner of | |
337 // hairline rects. We jam all the vertices to pixel centers to avoid thi
s, but not when MSAA | |
338 // is enabled because it can cause ugly artifacts. | |
339 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_
Flag, | 352 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_
Flag, |
340 snapToPixelCenters); | 353 snapToPixelCenters); |
341 } else { | |
342 // filled BW rect | |
343 batch.reset(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
nullptr, nullptr)); | |
344 } | 354 } |
| 355 |
| 356 if (!batch) { |
| 357 SkPath path; |
| 358 path.setIsVolatile(true); |
| 359 path.addRect(rect); |
| 360 this->internalDrawPath(&pipelineBuilder, viewMatrix, paint.getColor(), t
rue, |
| 361 path, strokeInfo ? *strokeInfo : GrStrokeInfo::Fi
llInfo()); |
| 362 return; |
| 363 } |
| 364 |
345 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 365 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
346 } | 366 } |
347 | 367 |
| 368 bool GrDrawContext::stencilRect(const SkIRect* scissorRect, |
| 369 const GrStencilSettings& ss, |
| 370 SkRegion::Op op, |
| 371 bool invert, |
| 372 bool doAA, |
| 373 const SkMatrix& viewMatrix, |
| 374 const SkRect& rect) { |
| 375 ASSERT_SINGLE_OWNER |
| 376 RETURN_FALSE_IF_ABANDONED |
| 377 SkDEBUGCODE(this->validate();) |
| 378 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::stencilRect"); |
| 379 |
| 380 AutoCheckFlush acf(fDrawingManager); |
| 381 |
| 382 GrPaint paint; |
| 383 paint.setAntiAlias(doAA); |
| 384 paint.setCoverageSetOpXPFactory(op, invert); |
| 385 |
| 386 SkAutoTUnref<GrDrawBatch> batch(this->getFillRectBatch(paint, viewMatrix, re
ct)); |
| 387 if (batch) { |
| 388 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, GrClip::WideOpen
()); |
| 389 pipelineBuilder.setStencil(ss); |
| 390 |
| 391 this->getDrawTarget()->drawBatch(pipelineBuilder, batch, scissorRect); |
| 392 return true; |
| 393 } |
| 394 |
| 395 SkPath path; |
| 396 path.setIsVolatile(true); |
| 397 path.addRect(rect); |
| 398 return this->stencilPath(scissorRect, ss, op, invert, doAA, viewMatrix, path
); |
| 399 } |
| 400 |
348 void GrDrawContext::fillRectToRect(const GrClip& clip, | 401 void GrDrawContext::fillRectToRect(const GrClip& clip, |
349 const GrPaint& paint, | 402 const GrPaint& paint, |
350 const SkMatrix& viewMatrix, | 403 const SkMatrix& viewMatrix, |
351 const SkRect& rectToDraw, | 404 const SkRect& rectToDraw, |
352 const SkRect& localRect) { | 405 const SkRect& localRect) { |
353 ASSERT_SINGLE_OWNER | 406 ASSERT_SINGLE_OWNER |
354 RETURN_IF_ABANDONED | 407 RETURN_IF_ABANDONED |
355 SkDEBUGCODE(this->validate();) | 408 SkDEBUGCODE(this->validate();) |
356 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect"); | 409 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect"); |
357 | 410 |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 if (batch) { | 761 if (batch) { |
709 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 762 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
710 return; | 763 return; |
711 } | 764 } |
712 } | 765 } |
713 } | 766 } |
714 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, | 767 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, |
715 paint.isAntiAlias(), path, strokeInfo); | 768 paint.isAntiAlias(), path, strokeInfo); |
716 } | 769 } |
717 | 770 |
| 771 bool GrDrawContext::stencilPath(const SkIRect* scissorRect, |
| 772 const GrStencilSettings& ss, |
| 773 SkRegion::Op op, |
| 774 bool invert, |
| 775 bool doAA, |
| 776 const SkMatrix& viewMatrix, |
| 777 const SkPath& path) { |
| 778 ASSERT_SINGLE_OWNER |
| 779 RETURN_FALSE_IF_ABANDONED |
| 780 SkDEBUGCODE(this->validate();) |
| 781 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath"); |
| 782 |
| 783 if (path.isEmpty() && path.isInverseFillType()) { |
| 784 this->stencilRect(scissorRect, ss, op, invert, false, SkMatrix::I(), |
| 785 SkRect::MakeIWH(fRenderTarget->width(), fRenderTarget-
>height())); |
| 786 return true; |
| 787 } |
| 788 |
| 789 AutoCheckFlush acf(fDrawingManager); |
| 790 |
| 791 // An Assumption here is that path renderer would use some form of tweaking |
| 792 // the src color (either the input alpha or in the frag shader) to implement |
| 793 // aa. If we have some future driver-mojo path AA that can do the right |
| 794 // thing WRT to the blend then we'll need some query on the PR. |
| 795 bool useCoverageAA = doAA && !fRenderTarget->isUnifiedMultisampled(); |
| 796 bool isStencilDisabled = true; |
| 797 bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled(); |
| 798 |
| 799 const GrPathRendererChain::DrawType type = |
| 800 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType |
| 801 : GrPathRendererChain::kColor_DrawType; |
| 802 |
| 803 GrPathRenderer::CanDrawPathArgs canDrawArgs; |
| 804 canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps(
); |
| 805 canDrawArgs.fViewMatrix = &viewMatrix; |
| 806 canDrawArgs.fPath = &path; |
| 807 canDrawArgs.fStroke = &GrStrokeInfo::FillInfo(); |
| 808 canDrawArgs.fAntiAlias = useCoverageAA; |
| 809 canDrawArgs.fIsStencilDisabled = isStencilDisabled; |
| 810 canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA; |
| 811 |
| 812 // Don't allow the SW renderer |
| 813 GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, ty
pe); |
| 814 if (!pr) { |
| 815 return false; |
| 816 } |
| 817 |
| 818 GrPaint paint; |
| 819 paint.setCoverageSetOpXPFactory(op, invert); |
| 820 |
| 821 GrClip clip; |
| 822 if (scissorRect) { |
| 823 clip.setScissor(*scissorRect); |
| 824 } |
| 825 |
| 826 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 827 pipelineBuilder.setStencil(ss); |
| 828 |
| 829 GrPathRenderer::DrawPathArgs args; |
| 830 args.fTarget = this->getDrawTarget(); |
| 831 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider(); |
| 832 args.fPipelineBuilder = &pipelineBuilder; |
| 833 args.fColor = GrColor_WHITE; |
| 834 args.fViewMatrix = &viewMatrix; |
| 835 args.fPath = &path; |
| 836 args.fStroke = &GrStrokeInfo::FillInfo(); |
| 837 args.fAntiAlias = useCoverageAA; |
| 838 pr->drawPath(args); |
| 839 return true; |
| 840 } |
| 841 |
718 void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder, | 842 void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder, |
719 const SkMatrix& viewMatrix, | 843 const SkMatrix& viewMatrix, |
720 GrColor color, | 844 GrColor color, |
721 bool useAA, | 845 bool useAA, |
722 const SkPath& path, | 846 const SkPath& path, |
723 const GrStrokeInfo& strokeInfo) { | 847 const GrStrokeInfo& strokeInfo) { |
724 ASSERT_SINGLE_OWNER | 848 ASSERT_SINGLE_OWNER |
725 RETURN_IF_ABANDONED | 849 RETURN_IF_ABANDONED |
726 SkASSERT(!path.isEmpty()); | 850 SkASSERT(!path.isEmpty()); |
727 | 851 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 } | 942 } |
819 | 943 |
820 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* b
atch) { | 944 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* b
atch) { |
821 ASSERT_SINGLE_OWNER | 945 ASSERT_SINGLE_OWNER |
822 RETURN_IF_ABANDONED | 946 RETURN_IF_ABANDONED |
823 SkDEBUGCODE(this->validate();) | 947 SkDEBUGCODE(this->validate();) |
824 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch"); | 948 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch"); |
825 | 949 |
826 this->getDrawTarget()->drawBatch(*pipelineBuilder, batch); | 950 this->getDrawTarget()->drawBatch(*pipelineBuilder, batch); |
827 } | 951 } |
OLD | NEW |