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

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

Issue 1087323002: Implement caching in the tessellating path renderer, including strokes. Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: NULL -> nullptr Created 5 years, 4 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 | « src/gpu/GrPathRenderer.h ('k') | tests/TessellatingPathRendererTests.cpp » ('j') | 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 2015 Google Inc. 2 * Copyright 2015 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 "GrTessellatingPathRenderer.h" 8 #include "GrTessellatingPathRenderer.h"
9 9
10 #include "GrBatch.h" 10 #include "GrBatch.h"
(...skipping 1376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 // This path renderer can draw all fill styles, but does not do antialiasing . It can do convex 1387 // This path renderer can draw all fill styles, but does not do antialiasing . It can do convex
1388 // and concave paths, but we'll leave the convex ones to simpler algorithms. 1388 // and concave paths, but we'll leave the convex ones to simpler algorithms.
1389 return args.fStroke->isFillStyle() && !args.fAntiAlias && !args.fPath->isCon vex(); 1389 return args.fStroke->isFillStyle() && !args.fAntiAlias && !args.fPath->isCon vex();
1390 } 1390 }
1391 1391
1392 class TessellatingPathBatch : public GrBatch { 1392 class TessellatingPathBatch : public GrBatch {
1393 public: 1393 public:
1394 1394
1395 static GrBatch* Create(const GrColor& color, 1395 static GrBatch* Create(const GrColor& color,
1396 const SkPath& path, 1396 const SkPath& path,
1397 const GrStrokeInfo* stroke,
1397 const SkMatrix& viewMatrix, 1398 const SkMatrix& viewMatrix,
1398 SkRect clipBounds) { 1399 SkRect clipBounds,
1399 return SkNEW_ARGS(TessellatingPathBatch, (color, path, viewMatrix, clipB ounds)); 1400 const SkPath* origSrcPath,
1401 const GrStrokeInfo* origStrokeInfo) {
1402 return SkNEW_ARGS(TessellatingPathBatch, (color, path, stroke, viewMatri x, clipBounds, origSrcPath, origStrokeInfo));
1400 } 1403 }
1401 1404
1402 const char* name() const override { return "TessellatingPathBatch"; } 1405 const char* name() const override { return "TessellatingPathBatch"; }
1403 1406
1404 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 1407 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
1405 out->setKnownFourComponents(fColor); 1408 out->setKnownFourComponents(fColor);
1406 } 1409 }
1407 1410
1408 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 1411 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
1409 out->setUnknownSingleComponent(); 1412 out->setUnknownSingleComponent();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 return 0; 1481 return 0;
1479 } 1482 }
1480 SkPoint* verts = static_cast<SkPoint*>(vertexBuffer->map()); 1483 SkPoint* verts = static_cast<SkPoint*>(vertexBuffer->map());
1481 LOG("emitting %d verts\n", count); 1484 LOG("emitting %d verts\n", count);
1482 SkPoint* end = polys_to_triangles(polys, fillType, verts); 1485 SkPoint* end = polys_to_triangles(polys, fillType, verts);
1483 vertexBuffer->unmap(); 1486 vertexBuffer->unmap();
1484 int actualCount = static_cast<int>(end - verts); 1487 int actualCount = static_cast<int>(end - verts);
1485 LOG("actual count: %d\n", actualCount); 1488 LOG("actual count: %d\n", actualCount);
1486 SkASSERT(actualCount <= count); 1489 SkASSERT(actualCount <= count);
1487 1490
1488 if (!fPath.isVolatile()) { 1491 TessInfo info;
1489 TessInfo info; 1492 info.fTolerance = isLinear ? 0 : tol;
1490 info.fTolerance = isLinear ? 0 : tol; 1493 info.fCount = actualCount;
1491 info.fCount = actualCount; 1494 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info)));
1492 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info))); 1495 key->setCustomData(data.get());
1493 key->setCustomData(data.get()); 1496 resourceProvider->assignUniqueKeyToResource(*key, vertexBuffer.get());
1494 resourceProvider->assignUniqueKeyToResource(*key, vertexBuffer.get() ); 1497 SkPathPriv::AddGenIDChangeListener(fPathForKey, SkNEW(PathInvalidator(*k ey)));
1495 SkPathPriv::AddGenIDChangeListener(fPath, SkNEW(PathInvalidator(*key )));
1496 }
1497 return actualCount; 1498 return actualCount;
1498 } 1499 }
1499 1500
1500 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override { 1501 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override {
1501 // construct a cache key from the path's genID and the view matrix 1502 // construct a cache key from the path's genID and the view matrix
1502 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; 1503 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
1503 GrUniqueKey key; 1504 GrUniqueKey key;
1504 int clipBoundsSize32 = 1505 int clipBoundsSize32 =
1505 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0; 1506 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0;
1506 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32); 1507 int strokeDataSize32 = fOrigStroke.computeUniqueKeyFragmentData32Cnt();
1507 builder[0] = fPath.getGenerationID(); 1508 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32 + strok eDataSize32);
1508 builder[1] = fPath.getFillType(); 1509 builder[0] = fPathForKey.getGenerationID();
1510 builder[1] = fPathForKey.getFillType();
1509 // For inverse fills, the tessellation is dependent on clip bounds. 1511 // For inverse fills, the tessellation is dependent on clip bounds.
1510 if (fPath.isInverseFillType()) { 1512 if (fPath.isInverseFillType()) {
1511 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); 1513 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds));
1512 } 1514 }
1515 fOrigStroke.asUniqueKeyFragment(&builder[2 + clipBoundsSize32]);
1513 builder.finish(); 1516 builder.finish();
1514 GrResourceProvider* rp = batchTarget->resourceProvider(); 1517 GrResourceProvider* rp = batchTarget->resourceProvider();
1515 SkAutoTUnref<GrVertexBuffer> vertexBuffer(rp->findAndRefTByUniqueKey<GrV ertexBuffer>(key)); 1518 SkAutoTUnref<GrVertexBuffer> vertexBuffer(rp->findAndRefTByUniqueKey<GrV ertexBuffer>(key));
1516 int actualCount; 1519 int actualCount;
1517 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; 1520 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
1518 SkScalar tol = GrPathUtils::scaleToleranceToSrc( 1521 SkScalar tol = GrPathUtils::scaleToleranceToSrc(
1519 screenSpaceTol, fViewMatrix, fPath.getBounds()); 1522 screenSpaceTol, fViewMatrix, fPath.getBounds());
1520 if (!cache_match(vertexBuffer.get(), tol, &actualCount)) { 1523 if (!cache_match(vertexBuffer.get(), tol, &actualCount)) {
1521 actualCount = tessellate(&key, rp, vertexBuffer); 1524 actualCount = tessellate(&key, rp, vertexBuffer);
1522 } 1525 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 batchTarget->draw(vertices); 1557 batchTarget->draw(vertices);
1555 } 1558 }
1556 1559
1557 bool onCombineIfPossible(GrBatch*) override { 1560 bool onCombineIfPossible(GrBatch*) override {
1558 return false; 1561 return false;
1559 } 1562 }
1560 1563
1561 private: 1564 private:
1562 TessellatingPathBatch(const GrColor& color, 1565 TessellatingPathBatch(const GrColor& color,
1563 const SkPath& path, 1566 const SkPath& path,
1567 const GrStrokeInfo* stroke,
1564 const SkMatrix& viewMatrix, 1568 const SkMatrix& viewMatrix,
1565 const SkRect& clipBounds) 1569 const SkRect& clipBounds,
1570 const SkPath* origSrcPath,
1571 const GrStrokeInfo* origStrokeInfo)
1566 : fColor(color) 1572 : fColor(color)
1567 , fPath(path) 1573 , fPath(path)
1574 , fStroke(*stroke)
1568 , fViewMatrix(viewMatrix) 1575 , fViewMatrix(viewMatrix)
1569 , fClipBounds(clipBounds) { 1576 , fClipBounds(clipBounds)
1577 , fPathForKey(origSrcPath ? *origSrcPath : fPath)
1578 , fOrigStroke(origStrokeInfo ? *origStrokeInfo : *stroke) {
1570 this->initClassID<TessellatingPathBatch>(); 1579 this->initClassID<TessellatingPathBatch>();
1571 1580
1572 fBounds = path.getBounds(); 1581 fBounds = path.getBounds();
1573 viewMatrix.mapRect(&fBounds); 1582 viewMatrix.mapRect(&fBounds);
1574 } 1583 }
1575 1584
1576 GrColor fColor; 1585 GrColor fColor;
1577 SkPath fPath; 1586 SkPath fPath;
1587 GrStrokeInfo fStroke;
1578 SkMatrix fViewMatrix; 1588 SkMatrix fViewMatrix;
1579 SkRect fClipBounds; // in source space 1589 SkRect fClipBounds; // in source space
1580 GrPipelineInfo fPipelineInfo; 1590 GrPipelineInfo fPipelineInfo;
1591 SkPath fPathForKey;
1592 GrStrokeInfo fOrigStroke;
1581 }; 1593 };
1582 1594
1583 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) { 1595 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
1584 SkASSERT(!args.fAntiAlias); 1596 SkASSERT(!args.fAntiAlias);
1585 const GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget(); 1597 const GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget();
1586 if (NULL == rt) { 1598 if (NULL == rt) {
1587 return false; 1599 return false;
1588 } 1600 }
1589 1601
1590 SkIRect clipBoundsI; 1602 SkIRect clipBoundsI;
1591 args.fPipelineBuilder->clip().getConservativeBounds(rt, &clipBoundsI); 1603 args.fPipelineBuilder->clip().getConservativeBounds(rt, &clipBoundsI);
1592 SkRect clipBounds = SkRect::Make(clipBoundsI); 1604 SkRect clipBounds = SkRect::Make(clipBoundsI);
1593 SkMatrix vmi; 1605 SkMatrix vmi;
1594 if (!args.fViewMatrix->invert(&vmi)) { 1606 if (!args.fViewMatrix->invert(&vmi)) {
1595 return false; 1607 return false;
1596 } 1608 }
1597 vmi.mapRect(&clipBounds); 1609 vmi.mapRect(&clipBounds);
1598 SkAutoTUnref<GrBatch> batch(TessellatingPathBatch::Create(args.fColor, *args .fPath, 1610 SkAutoTUnref<GrBatch> batch(TessellatingPathBatch::Create(args.fColor, *args .fPath,
1599 *args.fViewMatrix, clipBounds)); 1611 args.fStroke, *arg s.fViewMatrix, clipBounds, args.fOrigSrcPath, args.fOrigStrokeInfo));
1600 args.fTarget->drawBatch(*args.fPipelineBuilder, batch); 1612 args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
1601 1613
1602 return true; 1614 return true;
1603 } 1615 }
1604 1616
1605 //////////////////////////////////////////////////////////////////////////////// /////////////////// 1617 //////////////////////////////////////////////////////////////////////////////// ///////////////////
1606 1618
1607 #ifdef GR_TEST_UTILS 1619 #ifdef GR_TEST_UTILS
1608 1620
1609 BATCH_TEST_DEFINE(TesselatingPathBatch) { 1621 BATCH_TEST_DEFINE(TesselatingPathBatch) {
1610 GrColor color = GrRandomColor(random); 1622 GrColor color = GrRandomColor(random);
1611 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); 1623 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
1612 SkPath path = GrTest::TestPath(random); 1624 SkPath path = GrTest::TestPath(random);
1625 GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
1613 SkRect clipBounds = GrTest::TestRect(random); 1626 SkRect clipBounds = GrTest::TestRect(random);
1614 SkMatrix vmi; 1627 SkMatrix vmi;
1615 bool result = viewMatrix.invert(&vmi); 1628 bool result = viewMatrix.invert(&vmi);
1616 if (!result) { 1629 if (!result) {
1617 SkFAIL("Cannot invert matrix\n"); 1630 SkFAIL("Cannot invert matrix\n");
1618 } 1631 }
1619 vmi.mapRect(&clipBounds); 1632 vmi.mapRect(&clipBounds);
1620 return TessellatingPathBatch::Create(color, path, viewMatrix, clipBounds); 1633 return TessellatingPathBatch::Create(color, path, &stroke, viewMatrix, clipB ounds, nullptr, nullptr);
1621 } 1634 }
1622 1635
1623 #endif 1636 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrPathRenderer.h ('k') | tests/TessellatingPathRendererTests.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698