Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: src/gpu/GrOvalRenderer.cpp

Issue 2283973002: Batch all circular rrects together (Closed)
Patch Set: Address comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 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 "GrOvalRenderer.h" 8 #include "GrOvalRenderer.h"
9 9
10 #include "GrBatchFlushState.h" 10 #include "GrBatchFlushState.h"
(...skipping 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 // ____________ 1355 // ____________
1356 // |_|________|_| 1356 // |_|________|_|
1357 // | |\ ____ /| | 1357 // | |\ ____ /| |
1358 // | | | | | | 1358 // | | | | | |
1359 // | | |____| | | 1359 // | | |____| | |
1360 // |_|/______\|_| 1360 // |_|/______\|_|
1361 // |_|________|_| 1361 // |_|________|_|
1362 // 1362 //
1363 // We don't draw the center quad from the fill rect in this case. 1363 // We don't draw the center quad from the fill rect in this case.
1364 1364
1365 static const uint16_t gRRectOverstrokeIndices[] = { 1365 static const uint16_t gOverstrokeRRectIndices[] = {
1366 // overstroke quads 1366 // overstroke quads
1367 // we place this at the beginning so that we can skip these indices when ren dering normally 1367 // we place this at the beginning so that we can skip these indices when ren dering normally
1368 16, 17, 19, 16, 19, 18, 1368 16, 17, 19, 16, 19, 18,
1369 19, 17, 23, 19, 23, 21, 1369 19, 17, 23, 19, 23, 21,
1370 21, 23, 22, 21, 22, 20, 1370 21, 23, 22, 21, 22, 20,
1371 22, 16, 18, 22, 18, 20, 1371 22, 16, 18, 22, 18, 20,
1372 1372
1373 // corners 1373 // corners
1374 0, 1, 5, 0, 5, 4, 1374 0, 1, 5, 0, 5, 4,
1375 2, 3, 7, 2, 7, 6, 1375 2, 3, 7, 2, 7, 6,
1376 8, 9, 13, 8, 13, 12, 1376 8, 9, 13, 8, 13, 12,
1377 10, 11, 15, 10, 15, 14, 1377 10, 11, 15, 10, 15, 14,
1378 1378
1379 // edges 1379 // edges
1380 1, 2, 6, 1, 6, 5, 1380 1, 2, 6, 1, 6, 5,
1381 4, 5, 9, 4, 9, 8, 1381 4, 5, 9, 4, 9, 8,
1382 6, 7, 11, 6, 11, 10, 1382 6, 7, 11, 6, 11, 10,
1383 9, 10, 14, 9, 14, 13, 1383 9, 10, 14, 9, 14, 13,
1384 1384
1385 // center 1385 // center
1386 // we place this at the end so that we can ignore these indices when not ren dering as filled 1386 // we place this at the end so that we can ignore these indices when not ren dering as filled
1387 5, 6, 10, 5, 10, 9, 1387 5, 6, 10, 5, 10, 9,
1388 }; 1388 };
1389 // fill and standard stroke indices skip the overstroke "ring"
1390 static const uint16_t* gStandardRRectIndices = gOverstrokeRRectIndices + 6*4;
1389 1391
1390 static const uint16_t* gRRectIndices = gRRectOverstrokeIndices + 6*4; 1392 // overstroke count is arraysize minus the center indices
1391 1393 static const int kIndicesPerOverstrokeRRect = SK_ARRAY_COUNT(gOverstrokeRRectInd ices) - 6;
1392 // overstroke count is arraysize 1394 // fill count skips overstroke indices and includes center
1393 static const int kIndicesPerOverstrokeRRect = SK_ARRAY_COUNT(gRRectOverstrokeInd ices) - 6;
1394 static const int kIndicesPerFillRRect = kIndicesPerOverstrokeRRect - 6*4 + 6; 1395 static const int kIndicesPerFillRRect = kIndicesPerOverstrokeRRect - 6*4 + 6;
1396 // stroke count is fill count minus center indices
1395 static const int kIndicesPerStrokeRRect = kIndicesPerFillRRect - 6; 1397 static const int kIndicesPerStrokeRRect = kIndicesPerFillRRect - 6;
1396 static const int kVertsPerStandardRRect = 16; 1398 static const int kVertsPerStandardRRect = 16;
1397 static const int kVertsPerOverstrokeRRect = 24; 1399 static const int kVertsPerOverstrokeRRect = 24;
1398 static const int kNumRRectsInIndexBuffer = 256;
1399 1400
1400 enum RRectType { 1401 enum RRectType {
1401 kFill_RRectType, 1402 kFill_RRectType,
1402 kStroke_RRectType, 1403 kStroke_RRectType,
1403 kOverstroke_RRectType 1404 kOverstroke_RRectType,
1404 }; 1405 };
1405 1406
1406 GR_DECLARE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey); 1407 static int rrect_type_to_vert_count(RRectType type) {
1407 GR_DECLARE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey); 1408 static const int kTypeToVertCount[] = {
1408 GR_DECLARE_STATIC_UNIQUE_KEY(gOverstrokeRRectOnlyIndexBufferKey); 1409 kVertsPerStandardRRect,
1409 static const GrBuffer* ref_rrect_index_buffer(RRectType type, 1410 kVertsPerStandardRRect,
1410 GrResourceProvider* resourceProvid er) { 1411 kVertsPerOverstrokeRRect,
1411 GR_DEFINE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey);
1412 GR_DEFINE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey);
1413 GR_DEFINE_STATIC_UNIQUE_KEY(gOverstrokeRRectOnlyIndexBufferKey);
1414 switch (type) {
1415 case kFill_RRectType:
1416 default:
1417 return resourceProvider->findOrCreateInstancedIndexBuffer(
1418 gRRectIndices, kIndicesPerFillRRect, kNumRRectsInIndexBuffer,
1419 kVertsPerStandardRRect, gRRectOnlyIndexBufferKey);
1420 case kStroke_RRectType:
1421 return resourceProvider->findOrCreateInstancedIndexBuffer(
1422 gRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndexBuffer,
1423 kVertsPerStandardRRect, gStrokeRRectOnlyIndexBufferKey);
1424 case kOverstroke_RRectType:
1425 return resourceProvider->findOrCreateInstancedIndexBuffer(
1426 gRRectOverstrokeIndices, kIndicesPerOverstrokeRRect, kNumRRectsI nIndexBuffer,
1427 kVertsPerOverstrokeRRect, gOverstrokeRRectOnlyIndexBufferKey);
1428 }; 1412 };
1413
1414 return kTypeToVertCount[type];
1415 }
1416
1417 static int rrect_type_to_index_count(RRectType type) {
1418 static const int kTypeToIndexCount[] = {
1419 kIndicesPerFillRRect,
1420 kIndicesPerStrokeRRect,
1421 kIndicesPerOverstrokeRRect,
1422 };
1423
1424 return kTypeToIndexCount[type];
1425 }
1426
1427 static const uint16_t* rrect_type_to_indices(RRectType type) {
1428 static const uint16_t* kTypeToIndices[] = {
1429 gStandardRRectIndices,
1430 gStandardRRectIndices,
1431 gOverstrokeRRectIndices,
1432 };
1433
1434 return kTypeToIndices[type];
1429 } 1435 }
1430 1436
1431 //////////////////////////////////////////////////////////////////////////////// /////////////////// 1437 //////////////////////////////////////////////////////////////////////////////// ///////////////////
1432 1438
1433 class RRectCircleRendererBatch : public GrVertexBatch { 1439 class RRectCircleRendererBatch : public GrVertexBatch {
1434 public: 1440 public:
1435 DEFINE_BATCH_CLASS_ID 1441 DEFINE_BATCH_CLASS_ID
1436 1442
1437 // A devStrokeWidth <= 0 indicates a fill only. If devStrokeWidth > 0 then s trokeOnly indicates 1443 // A devStrokeWidth <= 0 indicates a fill only. If devStrokeWidth > 0 then s trokeOnly indicates
1438 // whether the rrect is only stroked or stroked and filled. 1444 // whether the rrect is only stroked or stroked and filled.
1439 RRectCircleRendererBatch(GrColor color, const SkMatrix& viewMatrix, const Sk Rect& devRect, 1445 RRectCircleRendererBatch(GrColor color, const SkMatrix& viewMatrix, const Sk Rect& devRect,
1440 float devRadius, float devStrokeWidth, bool strokeO nly) 1446 float devRadius, float devStrokeWidth, bool strokeO nly)
1441 : INHERITED(ClassID()) 1447 : INHERITED(ClassID())
1442 , fViewMatrixIfUsingLocalCoords(viewMatrix) { 1448 , fViewMatrixIfUsingLocalCoords(viewMatrix) {
1443 SkRect bounds = devRect; 1449 SkRect bounds = devRect;
1444 SkASSERT(!(devStrokeWidth <= 0 && strokeOnly)); 1450 SkASSERT(!(devStrokeWidth <= 0 && strokeOnly));
1445 SkScalar innerRadius = 0.0f; 1451 SkScalar innerRadius = 0.0f;
1446 SkScalar outerRadius = devRadius; 1452 SkScalar outerRadius = devRadius;
1447 SkScalar halfWidth = 0; 1453 SkScalar halfWidth = 0;
1448 fType = kFill_RRectType; 1454 RRectType type = kFill_RRectType;
1449 if (devStrokeWidth > 0) { 1455 if (devStrokeWidth > 0) {
1450 if (SkScalarNearlyZero(devStrokeWidth)) { 1456 if (SkScalarNearlyZero(devStrokeWidth)) {
1451 halfWidth = SK_ScalarHalf; 1457 halfWidth = SK_ScalarHalf;
1452 } else { 1458 } else {
1453 halfWidth = SkScalarHalf(devStrokeWidth); 1459 halfWidth = SkScalarHalf(devStrokeWidth);
1454 } 1460 }
1455 1461
1456 if (strokeOnly) { 1462 if (strokeOnly) {
1457 // Outset stroke by 1/4 pixel 1463 // Outset stroke by 1/4 pixel
1458 devStrokeWidth += 0.25f; 1464 devStrokeWidth += 0.25f;
1459 // If stroke is greater than width or height, this is still a fi ll 1465 // If stroke is greater than width or height, this is still a fi ll
1460 // Otherwise we compute stroke params 1466 // Otherwise we compute stroke params
1461 if (devStrokeWidth <= devRect.width() && 1467 if (devStrokeWidth <= devRect.width() &&
1462 devStrokeWidth <= devRect.height()) { 1468 devStrokeWidth <= devRect.height()) {
1463 innerRadius = devRadius - halfWidth; 1469 innerRadius = devRadius - halfWidth;
1464 fType = (innerRadius >= 0) ? kStroke_RRectType : kOverstroke _RRectType; 1470 type = (innerRadius >= 0) ? kStroke_RRectType : kOverstroke_ RRectType;
1465 } 1471 }
1466 } 1472 }
1467 outerRadius += halfWidth; 1473 outerRadius += halfWidth;
1468 bounds.outset(halfWidth, halfWidth); 1474 bounds.outset(halfWidth, halfWidth);
1469 } 1475 }
1470 1476
1471 // The radii are outset for two reasons. First, it allows the shader to simply perform 1477 // The radii are outset for two reasons. First, it allows the shader to simply perform
1472 // simpler computation because the computed alpha is zero, rather than 5 0%, at the radius. 1478 // simpler computation because the computed alpha is zero, rather than 5 0%, at the radius.
1473 // Second, the outer radius is used to compute the verts of the bounding box that is 1479 // Second, the outer radius is used to compute the verts of the bounding box that is
1474 // rendered and the outset ensures the box will cover all partially cove red by the rrect 1480 // rendered and the outset ensures the box will cover all partially cove red by the rrect
1475 // corners. 1481 // corners.
1476 outerRadius += SK_ScalarHalf; 1482 outerRadius += SK_ScalarHalf;
1477 innerRadius -= SK_ScalarHalf; 1483 innerRadius -= SK_ScalarHalf;
1478 1484
1479 this->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo); 1485 this->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
1480 1486
1481 // Expand the rect for aa to generate correct vertices. 1487 // Expand the rect for aa to generate correct vertices.
1482 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 1488 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1483 1489
1484 fGeoData.emplace_back(Geometry { color, innerRadius, outerRadius, bounds }); 1490 fGeoData.emplace_back(Geometry{ color, innerRadius, outerRadius, bounds, type });
1491 fVertCount = rrect_type_to_vert_count(type);
1492 fIndexCount = rrect_type_to_index_count(type);
1493 fAllFill = (kFill_RRectType == type);
1485 } 1494 }
1486 1495
1487 const char* name() const override { return "RRectCircleBatch"; } 1496 const char* name() const override { return "RRectCircleBatch"; }
1488 1497
1489 SkString dumpInfo() const override { 1498 SkString dumpInfo() const override {
1490 SkString string; 1499 SkString string;
1491 for (int i = 0; i < fGeoData.count(); ++i) { 1500 for (int i = 0; i < fGeoData.count(); ++i) {
1492 string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %. 2f]," 1501 string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %. 2f],"
1493 "InnerRad: %.2f, OuterRad: %.2f\n", 1502 "InnerRad: %.2f, OuterRad: %.2f\n",
1494 fGeoData[i].fColor, 1503 fGeoData[i].fColor,
(...skipping 24 matching lines...) Expand all
1519 } 1528 }
1520 1529
1521 void onPrepareDraws(Target* target) const override { 1530 void onPrepareDraws(Target* target) const override {
1522 // Invert the view matrix as a local matrix (if any other processors req uire coords). 1531 // Invert the view matrix as a local matrix (if any other processors req uire coords).
1523 SkMatrix localMatrix; 1532 SkMatrix localMatrix;
1524 if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { 1533 if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) {
1525 return; 1534 return;
1526 } 1535 }
1527 1536
1528 // Setup geometry processor 1537 // Setup geometry processor
1529 SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(kFill_R RectType != fType, 1538 SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(fAllFil l,
1530 false, false, 1539 false, false,
1531 false, localMatrix)); 1540 false, localMatrix));
1532
1533 struct CircleVertex { 1541 struct CircleVertex {
1534 SkPoint fPos; 1542 SkPoint fPos;
1535 GrColor fColor; 1543 GrColor fColor;
1536 SkPoint fOffset; 1544 SkPoint fOffset;
1537 SkScalar fOuterRadius; 1545 SkScalar fOuterRadius;
1538 SkScalar fInnerRadius; 1546 SkScalar fInnerRadius;
1539 // No half plane, we don't use it here. 1547 // No half plane, we don't use it here.
1540 }; 1548 };
1541 1549
1542 int instanceCount = fGeoData.count(); 1550 int instanceCount = fGeoData.count();
1543 size_t vertexStride = gp->getVertexStride(); 1551 size_t vertexStride = gp->getVertexStride();
1544 SkASSERT(vertexStride == sizeof(CircleVertex)); 1552 SkASSERT(sizeof(CircleVertex) == vertexStride);
1545 1553
1546 // drop out the middle quad if we're stroked 1554 const GrBuffer* vertexBuffer;
1547 int indicesPerInstance = kIndicesPerFillRRect; 1555 int firstVertex;
1548 if (kStroke_RRectType == fType) {
1549 indicesPerInstance = kIndicesPerStrokeRRect;
1550 } else if (kOverstroke_RRectType == fType) {
1551 indicesPerInstance = kIndicesPerOverstrokeRRect;
1552 }
1553 SkAutoTUnref<const GrBuffer> indexBuffer(
1554 ref_rrect_index_buffer(fType, target->resourceProvider()));
1555 1556
1556 InstancedHelper helper; 1557 CircleVertex* verts = (CircleVertex*) target->makeVertexSpace(vertexStri de, fVertCount,
1557 int vertexCount = (kOverstroke_RRectType == fType) ? kVertsPerOverstroke RRect 1558 &vertexBuf fer, &firstVertex);
1558 : kVertsPerStandardRR ect; 1559 if (!verts) {
1559 CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(target ,
1560 kTriangles_GrPrimitiveType, vertexStride, indexBuffer, vertexCount,
1561 indicesPerInstance, instanceCount));
1562 if (!verts || !indexBuffer) {
1563 SkDebugf("Could not allocate vertices\n"); 1560 SkDebugf("Could not allocate vertices\n");
1564 return; 1561 return;
1565 } 1562 }
1566 1563
1564 const GrBuffer* indexBuffer = nullptr;
1565 int firstIndex = 0;
1566 uint16_t* indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &f irstIndex);
1567 if (!indices) {
1568 SkDebugf("Could not allocate indices\n");
1569 return;
1570 }
1571
1572 int currStartVertex = 0;
1567 for (int i = 0; i < instanceCount; i++) { 1573 for (int i = 0; i < instanceCount; i++) {
1568 const Geometry& args = fGeoData[i]; 1574 const Geometry& args = fGeoData[i];
1569 1575
1570 GrColor color = args.fColor; 1576 GrColor color = args.fColor;
1571 SkScalar outerRadius = args.fOuterRadius; 1577 SkScalar outerRadius = args.fOuterRadius;
1572 1578
1573 const SkRect& bounds = args.fDevBounds; 1579 const SkRect& bounds = args.fDevBounds;
1574 1580
1575 SkScalar yCoords[4] = { 1581 SkScalar yCoords[4] = {
1576 bounds.fTop, 1582 bounds.fTop,
1577 bounds.fTop + outerRadius, 1583 bounds.fTop + outerRadius,
1578 bounds.fBottom - outerRadius, 1584 bounds.fBottom - outerRadius,
1579 bounds.fBottom 1585 bounds.fBottom
1580 }; 1586 };
1581 1587
1582 SkScalar yOuterRadii[4] = {-1, 0, 0, 1 }; 1588 SkScalar yOuterRadii[4] = {-1, 0, 0, 1 };
1583 // The inner radius in the vertex data must be specified in normaliz ed space. 1589 // The inner radius in the vertex data must be specified in normaliz ed space.
1584 SkScalar innerRadius = args.fInnerRadius / args.fOuterRadius; 1590 // For fills, specifying -1/outerRadius guarantees an alpha of 1.0 a t the inner radius.
1591 SkScalar innerRadius = args.fType != kFill_RRectType
1592 ? args.fInnerRadius / args.fOuterRadius
1593 : -1.0f / args.fOuterRadius;
1585 for (int i = 0; i < 4; ++i) { 1594 for (int i = 0; i < 4; ++i) {
1586 verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]); 1595 verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]);
1587 verts->fColor = color; 1596 verts->fColor = color;
1588 verts->fOffset = SkPoint::Make(-1, yOuterRadii[i]); 1597 verts->fOffset = SkPoint::Make(-1, yOuterRadii[i]);
1589 verts->fOuterRadius = outerRadius; 1598 verts->fOuterRadius = outerRadius;
1590 verts->fInnerRadius = innerRadius; 1599 verts->fInnerRadius = innerRadius;
1591 verts++; 1600 verts++;
1592 1601
1593 verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[ i]); 1602 verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[ i]);
1594 verts->fColor = color; 1603 verts->fColor = color;
(...skipping 17 matching lines...) Expand all
1612 verts++; 1621 verts++;
1613 } 1622 }
1614 // Add the additional vertices for overstroked rrects. 1623 // Add the additional vertices for overstroked rrects.
1615 // Effectively this is an additional stroked rrect, with its 1624 // Effectively this is an additional stroked rrect, with its
1616 // outer radius = outerRadius - innerRadius, and inner radius = 0. 1625 // outer radius = outerRadius - innerRadius, and inner radius = 0.
1617 // This will give us correct AA in the center and the correct 1626 // This will give us correct AA in the center and the correct
1618 // distance to the outer edge. 1627 // distance to the outer edge.
1619 // 1628 //
1620 // Also, the outer offset is a constant vector pointing to the right , which 1629 // Also, the outer offset is a constant vector pointing to the right , which
1621 // guarantees that the distance value along the outer rectangle is c onstant. 1630 // guarantees that the distance value along the outer rectangle is c onstant.
1622 if (kOverstroke_RRectType == fType) { 1631 if (kOverstroke_RRectType == args.fType) {
1623 SkScalar overstrokeOuterRadius = outerRadius - args.fInnerRadius ; 1632 SkScalar overstrokeOuterRadius = outerRadius - args.fInnerRadius ;
1624 // this is the normalized distance from the outer rectangle of t his 1633 // this is the normalized distance from the outer rectangle of t his
1625 // geometry to the outer edge 1634 // geometry to the outer edge
1626 SkScalar maxOffset = -args.fInnerRadius/overstrokeOuterRadius; 1635 SkScalar maxOffset = -args.fInnerRadius / overstrokeOuterRadius;
1627 1636
1628 verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[ 1]); 1637 verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[ 1]);
1629 verts->fColor = color; 1638 verts->fColor = color;
1630 verts->fOffset = SkPoint::Make(maxOffset, 0); 1639 verts->fOffset = SkPoint::Make(maxOffset, 0);
1631 verts->fOuterRadius = overstrokeOuterRadius; 1640 verts->fOuterRadius = overstrokeOuterRadius;
1632 verts->fInnerRadius = 0; 1641 verts->fInnerRadius = 0;
1633 verts++; 1642 verts++;
1634 1643
1635 verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords [1]); 1644 verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords [1]);
1636 verts->fColor = color; 1645 verts->fColor = color;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 verts->fInnerRadius = 0; 1687 verts->fInnerRadius = 0;
1679 verts++; 1688 verts++;
1680 1689
1681 verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords [2]); 1690 verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords [2]);
1682 verts->fColor = color; 1691 verts->fColor = color;
1683 verts->fOffset = SkPoint::Make(maxOffset, 0); 1692 verts->fOffset = SkPoint::Make(maxOffset, 0);
1684 verts->fOuterRadius = overstrokeOuterRadius; 1693 verts->fOuterRadius = overstrokeOuterRadius;
1685 verts->fInnerRadius = 0; 1694 verts->fInnerRadius = 0;
1686 verts++; 1695 verts++;
1687 } 1696 }
1697
1698 const uint16_t* primIndices = rrect_type_to_indices(args.fType);
1699 const int primIndexCount = rrect_type_to_index_count(args.fType);
1700 for (int i = 0; i < primIndexCount; ++i) {
1701 *indices++ = primIndices[i] + currStartVertex;
1702 }
1703
1704 currStartVertex += rrect_type_to_vert_count(args.fType);
1688 } 1705 }
1689 1706
1690 helper.recordDraw(target, gp); 1707 GrMesh mesh;
1708 mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
1709 firstIndex, fVertCount, fIndexCount);
1710 target->draw(gp.get(), mesh);
1691 } 1711 }
1692 1712
1693 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 1713 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
1694 RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>(); 1714 RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>();
1695 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), 1715 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(),
1696 that->bounds(), caps)) { 1716 that->bounds(), caps)) {
1697 return false; 1717 return false;
1698 } 1718 }
1699 1719
1700 if (fType != that->fType) {
1701 return false;
1702 }
1703
1704 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) { 1720 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) {
1705 return false; 1721 return false;
1706 } 1722 }
1707 1723
1708 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 1724 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin());
1709 this->joinBounds(*that); 1725 this->joinBounds(*that);
1726 fVertCount += that->fVertCount;
1727 fIndexCount += that->fIndexCount;
1728 fAllFill = fAllFill && that->fAllFill;
1710 return true; 1729 return true;
1711 } 1730 }
1712 1731
1713 struct Geometry { 1732 struct Geometry {
1714 GrColor fColor; 1733 GrColor fColor;
1715 SkScalar fInnerRadius; 1734 SkScalar fInnerRadius;
1716 SkScalar fOuterRadius; 1735 SkScalar fOuterRadius;
1717 SkRect fDevBounds; 1736 SkRect fDevBounds;
1737 RRectType fType;
1718 }; 1738 };
1719 1739
1720 RRectType fType; 1740 SkSTArray<1, Geometry, true> fGeoData;
1721 SkMatrix fViewMatrixIfUsingLocalCoords; 1741 SkMatrix fViewMatrixIfUsingLocalCoords;
1722 SkSTArray<1, Geometry, true> fGeoData; 1742 int fVertCount;
1743 int fIndexCount;
1744 bool fAllFill;
1723 1745
1724 typedef GrVertexBatch INHERITED; 1746 typedef GrVertexBatch INHERITED;
1725 }; 1747 };
1726 1748
1749 static const int kNumRRectsInIndexBuffer = 256;
1750
1751 GR_DECLARE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey);
1752 GR_DECLARE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey);
1753 static const GrBuffer* ref_rrect_index_buffer(RRectType type,
1754 GrResourceProvider* resourceProvid er) {
1755 GR_DEFINE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey);
1756 GR_DEFINE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey);
1757 switch (type) {
1758 case kFill_RRectType:
1759 return resourceProvider->findOrCreateInstancedIndexBuffer(
1760 gStandardRRectIndices, kIndicesPerFillRRect, kNumRRectsInIndexBu ffer,
1761 kVertsPerStandardRRect, gRRectOnlyIndexBufferKey);
1762 case kStroke_RRectType:
1763 return resourceProvider->findOrCreateInstancedIndexBuffer(
1764 gStandardRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndex Buffer,
1765 kVertsPerStandardRRect, gStrokeRRectOnlyIndexBufferKey);
1766 default:
1767 SkASSERT(false);
1768 return nullptr;
1769 };
1770 }
1771
1727 class RRectEllipseRendererBatch : public GrVertexBatch { 1772 class RRectEllipseRendererBatch : public GrVertexBatch {
1728 public: 1773 public:
1729 DEFINE_BATCH_CLASS_ID 1774 DEFINE_BATCH_CLASS_ID
1730 1775
1731 // If devStrokeWidths values are <= 0 indicates then fill only. Otherwise, s trokeOnly indicates 1776 // If devStrokeWidths values are <= 0 indicates then fill only. Otherwise, s trokeOnly indicates
1732 // whether the rrect is only stroked or stroked and filled. 1777 // whether the rrect is only stroked or stroked and filled.
1733 static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& devRect, 1778 static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& devRect,
1734 float devXRadius, float devYRadius, SkVector devS trokeWidths, 1779 float devXRadius, float devYRadius, SkVector devS trokeWidths,
1735 bool strokeOnly) { 1780 bool strokeOnly) {
1736 SkASSERT(devXRadius > 0.5); 1781 SkASSERT(devXRadius > 0.5);
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
2128 } 2173 }
2129 2174
2130 DRAW_BATCH_TEST_DEFINE(RRectBatch) { 2175 DRAW_BATCH_TEST_DEFINE(RRectBatch) {
2131 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); 2176 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
2132 GrColor color = GrRandomColor(random); 2177 GrColor color = GrRandomColor(random);
2133 const SkRRect& rrect = GrTest::TestRRectSimple(random); 2178 const SkRRect& rrect = GrTest::TestRRectSimple(random);
2134 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra ndom)); 2179 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra ndom));
2135 } 2180 }
2136 2181
2137 #endif 2182 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698