| 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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 this->drawRect(clip, *paint, viewMatrix, r); | 220 this->drawRect(clip, *paint, viewMatrix, r); |
| 221 } else { | 221 } else { |
| 222 SkMatrix localMatrix; | 222 SkMatrix localMatrix; |
| 223 if (!viewMatrix.invert(&localMatrix)) { | 223 if (!viewMatrix.invert(&localMatrix)) { |
| 224 SkDebugf("Could not invert matrix\n"); | 224 SkDebugf("Could not invert matrix\n"); |
| 225 return; | 225 return; |
| 226 } | 226 } |
| 227 | 227 |
| 228 AutoCheckFlush acf(fDrawingManager); | 228 AutoCheckFlush acf(fDrawingManager); |
| 229 | 229 |
| 230 GrPipelineBuilder pipelineBuilder(*paint, fRenderTarget, clip); |
| 230 SkAutoTUnref<GrDrawBatch> batch( | 231 SkAutoTUnref<GrDrawBatch> batch( |
| 231 GrRectBatchFactory::CreateNonAAFill(paint->getColor(), SkMatrix:
:I(), r, nullptr, | 232 GrRectBatchFactory::CreateNonAAFill(paint->getColor(), SkMatrix:
:I(), r, nullptr, |
| 232 &localMatrix)); | 233 &localMatrix)); |
| 233 GrPipelineBuilder pipelineBuilder(*paint, fRenderTarget, clip); | |
| 234 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 234 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 235 } | 235 } |
| 236 } | 236 } |
| 237 | 237 |
| 238 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po
int) { | 238 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po
int) { |
| 239 return point.fX >= rect.fLeft && point.fX <= rect.fRight && | 239 return point.fX >= rect.fLeft && point.fX <= rect.fRight && |
| 240 point.fY >= rect.fTop && point.fY <= rect.fBottom; | 240 point.fY >= rect.fTop && point.fY <= rect.fBottom; |
| 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) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 256 ASSERT_SINGLE_OWNER | 256 ASSERT_SINGLE_OWNER |
| 257 RETURN_IF_ABANDONED | 257 RETURN_IF_ABANDONED |
| 258 SkDEBUGCODE(this->validate();) | 258 SkDEBUGCODE(this->validate();) |
| 259 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect"); | 259 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect"); |
| 260 | 260 |
| 261 // Dashing should've been devolved to a path in SkGpuDevice | 261 // Dashing should've been devolved to a path in SkGpuDevice |
| 262 SkASSERT(!strokeInfo || !strokeInfo->isDashed()); | 262 SkASSERT(!strokeInfo || !strokeInfo->isDashed()); |
| 263 | 263 |
| 264 AutoCheckFlush acf(fDrawingManager); | 264 AutoCheckFlush acf(fDrawingManager); |
| 265 | 265 |
| 266 SkScalar width = !strokeInfo ? -1 : strokeInfo->getWidth(); | 266 SkScalar width = nullptr == strokeInfo ? -1 : strokeInfo->getWidth(); |
| 267 | 267 |
| 268 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking | 268 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking |
| 269 // cases where the RT is fully inside a stroke. | 269 // cases where the RT is fully inside a stroke. |
| 270 if (width < 0) { | 270 if (width < 0) { |
| 271 SkRect rtRect; | 271 SkRect rtRect; |
| 272 fRenderTarget->getBoundsRect(&rtRect); | 272 fRenderTarget->getBoundsRect(&rtRect); |
| 273 SkRect clipSpaceRTRect = rtRect; | 273 SkRect clipSpaceRTRect = rtRect; |
| 274 bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType(); | 274 bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType(); |
| 275 if (checkClip) { | 275 if (checkClip) { |
| 276 clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX), | 276 clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 292 // Will it blend? | 292 // Will it blend? |
| 293 GrColor clearColor; | 293 GrColor clearColor; |
| 294 if (paint.isConstantBlendedColor(&clearColor)) { | 294 if (paint.isConstantBlendedColor(&clearColor)) { |
| 295 this->getDrawTarget()->clear(nullptr, clearColor, true, fRen
derTarget); | 295 this->getDrawTarget()->clear(nullptr, clearColor, true, fRen
derTarget); |
| 296 return; | 296 return; |
| 297 } | 297 } |
| 298 } | 298 } |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 | 301 |
| 302 bool snapToPixelCenters = false; | 302 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 303 GrColor color = paint.getColor(); |
| 304 |
| 303 SkAutoTUnref<GrDrawBatch> batch; | 305 SkAutoTUnref<GrDrawBatch> batch; |
| 304 if (should_apply_coverage_aa(paint, fRenderTarget)) { | 306 if (should_apply_coverage_aa(paint, fRenderTarget)) { |
| 305 if (width >= 0) { | 307 if (width >= 0) { |
| 306 // The stroke path needs the rect to remain axis aligned (no rotatio
n or skew). | 308 // The stroke path needs the rect to remain axis aligned (no rotatio
n or skew). |
| 307 if (viewMatrix.rectStaysRect()) { | 309 if (viewMatrix.rectStaysRect()) { |
| 308 batch.reset(GrRectBatchFactory::CreateAAStroke(paint.getColor(),
viewMatrix, rect, | 310 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix
, rect, |
| 309 *strokeInfo)); | 311 *strokeInfo)); |
| 310 } | 312 } |
| 311 } else { | 313 } else { |
| 312 // The fill path can handle rotation but not skew. | 314 // The fill path can handle rotation but not skew. |
| 313 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { | 315 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
| 314 SkRect devBoundRect; | 316 SkRect devBoundRect; |
| 315 viewMatrix.mapRect(&devBoundRect, rect); | 317 viewMatrix.mapRect(&devBoundRect, rect); |
| 316 batch.reset(GrRectBatchFactory::CreateAAFill(paint.getColor(), v
iewMatrix, rect, | 318 batch.reset(GrRectBatchFactory::CreateAAFill(color, viewMatrix,
rect, |
| 317 devBoundRect)); | 319 devBoundRect)); |
| 318 } | 320 } |
| 319 } | 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 } |
| 320 } else if (width >= 0) { | 330 } else if (width >= 0) { |
| 321 // Non-AA hairlines are snapped to pixel centers to make which pixels ar
e hit deterministic | 331 // Non-AA hairlines are snapped to pixel centers to make which pixels ar
e hit deterministic |
| 322 snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultisample
d()); | 332 bool snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultis
ampled()); |
| 323 batch.reset(GrRectBatchFactory::CreateNonAAStroke(paint.getColor(), view
Matrix, rect, | 333 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rec
t, width, |
| 324 width, snapToPixelCent
ers)); | 334 snapToPixelCenters)); |
| 325 | 335 |
| 326 // Depending on sub-pixel coordinates and the particular GPU, we may los
e a corner of | 336 // Depending on sub-pixel coordinates and the particular GPU, we may los
e a corner of |
| 327 // hairline rects. We jam all the vertices to pixel centers to avoid thi
s, but not when | 337 // hairline rects. We jam all the vertices to pixel centers to avoid thi
s, but not when MSAA |
| 328 // MSAA is enabled because it can cause ugly artifacts. | 338 // is enabled because it can cause ugly artifacts. |
| 339 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_
Flag, |
| 340 snapToPixelCenters); |
| 329 } else { | 341 } else { |
| 330 // filled BW rect | 342 // filled BW rect |
| 331 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rect, | 343 batch.reset(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
nullptr, nullptr)); |
| 332 nullptr, nullptr)); | |
| 333 } | 344 } |
| 334 | 345 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 335 if (batch) { | |
| 336 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 337 | |
| 338 if (snapToPixelCenters) { | |
| 339 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCent
ers_Flag, | |
| 340 snapToPixelCenters); | |
| 341 } | |
| 342 | |
| 343 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | |
| 344 return; | |
| 345 } | |
| 346 | |
| 347 SkPath path; | |
| 348 path.setIsVolatile(true); | |
| 349 path.addRect(rect); | |
| 350 this->internalDrawPath(clip, paint, viewMatrix, path, | |
| 351 strokeInfo ? *strokeInfo : GrStrokeInfo::FillInfo()); | |
| 352 } | 346 } |
| 353 | 347 |
| 354 void GrDrawContext::fillRectToRect(const GrClip& clip, | 348 void GrDrawContext::fillRectToRect(const GrClip& clip, |
| 355 const GrPaint& paint, | 349 const GrPaint& paint, |
| 356 const SkMatrix& viewMatrix, | 350 const SkMatrix& viewMatrix, |
| 357 const SkRect& rectToDraw, | 351 const SkRect& rectToDraw, |
| 358 const SkRect& localRect) { | 352 const SkRect& localRect) { |
| 359 ASSERT_SINGLE_OWNER | 353 ASSERT_SINGLE_OWNER |
| 360 RETURN_IF_ABANDONED | 354 RETURN_IF_ABANDONED |
| 361 SkDEBUGCODE(this->validate();) | 355 SkDEBUGCODE(this->validate();) |
| 362 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect"); | 356 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect"); |
| 363 | 357 |
| 364 AutoCheckFlush acf(fDrawingManager); | 358 AutoCheckFlush acf(fDrawingManager); |
| 365 | 359 |
| 360 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 366 SkAutoTUnref<GrDrawBatch> batch; | 361 SkAutoTUnref<GrDrawBatch> batch; |
| 367 if (should_apply_coverage_aa(paint, fRenderTarget) && | 362 if (should_apply_coverage_aa(paint, fRenderTarget) && |
| 368 view_matrix_ok_for_aa_fill_rect(viewMatrix)) { | 363 view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
| 369 batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), vie
wMatrix, rectToDraw, | 364 batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), vie
wMatrix, rectToDraw, |
| 370 localRect)); | 365 localRect)); |
| 371 } else { | 366 } else { |
| 372 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rectToDraw, | 367 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rectToDraw, |
| 373 &localRect, nullptr)); | 368 &localRect, nullptr)); |
| 374 } | 369 } |
| 375 | 370 |
| 376 if (batch) { | 371 if (batch) { |
| 377 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 378 this->drawBatch(&pipelineBuilder, batch); | 372 this->drawBatch(&pipelineBuilder, batch); |
| 379 } | 373 } |
| 380 } | 374 } |
| 381 | 375 |
| 382 void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip, | 376 void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip, |
| 383 const GrPaint& paint, | 377 const GrPaint& paint, |
| 384 const SkMatrix& viewMatrix, | 378 const SkMatrix& viewMatrix, |
| 385 const SkRect& rectToDraw, | 379 const SkRect& rectToDraw, |
| 386 const SkMatrix& localMatrix) { | 380 const SkMatrix& localMatrix) { |
| 387 ASSERT_SINGLE_OWNER | 381 ASSERT_SINGLE_OWNER |
| 388 RETURN_IF_ABANDONED | 382 RETURN_IF_ABANDONED |
| 389 SkDEBUGCODE(this->validate();) | 383 SkDEBUGCODE(this->validate();) |
| 390 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectWithLocalMatr
ix"); | 384 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectWithLocalMatr
ix"); |
| 391 | 385 |
| 392 AutoCheckFlush acf(fDrawingManager); | 386 AutoCheckFlush acf(fDrawingManager); |
| 393 | 387 |
| 388 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 389 |
| 394 SkAutoTUnref<GrDrawBatch> batch; | 390 SkAutoTUnref<GrDrawBatch> batch; |
| 395 if (should_apply_coverage_aa(paint, fRenderTarget) && | 391 if (should_apply_coverage_aa(paint, fRenderTarget) && |
| 396 view_matrix_ok_for_aa_fill_rect(viewMatrix)) { | 392 view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
| 397 batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, loca
lMatrix, | 393 batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, loca
lMatrix, |
| 398 rectToDraw)); | 394 rectToDraw)); |
| 399 } else { | 395 } else { |
| 400 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rectToDraw, | 396 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rectToDraw, |
| 401 nullptr, &localMatrix)); | 397 nullptr, &localMatrix)); |
| 402 } | 398 } |
| 403 | |
| 404 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 405 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 399 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 406 } | 400 } |
| 407 | 401 |
| 408 void GrDrawContext::drawVertices(const GrClip& clip, | 402 void GrDrawContext::drawVertices(const GrClip& clip, |
| 409 const GrPaint& paint, | 403 const GrPaint& paint, |
| 410 const SkMatrix& viewMatrix, | 404 const SkMatrix& viewMatrix, |
| 411 GrPrimitiveType primitiveType, | 405 GrPrimitiveType primitiveType, |
| 412 int vertexCount, | 406 int vertexCount, |
| 413 const SkPoint positions[], | 407 const SkPoint positions[], |
| 414 const SkPoint texCoords[], | 408 const SkPoint texCoords[], |
| 415 const GrColor colors[], | 409 const GrColor colors[], |
| 416 const uint16_t indices[], | 410 const uint16_t indices[], |
| 417 int indexCount) { | 411 int indexCount) { |
| 418 ASSERT_SINGLE_OWNER | 412 ASSERT_SINGLE_OWNER |
| 419 RETURN_IF_ABANDONED | 413 RETURN_IF_ABANDONED |
| 420 SkDEBUGCODE(this->validate();) | 414 SkDEBUGCODE(this->validate();) |
| 421 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawVertices"); | 415 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawVertices"); |
| 422 | 416 |
| 423 AutoCheckFlush acf(fDrawingManager); | 417 AutoCheckFlush acf(fDrawingManager); |
| 424 | 418 |
| 419 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 420 |
| 425 // TODO clients should give us bounds | 421 // TODO clients should give us bounds |
| 426 SkRect bounds; | 422 SkRect bounds; |
| 427 if (!bounds.setBoundsCheck(positions, vertexCount)) { | 423 if (!bounds.setBoundsCheck(positions, vertexCount)) { |
| 428 SkDebugf("drawVertices call empty bounds\n"); | 424 SkDebugf("drawVertices call empty bounds\n"); |
| 429 return; | 425 return; |
| 430 } | 426 } |
| 431 | 427 |
| 432 viewMatrix.mapRect(&bounds); | 428 viewMatrix.mapRect(&bounds); |
| 433 | 429 |
| 434 // If we don't have AA then we outset for a half pixel in each direction to
account for | 430 // If we don't have AA then we outset for a half pixel in each direction to
account for |
| 435 // snapping. We also do this for the "hair" primitive types: lines and point
s since they have | 431 // snapping. We also do this for the "hair" primitive types: lines and point
s since they have |
| 436 // a 1 pixel thickness in device space. | 432 // a 1 pixel thickness in device space. |
| 437 if (!paint.isAntiAlias() || GrIsPrimTypeLines(primitiveType) || | 433 if (!paint.isAntiAlias() || GrIsPrimTypeLines(primitiveType) || |
| 438 kPoints_GrPrimitiveType == primitiveType) { | 434 kPoints_GrPrimitiveType == primitiveType) { |
| 439 bounds.outset(0.5f, 0.5f); | 435 bounds.outset(0.5f, 0.5f); |
| 440 } | 436 } |
| 441 | 437 |
| 442 GrDrawVerticesBatch::Geometry geometry; | 438 GrDrawVerticesBatch::Geometry geometry; |
| 443 geometry.fColor = paint.getColor(); | 439 geometry.fColor = paint.getColor(); |
| 444 SkAutoTUnref<GrDrawBatch> batch(GrDrawVerticesBatch::Create(geometry, primit
iveType, viewMatrix, | 440 SkAutoTUnref<GrDrawBatch> batch(GrDrawVerticesBatch::Create(geometry, primit
iveType, viewMatrix, |
| 445 positions, verte
xCount, indices, | 441 positions, verte
xCount, indices, |
| 446 indexCount, colo
rs, texCoords, | 442 indexCount, colo
rs, texCoords, |
| 447 bounds)); | 443 bounds)); |
| 448 | 444 |
| 449 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 450 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 445 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 451 } | 446 } |
| 452 | 447 |
| 453 /////////////////////////////////////////////////////////////////////////////// | 448 /////////////////////////////////////////////////////////////////////////////// |
| 454 | 449 |
| 455 void GrDrawContext::drawAtlas(const GrClip& clip, | 450 void GrDrawContext::drawAtlas(const GrClip& clip, |
| 456 const GrPaint& paint, | 451 const GrPaint& paint, |
| 457 const SkMatrix& viewMatrix, | 452 const SkMatrix& viewMatrix, |
| 458 int spriteCount, | 453 int spriteCount, |
| 459 const SkRSXform xform[], | 454 const SkRSXform xform[], |
| 460 const SkRect texRect[], | 455 const SkRect texRect[], |
| 461 const SkColor colors[]) { | 456 const SkColor colors[]) { |
| 462 ASSERT_SINGLE_OWNER | 457 ASSERT_SINGLE_OWNER |
| 463 RETURN_IF_ABANDONED | 458 RETURN_IF_ABANDONED |
| 464 SkDEBUGCODE(this->validate();) | 459 SkDEBUGCODE(this->validate();) |
| 465 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawAtlas"); | 460 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawAtlas"); |
| 466 | 461 |
| 467 AutoCheckFlush acf(fDrawingManager); | 462 AutoCheckFlush acf(fDrawingManager); |
| 468 | 463 |
| 464 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 465 |
| 469 GrDrawAtlasBatch::Geometry geometry; | 466 GrDrawAtlasBatch::Geometry geometry; |
| 470 geometry.fColor = paint.getColor(); | 467 geometry.fColor = paint.getColor(); |
| 471 SkAutoTUnref<GrDrawBatch> batch(GrDrawAtlasBatch::Create(geometry, viewMatri
x, spriteCount, | 468 SkAutoTUnref<GrDrawBatch> batch(GrDrawAtlasBatch::Create(geometry, viewMatri
x, spriteCount, |
| 472 xform, texRect, col
ors)); | 469 xform, texRect, col
ors)); |
| 473 | 470 |
| 474 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 475 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 471 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 476 } | 472 } |
| 477 | 473 |
| 478 /////////////////////////////////////////////////////////////////////////////// | 474 /////////////////////////////////////////////////////////////////////////////// |
| 479 | 475 |
| 480 void GrDrawContext::drawRRect(const GrClip& clip, | 476 void GrDrawContext::drawRRect(const GrClip& clip, |
| 481 const GrPaint& paint, | 477 const GrPaint& paint, |
| 482 const SkMatrix& viewMatrix, | 478 const SkMatrix& viewMatrix, |
| 483 const SkRRect& rrect, | 479 const SkRRect& rrect, |
| 484 const GrStrokeInfo& strokeInfo) { | 480 const GrStrokeInfo& strokeInfo) { |
| 485 ASSERT_SINGLE_OWNER | 481 ASSERT_SINGLE_OWNER |
| 486 RETURN_IF_ABANDONED | 482 RETURN_IF_ABANDONED |
| 487 SkDEBUGCODE(this->validate();) | 483 SkDEBUGCODE(this->validate();) |
| 488 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRRect"); | 484 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRRect"); |
| 489 | 485 |
| 490 if (rrect.isEmpty()) { | 486 if (rrect.isEmpty()) { |
| 491 return; | 487 return; |
| 492 } | 488 } |
| 493 | 489 |
| 494 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice | 490 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice |
| 495 | 491 |
| 496 AutoCheckFlush acf(fDrawingManager); | 492 AutoCheckFlush acf(fDrawingManager); |
| 497 | 493 |
| 494 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 495 GrColor color = paint.getColor(); |
| 496 |
| 498 if (should_apply_coverage_aa(paint, fRenderTarget)) { | 497 if (should_apply_coverage_aa(paint, fRenderTarget)) { |
| 499 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); | 498 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
| 500 | 499 |
| 501 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(paint.g
etColor(), | 500 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(color, |
| 502 viewMat
rix, | 501 viewMat
rix, |
| 503 rrect, | 502 rrect, |
| 504 strokeI
nfo, | 503 strokeI
nfo, |
| 505 shaderC
aps)); | 504 shaderC
aps)); |
| 506 if (batch) { | 505 if (batch) { |
| 507 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 508 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 506 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 509 return; | 507 return; |
| 510 } | 508 } |
| 511 } | 509 } |
| 512 | 510 |
| 513 SkPath path; | 511 SkPath path; |
| 514 path.setIsVolatile(true); | 512 path.setIsVolatile(true); |
| 515 path.addRRect(rrect); | 513 path.addRRect(rrect); |
| 516 this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); | 514 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, |
| 515 paint.isAntiAlias(), path, strokeInfo); |
| 517 } | 516 } |
| 518 | 517 |
| 519 /////////////////////////////////////////////////////////////////////////////// | 518 /////////////////////////////////////////////////////////////////////////////// |
| 520 | 519 |
| 521 void GrDrawContext::drawOval(const GrClip& clip, | 520 void GrDrawContext::drawOval(const GrClip& clip, |
| 522 const GrPaint& paint, | 521 const GrPaint& paint, |
| 523 const SkMatrix& viewMatrix, | 522 const SkMatrix& viewMatrix, |
| 524 const SkRect& oval, | 523 const SkRect& oval, |
| 525 const GrStrokeInfo& strokeInfo) { | 524 const GrStrokeInfo& strokeInfo) { |
| 526 ASSERT_SINGLE_OWNER | 525 ASSERT_SINGLE_OWNER |
| 527 RETURN_IF_ABANDONED | 526 RETURN_IF_ABANDONED |
| 528 SkDEBUGCODE(this->validate();) | 527 SkDEBUGCODE(this->validate();) |
| 529 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawOval"); | 528 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawOval"); |
| 530 | 529 |
| 531 if (oval.isEmpty()) { | 530 if (oval.isEmpty()) { |
| 532 return; | 531 return; |
| 533 } | 532 } |
| 534 | 533 |
| 535 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice | 534 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice |
| 536 | 535 |
| 537 AutoCheckFlush acf(fDrawingManager); | 536 AutoCheckFlush acf(fDrawingManager); |
| 538 | 537 |
| 538 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 539 GrColor color = paint.getColor(); |
| 540 |
| 539 if (should_apply_coverage_aa(paint, fRenderTarget)) { | 541 if (should_apply_coverage_aa(paint, fRenderTarget)) { |
| 540 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); | 542 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
| 541 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.ge
tColor(), | 543 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(color, |
| 542 viewMatr
ix, | 544 viewMatr
ix, |
| 543 oval, | 545 oval, |
| 544 strokeIn
fo, | 546 strokeIn
fo, |
| 545 shaderCa
ps)); | 547 shaderCa
ps)); |
| 546 if (batch) { | 548 if (batch) { |
| 547 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 548 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 549 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 549 return; | 550 return; |
| 550 } | 551 } |
| 551 } | 552 } |
| 552 | 553 |
| 553 SkPath path; | 554 SkPath path; |
| 554 path.setIsVolatile(true); | 555 path.setIsVolatile(true); |
| 555 path.addOval(oval); | 556 path.addOval(oval); |
| 556 this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); | 557 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, |
| 558 paint.isAntiAlias(), path, strokeInfo); |
| 557 } | 559 } |
| 558 | 560 |
| 559 void GrDrawContext::drawImageNine(const GrClip& clip, | 561 void GrDrawContext::drawImageNine(const GrClip& clip, |
| 560 const GrPaint& paint, | 562 const GrPaint& paint, |
| 561 const SkMatrix& viewMatrix, | 563 const SkMatrix& viewMatrix, |
| 562 int imageWidth, | 564 int imageWidth, |
| 563 int imageHeight, | 565 int imageHeight, |
| 564 const SkIRect& center, | 566 const SkIRect& center, |
| 565 const SkRect& dst) { | 567 const SkRect& dst) { |
| 566 ASSERT_SINGLE_OWNER | 568 ASSERT_SINGLE_OWNER |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 SkDEBUGCODE(this->validate();) | 666 SkDEBUGCODE(this->validate();) |
| 665 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath"); | 667 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath"); |
| 666 | 668 |
| 667 if (path.isEmpty()) { | 669 if (path.isEmpty()) { |
| 668 if (path.isInverseFillType()) { | 670 if (path.isInverseFillType()) { |
| 669 this->drawPaint(clip, paint, viewMatrix); | 671 this->drawPaint(clip, paint, viewMatrix); |
| 670 } | 672 } |
| 671 return; | 673 return; |
| 672 } | 674 } |
| 673 | 675 |
| 676 GrColor color = paint.getColor(); |
| 677 |
| 678 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. |
| 679 // Scratch textures can be recycled after they are returned to the texture |
| 680 // cache. This presents a potential hazard for buffered drawing. However, |
| 681 // the writePixels that uploads to the scratch will perform a flush so we're |
| 682 // OK. |
| 674 AutoCheckFlush acf(fDrawingManager); | 683 AutoCheckFlush acf(fDrawingManager); |
| 675 | 684 |
| 685 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 676 if (should_apply_coverage_aa(paint, fRenderTarget) && !strokeInfo.isDashed()
) { | 686 if (should_apply_coverage_aa(paint, fRenderTarget) && !strokeInfo.isDashed()
) { |
| 677 if (strokeInfo.getWidth() < 0 && !path.isConvex()) { | 687 if (strokeInfo.getWidth() < 0 && !path.isConvex()) { |
| 678 // Concave AA paths are expensive - try to avoid them for special ca
ses | 688 // Concave AA paths are expensive - try to avoid them for special ca
ses |
| 679 SkRect rects[2]; | 689 SkRect rects[2]; |
| 680 | 690 |
| 681 if (is_nested_rects(viewMatrix, path, strokeInfo, rects)) { | 691 if (is_nested_rects(viewMatrix, path, strokeInfo, rects)) { |
| 682 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFill
NestedRects( | 692 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFill
NestedRects( |
| 683 paint.getColor(), viewMatrix, rects)); | 693 color, viewMatrix, rects)); |
| 684 | |
| 685 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 686 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 694 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 687 return; | 695 return; |
| 688 } | 696 } |
| 689 } | 697 } |
| 690 SkRect ovalRect; | 698 SkRect ovalRect; |
| 691 bool isOval = path.isOval(&ovalRect); | 699 bool isOval = path.isOval(&ovalRect); |
| 692 | 700 |
| 693 if (isOval && !path.isInverseFillType()) { | 701 if (isOval && !path.isInverseFillType()) { |
| 694 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); | 702 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
| 695 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(pain
t.getColor(), | 703 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(colo
r, |
| 696 view
Matrix, | 704 view
Matrix, |
| 697 oval
Rect, | 705 oval
Rect, |
| 698 stro
keInfo, | 706 stro
keInfo, |
| 699 shad
erCaps)); | 707 shad
erCaps)); |
| 700 if (batch) { | 708 if (batch) { |
| 701 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 702 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 709 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 703 return; | 710 return; |
| 704 } | 711 } |
| 705 } | 712 } |
| 706 } | 713 } |
| 707 | 714 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, |
| 708 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. | 715 paint.isAntiAlias(), path, strokeInfo); |
| 709 // Scratch textures can be recycled after they are returned to the texture | |
| 710 // cache. This presents a potential hazard for buffered drawing. However, | |
| 711 // the writePixels that uploads to the scratch will perform a flush so we're | |
| 712 // OK. | |
| 713 this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); | |
| 714 } | 716 } |
| 715 | 717 |
| 716 void GrDrawContext::internalDrawPath(const GrClip& clip, | 718 void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder, |
| 717 const GrPaint& paint, | |
| 718 const SkMatrix& viewMatrix, | 719 const SkMatrix& viewMatrix, |
| 720 GrColor color, |
| 721 bool useAA, |
| 719 const SkPath& path, | 722 const SkPath& path, |
| 720 const GrStrokeInfo& strokeInfo) { | 723 const GrStrokeInfo& strokeInfo) { |
| 721 ASSERT_SINGLE_OWNER | 724 ASSERT_SINGLE_OWNER |
| 722 RETURN_IF_ABANDONED | 725 RETURN_IF_ABANDONED |
| 723 SkASSERT(!path.isEmpty()); | 726 SkASSERT(!path.isEmpty()); |
| 724 | 727 |
| 725 // An Assumption here is that path renderer would use some form of tweaking | 728 // An Assumption here is that path renderer would use some form of tweaking |
| 726 // the src color (either the input alpha or in the frag shader) to implement | 729 // the src color (either the input alpha or in the frag shader) to implement |
| 727 // aa. If we have some future driver-mojo path AA that can do the right | 730 // aa. If we have some future driver-mojo path AA that can do the right |
| 728 // thing WRT to the blend then we'll need some query on the PR. | 731 // thing WRT to the blend then we'll need some query on the PR. |
| 729 bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget); | 732 bool useCoverageAA = useAA && |
| 730 const bool isStencilDisabled = true; | 733 !pipelineBuilder->getRenderTarget()->isUnifiedMultisampled(); |
| 731 bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled(); | 734 bool isStencilDisabled = pipelineBuilder->getStencil().isDisabled(); |
| 735 bool isStencilBufferMSAA = pipelineBuilder->getRenderTarget()->isStencilBuff
erMultisampled(); |
| 732 | 736 |
| 733 const GrPathRendererChain::DrawType type = | 737 const GrPathRendererChain::DrawType type = |
| 734 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType | 738 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType |
| 735 : GrPathRendererChain::kColor_DrawType; | 739 : GrPathRendererChain::kColor_DrawType; |
| 736 | 740 |
| 737 const SkPath* pathPtr = &path; | 741 const SkPath* pathPtr = &path; |
| 738 SkTLazy<SkPath> tmpPath; | 742 SkTLazy<SkPath> tmpPath; |
| 739 const GrStrokeInfo* strokeInfoPtr = &strokeInfo; | 743 const GrStrokeInfo* strokeInfoPtr = &strokeInfo; |
| 740 | 744 |
| 741 GrPathRenderer::CanDrawPathArgs canDrawArgs; | 745 GrPathRenderer::CanDrawPathArgs canDrawArgs; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type); | 798 pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type); |
| 795 } | 799 } |
| 796 | 800 |
| 797 if (nullptr == pr) { | 801 if (nullptr == pr) { |
| 798 #ifdef SK_DEBUG | 802 #ifdef SK_DEBUG |
| 799 SkDebugf("Unable to find path renderer compatible with path.\n"); | 803 SkDebugf("Unable to find path renderer compatible with path.\n"); |
| 800 #endif | 804 #endif |
| 801 return; | 805 return; |
| 802 } | 806 } |
| 803 | 807 |
| 804 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 805 | |
| 806 GrPathRenderer::DrawPathArgs args; | 808 GrPathRenderer::DrawPathArgs args; |
| 807 args.fTarget = this->getDrawTarget(); | 809 args.fTarget = this->getDrawTarget(); |
| 808 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider(); | 810 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider(); |
| 809 args.fPipelineBuilder = &pipelineBuilder; | 811 args.fPipelineBuilder = pipelineBuilder; |
| 810 args.fColor = paint.getColor(); | 812 args.fColor = color; |
| 811 args.fViewMatrix = &viewMatrix; | 813 args.fViewMatrix = &viewMatrix; |
| 812 args.fPath = pathPtr; | 814 args.fPath = pathPtr; |
| 813 args.fStroke = strokeInfoPtr; | 815 args.fStroke = strokeInfoPtr; |
| 814 args.fAntiAlias = useCoverageAA; | 816 args.fAntiAlias = useCoverageAA; |
| 815 pr->drawPath(args); | 817 pr->drawPath(args); |
| 816 } | 818 } |
| 817 | 819 |
| 818 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* b
atch) { | 820 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* b
atch) { |
| 819 ASSERT_SINGLE_OWNER | 821 ASSERT_SINGLE_OWNER |
| 820 RETURN_IF_ABANDONED | 822 RETURN_IF_ABANDONED |
| 821 SkDEBUGCODE(this->validate();) | 823 SkDEBUGCODE(this->validate();) |
| 822 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch"); | 824 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch"); |
| 823 | 825 |
| 824 this->getDrawTarget()->drawBatch(*pipelineBuilder, batch); | 826 this->getDrawTarget()->drawBatch(*pipelineBuilder, batch); |
| 825 } | 827 } |
| OLD | NEW |