| 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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 this->drawRect(clip, *paint, viewMatrix, r); | 222 this->drawRect(clip, *paint, viewMatrix, r); |
| 223 } else { | 223 } else { |
| 224 SkMatrix localMatrix; | 224 SkMatrix localMatrix; |
| 225 if (!viewMatrix.invert(&localMatrix)) { | 225 if (!viewMatrix.invert(&localMatrix)) { |
| 226 SkDebugf("Could not invert matrix\n"); | 226 SkDebugf("Could not invert matrix\n"); |
| 227 return; | 227 return; |
| 228 } | 228 } |
| 229 | 229 |
| 230 AutoCheckFlush acf(fDrawingManager); | 230 AutoCheckFlush acf(fDrawingManager); |
| 231 | 231 |
| 232 GrPipelineBuilder pipelineBuilder(*paint, fRenderTarget, clip); | |
| 233 SkAutoTUnref<GrDrawBatch> batch( | 232 SkAutoTUnref<GrDrawBatch> batch( |
| 234 GrRectBatchFactory::CreateNonAAFill(paint->getColor(), SkMatrix:
:I(), r, nullptr, | 233 GrRectBatchFactory::CreateNonAAFill(paint->getColor(), SkMatrix:
:I(), r, nullptr, |
| 235 &localMatrix)); | 234 &localMatrix)); |
| 235 GrPipelineBuilder pipelineBuilder(*paint, fRenderTarget, clip); |
| 236 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 236 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 237 } | 237 } |
| 238 } | 238 } |
| 239 | 239 |
| 240 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po
int) { | 240 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po
int) { |
| 241 return point.fX >= rect.fLeft && point.fX <= rect.fRight && | 241 return point.fX >= rect.fLeft && point.fX <= rect.fRight && |
| 242 point.fY >= rect.fTop && point.fY <= rect.fBottom; | 242 point.fY >= rect.fTop && point.fY <= rect.fBottom; |
| 243 } | 243 } |
| 244 | 244 |
| 245 static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) { | 245 static bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 258 ASSERT_SINGLE_OWNER | 258 ASSERT_SINGLE_OWNER |
| 259 RETURN_IF_ABANDONED | 259 RETURN_IF_ABANDONED |
| 260 SkDEBUGCODE(this->validate();) | 260 SkDEBUGCODE(this->validate();) |
| 261 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect"); | 261 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRect"); |
| 262 | 262 |
| 263 // Dashing should've been devolved to a path in SkGpuDevice | 263 // Dashing should've been devolved to a path in SkGpuDevice |
| 264 SkASSERT(!strokeInfo || !strokeInfo->isDashed()); | 264 SkASSERT(!strokeInfo || !strokeInfo->isDashed()); |
| 265 | 265 |
| 266 AutoCheckFlush acf(fDrawingManager); | 266 AutoCheckFlush acf(fDrawingManager); |
| 267 | 267 |
| 268 SkScalar width = nullptr == strokeInfo ? -1 : strokeInfo->getWidth(); | 268 SkScalar width = !strokeInfo ? -1 : strokeInfo->getWidth(); |
| 269 | 269 |
| 270 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking | 270 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking |
| 271 // cases where the RT is fully inside a stroke. | 271 // cases where the RT is fully inside a stroke. |
| 272 if (width < 0) { | 272 if (width < 0) { |
| 273 SkRect rtRect; | 273 SkRect rtRect; |
| 274 fRenderTarget->getBoundsRect(&rtRect); | 274 fRenderTarget->getBoundsRect(&rtRect); |
| 275 SkRect clipSpaceRTRect = rtRect; | 275 SkRect clipSpaceRTRect = rtRect; |
| 276 bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType(); | 276 bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType(); |
| 277 if (checkClip) { | 277 if (checkClip) { |
| 278 clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX), | 278 clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 294 // Will it blend? | 294 // Will it blend? |
| 295 GrColor clearColor; | 295 GrColor clearColor; |
| 296 if (paint.isConstantBlendedColor(&clearColor)) { | 296 if (paint.isConstantBlendedColor(&clearColor)) { |
| 297 this->getDrawTarget()->clear(nullptr, clearColor, true, fRen
derTarget); | 297 this->getDrawTarget()->clear(nullptr, clearColor, true, fRen
derTarget); |
| 298 return; | 298 return; |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 } | 301 } |
| 302 } | 302 } |
| 303 | 303 |
| 304 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | 304 bool snapToPixelCenters = false; |
| 305 GrColor color = paint.getColor(); | |
| 306 | |
| 307 SkAutoTUnref<GrDrawBatch> batch; | 305 SkAutoTUnref<GrDrawBatch> batch; |
| 308 if (should_apply_coverage_aa(paint, fRenderTarget)) { | 306 if (should_apply_coverage_aa(paint, fRenderTarget)) { |
| 309 if (width >= 0) { | 307 if (width >= 0) { |
| 310 // 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). |
| 311 if (viewMatrix.rectStaysRect()) { | 309 if (viewMatrix.rectStaysRect()) { |
| 312 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix
, rect, | 310 batch.reset(GrRectBatchFactory::CreateAAStroke(paint.getColor(),
viewMatrix, rect, |
| 313 *strokeInfo)); | 311 *strokeInfo)); |
| 314 } | 312 } |
| 315 } else { | 313 } else { |
| 316 // The fill path can handle rotation but not skew. | 314 // The fill path can handle rotation but not skew. |
| 317 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { | 315 if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
| 318 SkRect devBoundRect; | 316 SkRect devBoundRect; |
| 319 viewMatrix.mapRect(&devBoundRect, rect); | 317 viewMatrix.mapRect(&devBoundRect, rect); |
| 320 batch.reset(GrRectBatchFactory::CreateAAFill(color, viewMatrix,
rect, | 318 batch.reset(GrRectBatchFactory::CreateAAFill(paint.getColor(), v
iewMatrix, rect, |
| 321 devBoundRect)); | 319 devBoundRect)); |
| 322 } | 320 } |
| 323 } | 321 } |
| 324 if (!batch) { | |
| 325 SkPath path; | |
| 326 path.setIsVolatile(true); | |
| 327 path.addRect(rect); | |
| 328 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, true, pa
th, *strokeInfo); | |
| 329 SkASSERT(paint.isAntiAlias()); | |
| 330 return; | |
| 331 } | |
| 332 } else if (width >= 0) { | 322 } else if (width >= 0) { |
| 333 // Non-AA hairlines are snapped to pixel centers to make which pixels ar
e hit deterministic | 323 // Non-AA hairlines are snapped to pixel centers to make which pixels ar
e hit deterministic |
| 334 bool snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultis
ampled()); | 324 snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultisample
d()); |
| 335 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rec
t, width, | 325 batch.reset(GrRectBatchFactory::CreateNonAAStroke(paint.getColor(), view
Matrix, rect, |
| 336 snapToPixelCenters)); | 326 width, snapToPixelCent
ers)); |
| 337 | 327 |
| 338 // Depending on sub-pixel coordinates and the particular GPU, we may los
e a corner of | 328 // Depending on sub-pixel coordinates and the particular GPU, we may los
e a corner of |
| 339 // hairline rects. We jam all the vertices to pixel centers to avoid thi
s, but not when MSAA | 329 // hairline rects. We jam all the vertices to pixel centers to avoid thi
s, but not when |
| 340 // is enabled because it can cause ugly artifacts. | 330 // MSAA is enabled because it can cause ugly artifacts. |
| 341 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_
Flag, | |
| 342 snapToPixelCenters); | |
| 343 } else { | 331 } else { |
| 344 // filled BW rect | 332 // filled BW rect |
| 345 batch.reset(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
nullptr, nullptr)); | 333 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rect, |
| 334 nullptr, nullptr)); |
| 346 } | 335 } |
| 347 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 336 |
| 337 if (batch) { |
| 338 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 339 |
| 340 if (snapToPixelCenters) { |
| 341 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCent
ers_Flag, |
| 342 snapToPixelCenters); |
| 343 } |
| 344 |
| 345 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 346 return; |
| 347 } |
| 348 |
| 349 SkPath path; |
| 350 path.setIsVolatile(true); |
| 351 path.addRect(rect); |
| 352 this->internalDrawPath(clip, paint, viewMatrix, path, |
| 353 strokeInfo ? *strokeInfo : GrStrokeInfo::FillInfo()); |
| 348 } | 354 } |
| 349 | 355 |
| 350 void GrDrawContext::fillRectToRect(const GrClip& clip, | 356 void GrDrawContext::fillRectToRect(const GrClip& clip, |
| 351 const GrPaint& paint, | 357 const GrPaint& paint, |
| 352 const SkMatrix& viewMatrix, | 358 const SkMatrix& viewMatrix, |
| 353 const SkRect& rectToDraw, | 359 const SkRect& rectToDraw, |
| 354 const SkRect& localRect) { | 360 const SkRect& localRect) { |
| 355 ASSERT_SINGLE_OWNER | 361 ASSERT_SINGLE_OWNER |
| 356 RETURN_IF_ABANDONED | 362 RETURN_IF_ABANDONED |
| 357 SkDEBUGCODE(this->validate();) | 363 SkDEBUGCODE(this->validate();) |
| 358 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect"); | 364 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect"); |
| 359 | 365 |
| 360 AutoCheckFlush acf(fDrawingManager); | 366 AutoCheckFlush acf(fDrawingManager); |
| 361 | 367 |
| 362 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 363 SkAutoTUnref<GrDrawBatch> batch; | 368 SkAutoTUnref<GrDrawBatch> batch; |
| 364 if (should_apply_coverage_aa(paint, fRenderTarget) && | 369 if (should_apply_coverage_aa(paint, fRenderTarget) && |
| 365 view_matrix_ok_for_aa_fill_rect(viewMatrix)) { | 370 view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
| 366 batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), vie
wMatrix, rectToDraw, | 371 batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), vie
wMatrix, rectToDraw, |
| 367 localRect)); | 372 localRect)); |
| 368 } else { | 373 } else { |
| 369 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rectToDraw, | 374 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rectToDraw, |
| 370 &localRect, nullptr)); | 375 &localRect, nullptr)); |
| 371 } | 376 } |
| 372 | 377 |
| 373 if (batch) { | 378 if (batch) { |
| 379 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 374 this->drawBatch(&pipelineBuilder, batch); | 380 this->drawBatch(&pipelineBuilder, batch); |
| 375 } | 381 } |
| 376 } | 382 } |
| 377 | 383 |
| 378 void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip, | 384 void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip, |
| 379 const GrPaint& paint, | 385 const GrPaint& paint, |
| 380 const SkMatrix& viewMatrix, | 386 const SkMatrix& viewMatrix, |
| 381 const SkRect& rectToDraw, | 387 const SkRect& rectToDraw, |
| 382 const SkMatrix& localMatrix) { | 388 const SkMatrix& localMatrix) { |
| 383 ASSERT_SINGLE_OWNER | 389 ASSERT_SINGLE_OWNER |
| 384 RETURN_IF_ABANDONED | 390 RETURN_IF_ABANDONED |
| 385 SkDEBUGCODE(this->validate();) | 391 SkDEBUGCODE(this->validate();) |
| 386 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectWithLocalMatr
ix"); | 392 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectWithLocalMatr
ix"); |
| 387 | 393 |
| 388 AutoCheckFlush acf(fDrawingManager); | 394 AutoCheckFlush acf(fDrawingManager); |
| 389 | 395 |
| 390 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 391 | |
| 392 SkAutoTUnref<GrDrawBatch> batch; | 396 SkAutoTUnref<GrDrawBatch> batch; |
| 393 if (should_apply_coverage_aa(paint, fRenderTarget) && | 397 if (should_apply_coverage_aa(paint, fRenderTarget) && |
| 394 view_matrix_ok_for_aa_fill_rect(viewMatrix)) { | 398 view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
| 395 batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, loca
lMatrix, | 399 batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, loca
lMatrix, |
| 396 rectToDraw)); | 400 rectToDraw)); |
| 397 } else { | 401 } else { |
| 398 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rectToDraw, | 402 batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMa
trix, rectToDraw, |
| 399 nullptr, &localMatrix)); | 403 nullptr, &localMatrix)); |
| 400 } | 404 } |
| 405 |
| 406 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 401 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 407 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 402 } | 408 } |
| 403 | 409 |
| 404 void GrDrawContext::drawVertices(const GrClip& clip, | 410 void GrDrawContext::drawVertices(const GrClip& clip, |
| 405 const GrPaint& paint, | 411 const GrPaint& paint, |
| 406 const SkMatrix& viewMatrix, | 412 const SkMatrix& viewMatrix, |
| 407 GrPrimitiveType primitiveType, | 413 GrPrimitiveType primitiveType, |
| 408 int vertexCount, | 414 int vertexCount, |
| 409 const SkPoint positions[], | 415 const SkPoint positions[], |
| 410 const SkPoint texCoords[], | 416 const SkPoint texCoords[], |
| 411 const GrColor colors[], | 417 const GrColor colors[], |
| 412 const uint16_t indices[], | 418 const uint16_t indices[], |
| 413 int indexCount) { | 419 int indexCount) { |
| 414 ASSERT_SINGLE_OWNER | 420 ASSERT_SINGLE_OWNER |
| 415 RETURN_IF_ABANDONED | 421 RETURN_IF_ABANDONED |
| 416 SkDEBUGCODE(this->validate();) | 422 SkDEBUGCODE(this->validate();) |
| 417 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawVertices"); | 423 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawVertices"); |
| 418 | 424 |
| 419 AutoCheckFlush acf(fDrawingManager); | 425 AutoCheckFlush acf(fDrawingManager); |
| 420 | 426 |
| 421 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 422 | |
| 423 // TODO clients should give us bounds | 427 // TODO clients should give us bounds |
| 424 SkRect bounds; | 428 SkRect bounds; |
| 425 if (!bounds.setBoundsCheck(positions, vertexCount)) { | 429 if (!bounds.setBoundsCheck(positions, vertexCount)) { |
| 426 SkDebugf("drawVertices call empty bounds\n"); | 430 SkDebugf("drawVertices call empty bounds\n"); |
| 427 return; | 431 return; |
| 428 } | 432 } |
| 429 | 433 |
| 430 viewMatrix.mapRect(&bounds); | 434 viewMatrix.mapRect(&bounds); |
| 431 | 435 |
| 432 // If we don't have AA then we outset for a half pixel in each direction to
account for | 436 // If we don't have AA then we outset for a half pixel in each direction to
account for |
| 433 // snapping. We also do this for the "hair" primitive types: lines and point
s since they have | 437 // snapping. We also do this for the "hair" primitive types: lines and point
s since they have |
| 434 // a 1 pixel thickness in device space. | 438 // a 1 pixel thickness in device space. |
| 435 if (!paint.isAntiAlias() || GrIsPrimTypeLines(primitiveType) || | 439 if (!paint.isAntiAlias() || GrIsPrimTypeLines(primitiveType) || |
| 436 kPoints_GrPrimitiveType == primitiveType) { | 440 kPoints_GrPrimitiveType == primitiveType) { |
| 437 bounds.outset(0.5f, 0.5f); | 441 bounds.outset(0.5f, 0.5f); |
| 438 } | 442 } |
| 439 | 443 |
| 440 GrDrawVerticesBatch::Geometry geometry; | 444 GrDrawVerticesBatch::Geometry geometry; |
| 441 geometry.fColor = paint.getColor(); | 445 geometry.fColor = paint.getColor(); |
| 442 SkAutoTUnref<GrDrawBatch> batch(GrDrawVerticesBatch::Create(geometry, primit
iveType, viewMatrix, | 446 SkAutoTUnref<GrDrawBatch> batch(GrDrawVerticesBatch::Create(geometry, primit
iveType, viewMatrix, |
| 443 positions, verte
xCount, indices, | 447 positions, verte
xCount, indices, |
| 444 indexCount, colo
rs, texCoords, | 448 indexCount, colo
rs, texCoords, |
| 445 bounds)); | 449 bounds)); |
| 446 | 450 |
| 451 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 447 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 452 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 448 } | 453 } |
| 449 | 454 |
| 450 /////////////////////////////////////////////////////////////////////////////// | 455 /////////////////////////////////////////////////////////////////////////////// |
| 451 | 456 |
| 452 void GrDrawContext::drawAtlas(const GrClip& clip, | 457 void GrDrawContext::drawAtlas(const GrClip& clip, |
| 453 const GrPaint& paint, | 458 const GrPaint& paint, |
| 454 const SkMatrix& viewMatrix, | 459 const SkMatrix& viewMatrix, |
| 455 int spriteCount, | 460 int spriteCount, |
| 456 const SkRSXform xform[], | 461 const SkRSXform xform[], |
| 457 const SkRect texRect[], | 462 const SkRect texRect[], |
| 458 const SkColor colors[]) { | 463 const SkColor colors[]) { |
| 459 ASSERT_SINGLE_OWNER | 464 ASSERT_SINGLE_OWNER |
| 460 RETURN_IF_ABANDONED | 465 RETURN_IF_ABANDONED |
| 461 SkDEBUGCODE(this->validate();) | 466 SkDEBUGCODE(this->validate();) |
| 462 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawAtlas"); | 467 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawAtlas"); |
| 463 | 468 |
| 464 AutoCheckFlush acf(fDrawingManager); | 469 AutoCheckFlush acf(fDrawingManager); |
| 465 | 470 |
| 466 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 467 | |
| 468 GrDrawAtlasBatch::Geometry geometry; | 471 GrDrawAtlasBatch::Geometry geometry; |
| 469 geometry.fColor = paint.getColor(); | 472 geometry.fColor = paint.getColor(); |
| 470 SkAutoTUnref<GrDrawBatch> batch(GrDrawAtlasBatch::Create(geometry, viewMatri
x, spriteCount, | 473 SkAutoTUnref<GrDrawBatch> batch(GrDrawAtlasBatch::Create(geometry, viewMatri
x, spriteCount, |
| 471 xform, texRect, col
ors)); | 474 xform, texRect, col
ors)); |
| 472 | 475 |
| 476 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 473 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 477 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 474 } | 478 } |
| 475 | 479 |
| 476 /////////////////////////////////////////////////////////////////////////////// | 480 /////////////////////////////////////////////////////////////////////////////// |
| 477 | 481 |
| 478 void GrDrawContext::drawRRect(const GrClip& clip, | 482 void GrDrawContext::drawRRect(const GrClip& clip, |
| 479 const GrPaint& paint, | 483 const GrPaint& paint, |
| 480 const SkMatrix& viewMatrix, | 484 const SkMatrix& viewMatrix, |
| 481 const SkRRect& rrect, | 485 const SkRRect& rrect, |
| 482 const GrStrokeInfo& strokeInfo) { | 486 const GrStrokeInfo& strokeInfo) { |
| 483 ASSERT_SINGLE_OWNER | 487 ASSERT_SINGLE_OWNER |
| 484 RETURN_IF_ABANDONED | 488 RETURN_IF_ABANDONED |
| 485 SkDEBUGCODE(this->validate();) | 489 SkDEBUGCODE(this->validate();) |
| 486 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRRect"); | 490 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRRect"); |
| 487 | 491 |
| 488 if (rrect.isEmpty()) { | 492 if (rrect.isEmpty()) { |
| 489 return; | 493 return; |
| 490 } | 494 } |
| 491 | 495 |
| 492 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice | 496 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice |
| 493 | 497 |
| 494 AutoCheckFlush acf(fDrawingManager); | 498 AutoCheckFlush acf(fDrawingManager); |
| 495 | 499 |
| 496 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 497 GrColor color = paint.getColor(); | |
| 498 | |
| 499 if (should_apply_coverage_aa(paint, fRenderTarget)) { | 500 if (should_apply_coverage_aa(paint, fRenderTarget)) { |
| 500 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); | 501 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
| 501 | 502 |
| 502 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(color, | 503 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(paint.g
etColor(), |
| 503 viewMat
rix, | 504 viewMat
rix, |
| 504 rrect, | 505 rrect, |
| 505 strokeI
nfo, | 506 strokeI
nfo, |
| 506 shaderC
aps)); | 507 shaderC
aps)); |
| 507 if (batch) { | 508 if (batch) { |
| 509 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 508 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 510 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 509 return; | 511 return; |
| 510 } | 512 } |
| 511 } | 513 } |
| 512 | 514 |
| 513 SkPath path; | 515 SkPath path; |
| 514 path.setIsVolatile(true); | 516 path.setIsVolatile(true); |
| 515 path.addRRect(rrect); | 517 path.addRRect(rrect); |
| 516 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, | 518 this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); |
| 517 paint.isAntiAlias(), path, strokeInfo); | |
| 518 } | 519 } |
| 519 | 520 |
| 520 bool GrDrawContext::drawFilledDRRect(const GrClip& clip, | 521 bool GrDrawContext::drawFilledDRRect(const GrClip& clip, |
| 521 const GrPaint& paintIn, | 522 const GrPaint& paintIn, |
| 522 const SkMatrix& viewMatrix, | 523 const SkMatrix& viewMatrix, |
| 523 const SkRRect& origOuter, | 524 const SkRRect& origOuter, |
| 524 const SkRRect& origInner) { | 525 const SkRRect& origInner) { |
| 525 SkASSERT(!origInner.isEmpty()); | 526 SkASSERT(!origInner.isEmpty()); |
| 526 SkASSERT(!origOuter.isEmpty()); | 527 SkASSERT(!origOuter.isEmpty()); |
| 527 | 528 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 return; | 594 return; |
| 594 } | 595 } |
| 595 | 596 |
| 596 SkPath path; | 597 SkPath path; |
| 597 path.setIsVolatile(true); | 598 path.setIsVolatile(true); |
| 598 path.addRRect(inner); | 599 path.addRRect(inner); |
| 599 path.addRRect(outer); | 600 path.addRRect(outer); |
| 600 path.setFillType(SkPath::kEvenOdd_FillType); | 601 path.setFillType(SkPath::kEvenOdd_FillType); |
| 601 | 602 |
| 602 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | 603 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 603 this->internalDrawPath(&pipelineBuilder, viewMatrix, paint.getColor(), | 604 this->internalDrawPath(clip, paint, viewMatrix, path, GrStrokeInfo::FillInfo
()); |
| 604 paint.isAntiAlias(), path, GrStrokeInfo::FillInfo())
; | |
| 605 } | 605 } |
| 606 | 606 |
| 607 /////////////////////////////////////////////////////////////////////////////// | 607 /////////////////////////////////////////////////////////////////////////////// |
| 608 | 608 |
| 609 void GrDrawContext::drawOval(const GrClip& clip, | 609 void GrDrawContext::drawOval(const GrClip& clip, |
| 610 const GrPaint& paint, | 610 const GrPaint& paint, |
| 611 const SkMatrix& viewMatrix, | 611 const SkMatrix& viewMatrix, |
| 612 const SkRect& oval, | 612 const SkRect& oval, |
| 613 const GrStrokeInfo& strokeInfo) { | 613 const GrStrokeInfo& strokeInfo) { |
| 614 ASSERT_SINGLE_OWNER | 614 ASSERT_SINGLE_OWNER |
| 615 RETURN_IF_ABANDONED | 615 RETURN_IF_ABANDONED |
| 616 SkDEBUGCODE(this->validate();) | 616 SkDEBUGCODE(this->validate();) |
| 617 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawOval"); | 617 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawOval"); |
| 618 | 618 |
| 619 if (oval.isEmpty()) { | 619 if (oval.isEmpty()) { |
| 620 return; | 620 return; |
| 621 } | 621 } |
| 622 | 622 |
| 623 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice | 623 SkASSERT(!strokeInfo.isDashed()); // this should've been devolved to a path
in SkGpuDevice |
| 624 | 624 |
| 625 AutoCheckFlush acf(fDrawingManager); | 625 AutoCheckFlush acf(fDrawingManager); |
| 626 | 626 |
| 627 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 628 GrColor color = paint.getColor(); | |
| 629 | |
| 630 if (should_apply_coverage_aa(paint, fRenderTarget)) { | 627 if (should_apply_coverage_aa(paint, fRenderTarget)) { |
| 631 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); | 628 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
| 632 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(color, | 629 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.ge
tColor(), |
| 633 viewMatr
ix, | 630 viewMatr
ix, |
| 634 oval, | 631 oval, |
| 635 strokeIn
fo, | 632 strokeIn
fo, |
| 636 shaderCa
ps)); | 633 shaderCa
ps)); |
| 637 if (batch) { | 634 if (batch) { |
| 635 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 638 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 636 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 639 return; | 637 return; |
| 640 } | 638 } |
| 641 } | 639 } |
| 642 | 640 |
| 643 SkPath path; | 641 SkPath path; |
| 644 path.setIsVolatile(true); | 642 path.setIsVolatile(true); |
| 645 path.addOval(oval); | 643 path.addOval(oval); |
| 646 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, | 644 this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); |
| 647 paint.isAntiAlias(), path, strokeInfo); | |
| 648 } | 645 } |
| 649 | 646 |
| 650 void GrDrawContext::drawImageNine(const GrClip& clip, | 647 void GrDrawContext::drawImageNine(const GrClip& clip, |
| 651 const GrPaint& paint, | 648 const GrPaint& paint, |
| 652 const SkMatrix& viewMatrix, | 649 const SkMatrix& viewMatrix, |
| 653 int imageWidth, | 650 int imageWidth, |
| 654 int imageHeight, | 651 int imageHeight, |
| 655 const SkIRect& center, | 652 const SkIRect& center, |
| 656 const SkRect& dst) { | 653 const SkRect& dst) { |
| 657 ASSERT_SINGLE_OWNER | 654 ASSERT_SINGLE_OWNER |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 SkDEBUGCODE(this->validate();) | 752 SkDEBUGCODE(this->validate();) |
| 756 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath"); | 753 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath"); |
| 757 | 754 |
| 758 if (path.isEmpty()) { | 755 if (path.isEmpty()) { |
| 759 if (path.isInverseFillType()) { | 756 if (path.isInverseFillType()) { |
| 760 this->drawPaint(clip, paint, viewMatrix); | 757 this->drawPaint(clip, paint, viewMatrix); |
| 761 } | 758 } |
| 762 return; | 759 return; |
| 763 } | 760 } |
| 764 | 761 |
| 765 GrColor color = paint.getColor(); | |
| 766 | |
| 767 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. | |
| 768 // Scratch textures can be recycled after they are returned to the texture | |
| 769 // cache. This presents a potential hazard for buffered drawing. However, | |
| 770 // the writePixels that uploads to the scratch will perform a flush so we're | |
| 771 // OK. | |
| 772 AutoCheckFlush acf(fDrawingManager); | 762 AutoCheckFlush acf(fDrawingManager); |
| 773 | 763 |
| 774 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); | |
| 775 if (should_apply_coverage_aa(paint, fRenderTarget) && !strokeInfo.isDashed()
) { | 764 if (should_apply_coverage_aa(paint, fRenderTarget) && !strokeInfo.isDashed()
) { |
| 776 if (strokeInfo.getWidth() < 0 && !path.isConvex()) { | 765 if (strokeInfo.getWidth() < 0 && !path.isConvex()) { |
| 777 // Concave AA paths are expensive - try to avoid them for special ca
ses | 766 // Concave AA paths are expensive - try to avoid them for special ca
ses |
| 778 SkRect rects[2]; | 767 SkRect rects[2]; |
| 779 | 768 |
| 780 if (is_nested_rects(viewMatrix, path, strokeInfo, rects)) { | 769 if (is_nested_rects(viewMatrix, path, strokeInfo, rects)) { |
| 781 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFill
NestedRects( | 770 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFill
NestedRects( |
| 782 color, viewMatrix, rects)); | 771 paint.getColor(), viewMatrix, rects)); |
| 772 |
| 773 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 783 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 774 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 784 return; | 775 return; |
| 785 } | 776 } |
| 786 } | 777 } |
| 787 SkRect ovalRect; | 778 SkRect ovalRect; |
| 788 bool isOval = path.isOval(&ovalRect); | 779 bool isOval = path.isOval(&ovalRect); |
| 789 | 780 |
| 790 if (isOval && !path.isInverseFillType()) { | 781 if (isOval && !path.isInverseFillType()) { |
| 791 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); | 782 GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); |
| 792 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(colo
r, | 783 SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(pain
t.getColor(), |
| 793 view
Matrix, | 784 view
Matrix, |
| 794 oval
Rect, | 785 oval
Rect, |
| 795 stro
keInfo, | 786 stro
keInfo, |
| 796 shad
erCaps)); | 787 shad
erCaps)); |
| 797 if (batch) { | 788 if (batch) { |
| 789 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 798 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); | 790 this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
| 799 return; | 791 return; |
| 800 } | 792 } |
| 801 } | 793 } |
| 802 } | 794 } |
| 803 this->internalDrawPath(&pipelineBuilder, viewMatrix, color, | 795 |
| 804 paint.isAntiAlias(), path, strokeInfo); | 796 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. |
| 797 // Scratch textures can be recycled after they are returned to the texture |
| 798 // cache. This presents a potential hazard for buffered drawing. However, |
| 799 // the writePixels that uploads to the scratch will perform a flush so we're |
| 800 // OK. |
| 801 this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); |
| 805 } | 802 } |
| 806 | 803 |
| 807 void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder, | 804 void GrDrawContext::internalDrawPath(const GrClip& clip, |
| 805 const GrPaint& paint, |
| 808 const SkMatrix& viewMatrix, | 806 const SkMatrix& viewMatrix, |
| 809 GrColor color, | |
| 810 bool useAA, | |
| 811 const SkPath& path, | 807 const SkPath& path, |
| 812 const GrStrokeInfo& strokeInfo) { | 808 const GrStrokeInfo& strokeInfo) { |
| 813 ASSERT_SINGLE_OWNER | 809 ASSERT_SINGLE_OWNER |
| 814 RETURN_IF_ABANDONED | 810 RETURN_IF_ABANDONED |
| 815 SkASSERT(!path.isEmpty()); | 811 SkASSERT(!path.isEmpty()); |
| 816 | 812 |
| 817 // An Assumption here is that path renderer would use some form of tweaking | 813 // An Assumption here is that path renderer would use some form of tweaking |
| 818 // the src color (either the input alpha or in the frag shader) to implement | 814 // the src color (either the input alpha or in the frag shader) to implement |
| 819 // aa. If we have some future driver-mojo path AA that can do the right | 815 // aa. If we have some future driver-mojo path AA that can do the right |
| 820 // thing WRT to the blend then we'll need some query on the PR. | 816 // thing WRT to the blend then we'll need some query on the PR. |
| 821 bool useCoverageAA = useAA && | 817 bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget); |
| 822 !pipelineBuilder->getRenderTarget()->isUnifiedMultisampled(); | 818 const bool isStencilDisabled = true; |
| 823 bool isStencilDisabled = pipelineBuilder->getStencil().isDisabled(); | 819 bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled(); |
| 824 bool isStencilBufferMSAA = pipelineBuilder->getRenderTarget()->isStencilBuff
erMultisampled(); | |
| 825 | 820 |
| 826 const GrPathRendererChain::DrawType type = | 821 const GrPathRendererChain::DrawType type = |
| 827 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType | 822 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType |
| 828 : GrPathRendererChain::kColor_DrawType; | 823 : GrPathRendererChain::kColor_DrawType; |
| 829 | 824 |
| 830 const SkPath* pathPtr = &path; | 825 const SkPath* pathPtr = &path; |
| 831 SkTLazy<SkPath> tmpPath; | 826 SkTLazy<SkPath> tmpPath; |
| 832 const GrStrokeInfo* strokeInfoPtr = &strokeInfo; | 827 const GrStrokeInfo* strokeInfoPtr = &strokeInfo; |
| 833 | 828 |
| 834 GrPathRenderer::CanDrawPathArgs canDrawArgs; | 829 GrPathRenderer::CanDrawPathArgs canDrawArgs; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type); | 882 pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type); |
| 888 } | 883 } |
| 889 | 884 |
| 890 if (nullptr == pr) { | 885 if (nullptr == pr) { |
| 891 #ifdef SK_DEBUG | 886 #ifdef SK_DEBUG |
| 892 SkDebugf("Unable to find path renderer compatible with path.\n"); | 887 SkDebugf("Unable to find path renderer compatible with path.\n"); |
| 893 #endif | 888 #endif |
| 894 return; | 889 return; |
| 895 } | 890 } |
| 896 | 891 |
| 892 GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
| 893 |
| 897 GrPathRenderer::DrawPathArgs args; | 894 GrPathRenderer::DrawPathArgs args; |
| 898 args.fTarget = this->getDrawTarget(); | 895 args.fTarget = this->getDrawTarget(); |
| 899 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider(); | 896 args.fResourceProvider = fDrawingManager->getContext()->resourceProvider(); |
| 900 args.fPipelineBuilder = pipelineBuilder; | 897 args.fPipelineBuilder = &pipelineBuilder; |
| 901 args.fColor = color; | 898 args.fColor = paint.getColor(); |
| 902 args.fViewMatrix = &viewMatrix; | 899 args.fViewMatrix = &viewMatrix; |
| 903 args.fPath = pathPtr; | 900 args.fPath = pathPtr; |
| 904 args.fStroke = strokeInfoPtr; | 901 args.fStroke = strokeInfoPtr; |
| 905 args.fAntiAlias = useCoverageAA; | 902 args.fAntiAlias = useCoverageAA; |
| 906 pr->drawPath(args); | 903 pr->drawPath(args); |
| 907 } | 904 } |
| 908 | 905 |
| 909 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* b
atch) { | 906 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* b
atch) { |
| 910 ASSERT_SINGLE_OWNER | 907 ASSERT_SINGLE_OWNER |
| 911 RETURN_IF_ABANDONED | 908 RETURN_IF_ABANDONED |
| 912 SkDEBUGCODE(this->validate();) | 909 SkDEBUGCODE(this->validate();) |
| 913 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch"); | 910 GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch"); |
| 914 | 911 |
| 915 this->getDrawTarget()->drawBatch(*pipelineBuilder, batch); | 912 this->getDrawTarget()->drawBatch(*pipelineBuilder, batch); |
| 916 } | 913 } |
| OLD | NEW |