OLD | NEW |
---|---|
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 Loading... | |
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 fVertCount = rrect_type_to_vert_count(type); |
1491 fIndexCount = rrect_type_to_index_count(type); | |
1492 fGeoData.emplace_back(Geometry { color, innerRadius, outerRadius, bounds , type }); | |
1485 } | 1493 } |
1486 | 1494 |
1487 const char* name() const override { return "RRectCircleBatch"; } | 1495 const char* name() const override { return "RRectCircleBatch"; } |
1488 | 1496 |
1489 SkString dumpInfo() const override { | 1497 SkString dumpInfo() const override { |
1490 SkString string; | 1498 SkString string; |
1491 for (int i = 0; i < fGeoData.count(); ++i) { | 1499 for (int i = 0; i < fGeoData.count(); ++i) { |
1492 string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %. 2f]," | 1500 string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %. 2f]," |
1493 "InnerRad: %.2f, OuterRad: %.2f\n", | 1501 "InnerRad: %.2f, OuterRad: %.2f\n", |
1494 fGeoData[i].fColor, | 1502 fGeoData[i].fColor, |
(...skipping 23 matching lines...) Expand all Loading... | |
1518 } | 1526 } |
1519 } | 1527 } |
1520 | 1528 |
1521 void onPrepareDraws(Target* target) const override { | 1529 void onPrepareDraws(Target* target) const override { |
1522 // Invert the view matrix as a local matrix (if any other processors req uire coords). | 1530 // Invert the view matrix as a local matrix (if any other processors req uire coords). |
1523 SkMatrix localMatrix; | 1531 SkMatrix localMatrix; |
1524 if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { | 1532 if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { |
1525 return; | 1533 return; |
1526 } | 1534 } |
1527 | 1535 |
1528 // Setup geometry processor | |
1529 SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(kFill_R RectType != fType, | |
1530 false, false, | |
1531 false, localMatrix)); | |
1532 | |
1533 struct CircleVertex { | 1536 struct CircleVertex { |
1534 SkPoint fPos; | 1537 SkPoint fPos; |
1535 GrColor fColor; | 1538 GrColor fColor; |
1536 SkPoint fOffset; | 1539 SkPoint fOffset; |
1537 SkScalar fOuterRadius; | 1540 SkScalar fOuterRadius; |
1538 SkScalar fInnerRadius; | 1541 SkScalar fInnerRadius; |
1539 // No half plane, we don't use it here. | 1542 // No half plane, we don't use it here. |
1540 }; | 1543 }; |
1541 | 1544 |
1542 int instanceCount = fGeoData.count(); | 1545 int instanceCount = fGeoData.count(); |
1543 size_t vertexStride = gp->getVertexStride(); | 1546 size_t vertexStride = sizeof(CircleVertex); |
1544 SkASSERT(vertexStride == sizeof(CircleVertex)); | |
1545 | 1547 |
1546 // drop out the middle quad if we're stroked | 1548 const GrBuffer* vertexBuffer; |
1547 int indicesPerInstance = kIndicesPerFillRRect; | 1549 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 | 1550 |
1556 InstancedHelper helper; | 1551 CircleVertex* verts = (CircleVertex*) target->makeVertexSpace(vertexStri de, fVertCount, |
1557 int vertexCount = (kOverstroke_RRectType == fType) ? kVertsPerOverstroke RRect | 1552 &vertexBuf fer, &firstVertex); |
1558 : kVertsPerStandardRR ect; | 1553 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"); | 1554 SkDebugf("Could not allocate vertices\n"); |
1564 return; | 1555 return; |
1565 } | 1556 } |
1566 | 1557 |
1558 const GrBuffer* indexBuffer = nullptr; | |
1559 int firstIndex = 0; | |
1560 uint16_t* indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &f irstIndex); | |
1561 if (!indices) { | |
1562 SkDebugf("Could not allocate indices\n"); | |
1563 return; | |
1564 } | |
1565 | |
1566 int currStartVertex = 0; | |
1567 bool allFill = true; | |
1567 for (int i = 0; i < instanceCount; i++) { | 1568 for (int i = 0; i < instanceCount; i++) { |
1568 const Geometry& args = fGeoData[i]; | 1569 const Geometry& args = fGeoData[i]; |
robertphillips
2016/08/29 15:43:21
It seems a bit odd that we don't compute this as w
jvanverth1
2016/08/29 16:41:08
Done.
| |
1570 allFill = allFill && kFill_RRectType == args.fType; | |
1569 | 1571 |
1570 GrColor color = args.fColor; | 1572 GrColor color = args.fColor; |
1571 SkScalar outerRadius = args.fOuterRadius; | 1573 SkScalar outerRadius = args.fOuterRadius; |
1572 | 1574 |
1573 const SkRect& bounds = args.fDevBounds; | 1575 const SkRect& bounds = args.fDevBounds; |
1574 | 1576 |
1575 SkScalar yCoords[4] = { | 1577 SkScalar yCoords[4] = { |
1576 bounds.fTop, | 1578 bounds.fTop, |
1577 bounds.fTop + outerRadius, | 1579 bounds.fTop + outerRadius, |
1578 bounds.fBottom - outerRadius, | 1580 bounds.fBottom - outerRadius, |
1579 bounds.fBottom | 1581 bounds.fBottom |
1580 }; | 1582 }; |
1581 | 1583 |
1582 SkScalar yOuterRadii[4] = {-1, 0, 0, 1 }; | 1584 SkScalar yOuterRadii[4] = {-1, 0, 0, 1 }; |
1583 // The inner radius in the vertex data must be specified in normaliz ed space. | 1585 // The inner radius in the vertex data must be specified in normaliz ed space. |
1584 SkScalar innerRadius = args.fInnerRadius / args.fOuterRadius; | 1586 // For fills, specifying 1/outerRadius guarantees an alpha of 1.0 at the inner radius. |
bsalomon
2016/08/29 15:49:43
-1/outerRadius?
jvanverth1
2016/08/29 16:41:08
Done.
| |
1587 SkScalar innerRadius = args.fType != kFill_RRectType | |
1588 ? args.fInnerRadius / args.fOuterRadius | |
1589 : -1.0f / args.fOuterRadius; | |
1585 for (int i = 0; i < 4; ++i) { | 1590 for (int i = 0; i < 4; ++i) { |
1586 verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]); | 1591 verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]); |
1587 verts->fColor = color; | 1592 verts->fColor = color; |
1588 verts->fOffset = SkPoint::Make(-1, yOuterRadii[i]); | 1593 verts->fOffset = SkPoint::Make(-1, yOuterRadii[i]); |
1589 verts->fOuterRadius = outerRadius; | 1594 verts->fOuterRadius = outerRadius; |
1590 verts->fInnerRadius = innerRadius; | 1595 verts->fInnerRadius = innerRadius; |
1591 verts++; | 1596 verts++; |
1592 | 1597 |
1593 verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[ i]); | 1598 verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[ i]); |
1594 verts->fColor = color; | 1599 verts->fColor = color; |
(...skipping 17 matching lines...) Expand all Loading... | |
1612 verts++; | 1617 verts++; |
1613 } | 1618 } |
1614 // Add the additional vertices for overstroked rrects. | 1619 // Add the additional vertices for overstroked rrects. |
1615 // Effectively this is an additional stroked rrect, with its | 1620 // Effectively this is an additional stroked rrect, with its |
1616 // outer radius = outerRadius - innerRadius, and inner radius = 0. | 1621 // outer radius = outerRadius - innerRadius, and inner radius = 0. |
1617 // This will give us correct AA in the center and the correct | 1622 // This will give us correct AA in the center and the correct |
1618 // distance to the outer edge. | 1623 // distance to the outer edge. |
1619 // | 1624 // |
1620 // Also, the outer offset is a constant vector pointing to the right , which | 1625 // 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. | 1626 // guarantees that the distance value along the outer rectangle is c onstant. |
1622 if (kOverstroke_RRectType == fType) { | 1627 if (kOverstroke_RRectType == args.fType) { |
1623 SkScalar overstrokeOuterRadius = outerRadius - args.fInnerRadius ; | 1628 SkScalar overstrokeOuterRadius = outerRadius - args.fInnerRadius ; |
1624 // this is the normalized distance from the outer rectangle of t his | 1629 // this is the normalized distance from the outer rectangle of t his |
1625 // geometry to the outer edge | 1630 // geometry to the outer edge |
1626 SkScalar maxOffset = -args.fInnerRadius/overstrokeOuterRadius; | 1631 SkScalar maxOffset = -args.fInnerRadius / overstrokeOuterRadius; |
1627 | 1632 |
1628 verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[ 1]); | 1633 verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[ 1]); |
1629 verts->fColor = color; | 1634 verts->fColor = color; |
1630 verts->fOffset = SkPoint::Make(maxOffset, 0); | 1635 verts->fOffset = SkPoint::Make(maxOffset, 0); |
1631 verts->fOuterRadius = overstrokeOuterRadius; | 1636 verts->fOuterRadius = overstrokeOuterRadius; |
1632 verts->fInnerRadius = 0; | 1637 verts->fInnerRadius = 0; |
1633 verts++; | 1638 verts++; |
1634 | 1639 |
1635 verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords [1]); | 1640 verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords [1]); |
1636 verts->fColor = color; | 1641 verts->fColor = color; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1678 verts->fInnerRadius = 0; | 1683 verts->fInnerRadius = 0; |
1679 verts++; | 1684 verts++; |
1680 | 1685 |
1681 verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords [2]); | 1686 verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords [2]); |
1682 verts->fColor = color; | 1687 verts->fColor = color; |
1683 verts->fOffset = SkPoint::Make(maxOffset, 0); | 1688 verts->fOffset = SkPoint::Make(maxOffset, 0); |
1684 verts->fOuterRadius = overstrokeOuterRadius; | 1689 verts->fOuterRadius = overstrokeOuterRadius; |
1685 verts->fInnerRadius = 0; | 1690 verts->fInnerRadius = 0; |
1686 verts++; | 1691 verts++; |
1687 } | 1692 } |
1693 | |
1694 const uint16_t* primIndices = rrect_type_to_indices(args.fType); | |
1695 const int primIndexCount = rrect_type_to_index_count(args.fType); | |
1696 for (int i = 0; i < primIndexCount; ++i) { | |
1697 *indices++ = primIndices[i] + currStartVertex; | |
1698 } | |
1699 | |
1700 currStartVertex += rrect_type_to_vert_count(args.fType); | |
1688 } | 1701 } |
1689 | 1702 |
1690 helper.recordDraw(target, gp); | 1703 // Setup geometry processor |
1704 SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(allFill , | |
1705 false, false, | |
1706 false, localMatrix)); | |
1707 SkASSERT(gp->getVertexStride() == vertexStride); | |
1708 | |
1709 GrMesh mesh; | |
1710 mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex, | |
1711 firstIndex, fVertCount, fIndexCount); | |
1712 target->draw(gp.get(), mesh); | |
1691 } | 1713 } |
1692 | 1714 |
1693 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 1715 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
1694 RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>(); | 1716 RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>(); |
1695 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), | 1717 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(), |
1696 that->bounds(), caps)) { | 1718 that->bounds(), caps)) { |
1697 return false; | 1719 return false; |
1698 } | 1720 } |
1699 | 1721 |
1700 if (fType != that->fType) { | |
1701 return false; | |
1702 } | |
1703 | |
1704 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) { | 1722 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) { |
1705 return false; | 1723 return false; |
1706 } | 1724 } |
1707 | 1725 |
1708 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); | 1726 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); |
1709 this->joinBounds(*that); | 1727 this->joinBounds(*that); |
1728 fVertCount += that->fVertCount; | |
1729 fIndexCount += that->fIndexCount; | |
1710 return true; | 1730 return true; |
1711 } | 1731 } |
1712 | 1732 |
1713 struct Geometry { | 1733 struct Geometry { |
1714 GrColor fColor; | 1734 GrColor fColor; |
1715 SkScalar fInnerRadius; | 1735 SkScalar fInnerRadius; |
1716 SkScalar fOuterRadius; | 1736 SkScalar fOuterRadius; |
1717 SkRect fDevBounds; | 1737 SkRect fDevBounds; |
1738 RRectType fType; | |
1718 }; | 1739 }; |
1719 | 1740 |
1720 RRectType fType; | 1741 int fVertCount; |
1742 int fIndexCount; | |
1721 SkMatrix fViewMatrixIfUsingLocalCoords; | 1743 SkMatrix fViewMatrixIfUsingLocalCoords; |
1722 SkSTArray<1, Geometry, true> fGeoData; | 1744 SkSTArray<1, Geometry, true> fGeoData; |
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 Loading... | |
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 |
OLD | NEW |