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

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

Issue 1260363007: Revert "Implement caching of filled paths in the tessellated path renderer." (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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/core/SkPathRef.cpp ('k') | tests/PathTest.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"
11 #include "GrBatchTarget.h" 11 #include "GrBatchTarget.h"
12 #include "GrBatchTest.h" 12 #include "GrBatchTest.h"
13 #include "GrDefaultGeoProcFactory.h" 13 #include "GrDefaultGeoProcFactory.h"
14 #include "GrPathUtils.h" 14 #include "GrPathUtils.h"
15 #include "GrVertices.h" 15 #include "GrVertices.h"
16 #include "GrResourceCache.h"
17 #include "GrResourceProvider.h"
18 #include "SkChunkAlloc.h" 16 #include "SkChunkAlloc.h"
19 #include "SkGeometry.h" 17 #include "SkGeometry.h"
20 18
21 #include <stdio.h> 19 #include <stdio.h>
22 20
23 /* 21 /*
24 * This path renderer tessellates the path into triangles, uploads the triangles to a 22 * This path renderer tessellates the path into triangles, uploads the triangles to a
25 * vertex buffer, and renders them with a single draw call. It does not currentl y do 23 * vertex buffer, and renders them with a single draw call. It does not currentl y do
26 * antialiasing, so it must be used in conjunction with multisampling. 24 * antialiasing, so it must be used in conjunction with multisampling.
27 * 25 *
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 const SkPoint s = { SkScalarAve(r[0].fX, r[1].fX), SkScalarAve(r[0].fY, r[1] .fY) }; 531 const SkPoint s = { SkScalarAve(r[0].fX, r[1].fX), SkScalarAve(r[0].fY, r[1] .fY) };
534 pointsLeft >>= 1; 532 pointsLeft >>= 1;
535 prev = generate_cubic_points(p0, q[0], r[0], s, tolSqd, prev, head, pointsLe ft, alloc); 533 prev = generate_cubic_points(p0, q[0], r[0], s, tolSqd, prev, head, pointsLe ft, alloc);
536 prev = generate_cubic_points(s, r[1], q[2], p3, tolSqd, prev, head, pointsLe ft, alloc); 534 prev = generate_cubic_points(s, r[1], q[2], p3, tolSqd, prev, head, pointsLe ft, alloc);
537 return prev; 535 return prev;
538 } 536 }
539 537
540 // Stage 1: convert the input path to a set of linear contours (linked list of V ertices). 538 // Stage 1: convert the input path to a set of linear contours (linked list of V ertices).
541 539
542 void path_to_contours(const SkPath& path, SkScalar tolerance, const SkRect& clip Bounds, 540 void path_to_contours(const SkPath& path, SkScalar tolerance, const SkRect& clip Bounds,
543 Vertex** contours, SkChunkAlloc& alloc, bool *isLinear) { 541 Vertex** contours, SkChunkAlloc& alloc) {
544 542
545 SkScalar toleranceSqd = tolerance * tolerance; 543 SkScalar toleranceSqd = tolerance * tolerance;
546 544
547 SkPoint pts[4]; 545 SkPoint pts[4];
548 bool done = false; 546 bool done = false;
549 *isLinear = true;
550 SkPath::Iter iter(path, false); 547 SkPath::Iter iter(path, false);
551 Vertex* prev = NULL; 548 Vertex* prev = NULL;
552 Vertex* head = NULL; 549 Vertex* head = NULL;
553 if (path.isInverseFillType()) { 550 if (path.isInverseFillType()) {
554 SkPoint quad[4]; 551 SkPoint quad[4];
555 clipBounds.toQuad(quad); 552 clipBounds.toQuad(quad);
556 for (int i = 3; i >= 0; i--) { 553 for (int i = 3; i >= 0; i--) {
557 prev = append_point_to_contour(quad[i], prev, &head, alloc); 554 prev = append_point_to_contour(quad[i], prev, &head, alloc);
558 } 555 }
559 head->fPrev = prev; 556 head->fPrev = prev;
560 prev->fNext = head; 557 prev->fNext = head;
561 *contours++ = head; 558 *contours++ = head;
562 head = prev = NULL; 559 head = prev = NULL;
563 } 560 }
564 SkAutoConicToQuads converter; 561 SkAutoConicToQuads converter;
565 while (!done) { 562 while (!done) {
566 SkPath::Verb verb = iter.next(pts); 563 SkPath::Verb verb = iter.next(pts);
567 switch (verb) { 564 switch (verb) {
568 case SkPath::kConic_Verb: { 565 case SkPath::kConic_Verb: {
569 SkScalar weight = iter.conicWeight(); 566 SkScalar weight = iter.conicWeight();
570 const SkPoint* quadPts = converter.computeQuads(pts, weight, tol eranceSqd); 567 const SkPoint* quadPts = converter.computeQuads(pts, weight, tol eranceSqd);
571 for (int i = 0; i < converter.countQuads(); ++i) { 568 for (int i = 0; i < converter.countQuads(); ++i) {
572 int pointsLeft = GrPathUtils::quadraticPointCount(quadPts, t olerance); 569 int pointsLeft = GrPathUtils::quadraticPointCount(quadPts, t olerance);
573 prev = generate_quadratic_points(quadPts[0], quadPts[1], qua dPts[2], 570 prev = generate_quadratic_points(quadPts[0], quadPts[1], qua dPts[2],
574 toleranceSqd, prev, &head, pointsLeft, alloc); 571 toleranceSqd, prev, &head, pointsLeft, alloc);
575 quadPts += 2; 572 quadPts += 2;
576 } 573 }
577 *isLinear = false;
578 break; 574 break;
579 } 575 }
580 case SkPath::kMove_Verb: 576 case SkPath::kMove_Verb:
581 if (head) { 577 if (head) {
582 head->fPrev = prev; 578 head->fPrev = prev;
583 prev->fNext = head; 579 prev->fNext = head;
584 *contours++ = head; 580 *contours++ = head;
585 } 581 }
586 head = prev = NULL; 582 head = prev = NULL;
587 prev = append_point_to_contour(pts[0], prev, &head, alloc); 583 prev = append_point_to_contour(pts[0], prev, &head, alloc);
588 break; 584 break;
589 case SkPath::kLine_Verb: { 585 case SkPath::kLine_Verb: {
590 prev = append_point_to_contour(pts[1], prev, &head, alloc); 586 prev = append_point_to_contour(pts[1], prev, &head, alloc);
591 break; 587 break;
592 } 588 }
593 case SkPath::kQuad_Verb: { 589 case SkPath::kQuad_Verb: {
594 int pointsLeft = GrPathUtils::quadraticPointCount(pts, tolerance ); 590 int pointsLeft = GrPathUtils::quadraticPointCount(pts, tolerance );
595 prev = generate_quadratic_points(pts[0], pts[1], pts[2], toleran ceSqd, prev, 591 prev = generate_quadratic_points(pts[0], pts[1], pts[2], toleran ceSqd, prev,
596 &head, pointsLeft, alloc); 592 &head, pointsLeft, alloc);
597 *isLinear = false;
598 break; 593 break;
599 } 594 }
600 case SkPath::kCubic_Verb: { 595 case SkPath::kCubic_Verb: {
601 int pointsLeft = GrPathUtils::cubicPointCount(pts, tolerance); 596 int pointsLeft = GrPathUtils::cubicPointCount(pts, tolerance);
602 prev = generate_cubic_points(pts[0], pts[1], pts[2], pts[3], 597 prev = generate_cubic_points(pts[0], pts[1], pts[2], pts[3],
603 toleranceSqd, prev, &head, pointsLeft, alloc); 598 toleranceSqd, prev, &head, pointsLeft, alloc);
604 *isLinear = false;
605 break; 599 break;
606 } 600 }
607 case SkPath::kClose_Verb: 601 case SkPath::kClose_Verb:
608 if (head) { 602 if (head) {
609 head->fPrev = prev; 603 head->fPrev = prev;
610 prev->fNext = head; 604 prev->fNext = head;
611 *contours++ = head; 605 *contours++ = head;
612 } 606 }
613 head = prev = NULL; 607 head = prev = NULL;
614 break; 608 break;
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 SkPoint* polys_to_triangles(Poly* polys, SkPath::FillType fillType, SkPoint* dat a) { 1322 SkPoint* polys_to_triangles(Poly* polys, SkPath::FillType fillType, SkPoint* dat a) {
1329 SkPoint* d = data; 1323 SkPoint* d = data;
1330 for (Poly* poly = polys; poly; poly = poly->fNext) { 1324 for (Poly* poly = polys; poly; poly = poly->fNext) {
1331 if (apply_fill_type(fillType, poly->fWinding)) { 1325 if (apply_fill_type(fillType, poly->fWinding)) {
1332 d = poly->emit(d); 1326 d = poly->emit(d);
1333 } 1327 }
1334 } 1328 }
1335 return d; 1329 return d;
1336 } 1330 }
1337 1331
1338 struct TessInfo {
1339 SkScalar fTolerance;
1340 int fCount;
1341 };
1342
1343 bool cache_match(GrVertexBuffer* vertexBuffer, SkScalar tol, int* actualCount) {
1344 if (!vertexBuffer) {
1345 return false;
1346 }
1347 const SkData* data = vertexBuffer->getUniqueKey().getCustomData();
1348 SkASSERT(data);
1349 const TessInfo* info = static_cast<const TessInfo*>(data->data());
1350 if (info->fTolerance == 0 || info->fTolerance < 3.0f * tol) {
1351 *actualCount = info->fCount;
1352 return true;
1353 }
1354 return false;
1355 }
1356
1357 }; 1332 };
1358 1333
1359 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { 1334 GrTessellatingPathRenderer::GrTessellatingPathRenderer() {
1360 } 1335 }
1361 1336
1362 GrPathRenderer::StencilSupport GrTessellatingPathRenderer::onGetStencilSupport( 1337 GrPathRenderer::StencilSupport GrTessellatingPathRenderer::onGetStencilSupport(
1363 const GrDrawTarget*, 1338 const GrDrawTarget*,
1364 const GrPipelineBuil der*, 1339 const GrPipelineBuil der*,
1365 const SkPath&, 1340 const SkPath&,
1366 const GrStrokeInfo&) const { 1341 const GrStrokeInfo&) const {
1367 return GrPathRenderer::kNoSupport_StencilSupport; 1342 return GrPathRenderer::kNoSupport_StencilSupport;
1368 } 1343 }
1369 1344
1370 namespace {
1371
1372 // When the SkPathRef genID changes, invalidate a corresponding GrResource descr ibed by key.
1373 class PathInvalidator : public SkPathRef::GenIDChangeListener {
1374 public:
1375 explicit PathInvalidator(const GrUniqueKey& key) : fMsg(key) {}
1376 private:
1377 GrUniqueKeyInvalidatedMessage fMsg;
1378
1379 void onChange() override {
1380 SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg);
1381 }
1382 };
1383
1384 } // namespace
1385
1386 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t { 1345 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t {
1387 // This path renderer can draw all fill styles, but does not do antialiasing . It can do convex 1346 // 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. 1347 // and concave paths, but we'll leave the convex ones to simpler algorithms.
1389 return args.fStroke->isFillStyle() && !args.fAntiAlias && !args.fPath->isCon vex(); 1348 return args.fStroke->isFillStyle() && !args.fAntiAlias && !args.fPath->isCon vex();
1390 } 1349 }
1391 1350
1392 class TessellatingPathBatch : public GrBatch { 1351 class TessellatingPathBatch : public GrBatch {
1393 public: 1352 public:
1394 1353
1395 static GrBatch* Create(const GrColor& color, 1354 static GrBatch* Create(const GrColor& color,
(...skipping 15 matching lines...) Expand all
1411 1370
1412 void initBatchTracker(const GrPipelineInfo& init) override { 1371 void initBatchTracker(const GrPipelineInfo& init) override {
1413 // Handle any color overrides 1372 // Handle any color overrides
1414 if (!init.readsColor()) { 1373 if (!init.readsColor()) {
1415 fColor = GrColor_ILLEGAL; 1374 fColor = GrColor_ILLEGAL;
1416 } 1375 }
1417 init.getOverrideColorIfSet(&fColor); 1376 init.getOverrideColorIfSet(&fColor);
1418 fPipelineInfo = init; 1377 fPipelineInfo = init;
1419 } 1378 }
1420 1379
1421 int tessellate(GrUniqueKey* key, 1380 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override {
1422 GrResourceProvider* resourceProvider,
1423 SkAutoTUnref<GrVertexBuffer>& vertexBuffer) {
1424 SkRect pathBounds = fPath.getBounds(); 1381 SkRect pathBounds = fPath.getBounds();
1425 Comparator c; 1382 Comparator c;
1426 if (pathBounds.width() > pathBounds.height()) { 1383 if (pathBounds.width() > pathBounds.height()) {
1427 c.sweep_lt = sweep_lt_horiz; 1384 c.sweep_lt = sweep_lt_horiz;
1428 c.sweep_gt = sweep_gt_horiz; 1385 c.sweep_gt = sweep_gt_horiz;
1429 } else { 1386 } else {
1430 c.sweep_lt = sweep_lt_vert; 1387 c.sweep_lt = sweep_lt_vert;
1431 c.sweep_gt = sweep_gt_vert; 1388 c.sweep_gt = sweep_gt_vert;
1432 } 1389 }
1433 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; 1390 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
1434 SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMat rix, pathBounds); 1391 SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMat rix, pathBounds);
1435 int contourCnt; 1392 int contourCnt;
1436 int maxPts = GrPathUtils::worstCasePointCount(fPath, &contourCnt, tol); 1393 int maxPts = GrPathUtils::worstCasePointCount(fPath, &contourCnt, tol);
1437 if (maxPts <= 0) { 1394 if (maxPts <= 0) {
1438 return 0; 1395 return;
1439 } 1396 }
1440 if (maxPts > ((int)SK_MaxU16 + 1)) { 1397 if (maxPts > ((int)SK_MaxU16 + 1)) {
1441 SkDebugf("Path not rendered, too many verts (%d)\n", maxPts); 1398 SkDebugf("Path not rendered, too many verts (%d)\n", maxPts);
1442 return 0; 1399 return;
1443 } 1400 }
1444 SkPath::FillType fillType = fPath.getFillType(); 1401 SkPath::FillType fillType = fPath.getFillType();
1445 if (SkPath::IsInverseFillType(fillType)) { 1402 if (SkPath::IsInverseFillType(fillType)) {
1446 contourCnt++; 1403 contourCnt++;
1447 } 1404 }
1448 1405
1449 LOG("got %d pts, %d contours\n", maxPts, contourCnt); 1406 LOG("got %d pts, %d contours\n", maxPts, contourCnt);
1407 SkAutoTUnref<const GrGeometryProcessor> gp;
1408 {
1409 using namespace GrDefaultGeoProcFactory;
1410
1411 Color color(fColor);
1412 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ?
1413 LocalCoords::kUsePosition_Type :
1414 LocalCoords::kUnused_Type);
1415 Coverage::Type coverageType;
1416 if (fPipelineInfo.readsCoverage()) {
1417 coverageType = Coverage::kSolid_Type;
1418 } else {
1419 coverageType = Coverage::kNone_Type;
1420 }
1421 Coverage coverage(coverageType);
1422 gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoord s,
1423 fViewMatrix));
1424 }
1425 batchTarget->initDraw(gp, pipeline);
1426
1450 SkAutoTDeleteArray<Vertex*> contours(SkNEW_ARRAY(Vertex *, contourCnt)); 1427 SkAutoTDeleteArray<Vertex*> contours(SkNEW_ARRAY(Vertex *, contourCnt));
1451 1428
1452 // For the initial size of the chunk allocator, estimate based on the po int count: 1429 // For the initial size of the chunk allocator, estimate based on the po int count:
1453 // one vertex per point for the initial passes, plus two for the vertice s in the 1430 // one vertex per point for the initial passes, plus two for the vertice s in the
1454 // resulting Polys, since the same point may end up in two Polys. Assum e minimal 1431 // resulting Polys, since the same point may end up in two Polys. Assum e minimal
1455 // connectivity of one Edge per Vertex (will grow for intersections). 1432 // connectivity of one Edge per Vertex (will grow for intersections).
1456 SkChunkAlloc alloc(maxPts * (3 * sizeof(Vertex) + sizeof(Edge))); 1433 SkChunkAlloc alloc(maxPts * (3 * sizeof(Vertex) + sizeof(Edge)));
1457 bool isLinear; 1434 path_to_contours(fPath, tol, fClipBounds, contours.get(), alloc);
1458 path_to_contours(fPath, tol, fClipBounds, contours.get(), alloc, &isLine ar);
1459 Poly* polys; 1435 Poly* polys;
1460 polys = contours_to_polys(contours.get(), contourCnt, c, alloc); 1436 polys = contours_to_polys(contours.get(), contourCnt, c, alloc);
1461 int count = 0; 1437 int count = 0;
1462 for (Poly* poly = polys; poly; poly = poly->fNext) { 1438 for (Poly* poly = polys; poly; poly = poly->fNext) {
1463 if (apply_fill_type(fillType, poly->fWinding) && poly->fCount >= 3) { 1439 if (apply_fill_type(fillType, poly->fWinding) && poly->fCount >= 3) {
1464 count += (poly->fCount - 2) * (WIREFRAME ? 6 : 3); 1440 count += (poly->fCount - 2) * (WIREFRAME ? 6 : 3);
1465 } 1441 }
1466 } 1442 }
1467 if (0 == count) { 1443 if (0 == count) {
1468 return 0; 1444 return;
1469 } 1445 }
1470 1446
1471 size_t size = count * sizeof(SkPoint); 1447 size_t stride = gp->getVertexStride();
1472 if (!vertexBuffer.get() || vertexBuffer->gpuMemorySize() < size) { 1448 SkASSERT(stride == sizeof(SkPoint));
1473 vertexBuffer.reset(resourceProvider->createVertexBuffer( 1449 const GrVertexBuffer* vertexBuffer;
1474 size, GrResourceProvider::kStatic_BufferUsage, 0)); 1450 int firstVertex;
1451 SkPoint* verts = static_cast<SkPoint*>(
1452 batchTarget->makeVertSpace(stride, count, &vertexBuffer, &firstVerte x));
1453 if (!verts) {
1454 SkDebugf("Could not allocate vertices\n");
1455 return;
1475 } 1456 }
1476 if (!vertexBuffer.get()) { 1457
1477 SkDebugf("Could not allocate vertices\n");
1478 return 0;
1479 }
1480 SkPoint* verts = static_cast<SkPoint*>(vertexBuffer->map());
1481 LOG("emitting %d verts\n", count); 1458 LOG("emitting %d verts\n", count);
1482 SkPoint* end = polys_to_triangles(polys, fillType, verts); 1459 SkPoint* end = polys_to_triangles(polys, fillType, verts);
1483 vertexBuffer->unmap();
1484 int actualCount = static_cast<int>(end - verts); 1460 int actualCount = static_cast<int>(end - verts);
1485 LOG("actual count: %d\n", actualCount); 1461 LOG("actual count: %d\n", actualCount);
1486 SkASSERT(actualCount <= count); 1462 SkASSERT(actualCount <= count);
1487 1463
1488 if (!fPath.isVolatile()) {
1489 TessInfo info;
1490 info.fTolerance = isLinear ? 0 : tol;
1491 info.fCount = actualCount;
1492 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info)));
1493 key->setCustomData(data.get());
1494 resourceProvider->assignUniqueKeyToResource(*key, vertexBuffer.get() );
1495 SkPathPriv::AddGenIDChangeListener(fPath, SkNEW(PathInvalidator(*key )));
1496 }
1497 return actualCount;
1498 }
1499
1500 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) override {
1501 // construct a cache key from the path's genID and the view matrix
1502 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
1503 GrUniqueKey key;
1504 GrUniqueKey::Builder builder(&key, kDomain, 2);
1505 builder[0] = fPath.getGenerationID();
1506 builder[1] = fPath.getFillType();
1507 builder.finish();
1508 GrResourceProvider* rp = batchTarget->resourceProvider();
1509 SkAutoTUnref<GrVertexBuffer> vertexBuffer(rp->findAndRefTByUniqueKey<GrV ertexBuffer>(key));
1510 int actualCount;
1511 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
1512 SkScalar tol = GrPathUtils::scaleToleranceToSrc(
1513 screenSpaceTol, fViewMatrix, fPath.getBounds());
1514 if (!cache_match(vertexBuffer.get(), tol, &actualCount)) {
1515 actualCount = tessellate(&key, rp, vertexBuffer);
1516 }
1517
1518 if (actualCount == 0) {
1519 return;
1520 }
1521
1522 SkAutoTUnref<const GrGeometryProcessor> gp;
1523 {
1524 using namespace GrDefaultGeoProcFactory;
1525
1526 Color color(fColor);
1527 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ?
1528 LocalCoords::kUsePosition_Type :
1529 LocalCoords::kUnused_Type);
1530 Coverage::Type coverageType;
1531 if (fPipelineInfo.readsCoverage()) {
1532 coverageType = Coverage::kSolid_Type;
1533 } else {
1534 coverageType = Coverage::kNone_Type;
1535 }
1536 Coverage coverage(coverageType);
1537 gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoord s,
1538 fViewMatrix));
1539 }
1540
1541 batchTarget->initDraw(gp, pipeline);
1542 SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
1543
1544 GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType 1464 GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType
1545 : kTriangles_GrPrimitiveType; 1465 : kTriangles_GrPrimitiveType;
1546 GrVertices vertices; 1466 GrVertices vertices;
1547 vertices.init(primitiveType, vertexBuffer.get(), 0, actualCount); 1467 vertices.init(primitiveType, vertexBuffer, firstVertex, actualCount);
1548 batchTarget->draw(vertices); 1468 batchTarget->draw(vertices);
1469
1470 batchTarget->putBackVertices((size_t)(count - actualCount), stride);
1471 return;
1549 } 1472 }
1550 1473
1551 bool onCombineIfPossible(GrBatch*) override { 1474 bool onCombineIfPossible(GrBatch*) override {
1552 return false; 1475 return false;
1553 } 1476 }
1554 1477
1555 private: 1478 private:
1556 TessellatingPathBatch(const GrColor& color, 1479 TessellatingPathBatch(const GrColor& color,
1557 const SkPath& path, 1480 const SkPath& path,
1558 const SkMatrix& viewMatrix, 1481 const SkMatrix& viewMatrix,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 SkMatrix vmi; 1531 SkMatrix vmi;
1609 bool result = viewMatrix.invert(&vmi); 1532 bool result = viewMatrix.invert(&vmi);
1610 if (!result) { 1533 if (!result) {
1611 SkFAIL("Cannot invert matrix\n"); 1534 SkFAIL("Cannot invert matrix\n");
1612 } 1535 }
1613 vmi.mapRect(&clipBounds); 1536 vmi.mapRect(&clipBounds);
1614 return TessellatingPathBatch::Create(color, path, viewMatrix, clipBounds); 1537 return TessellatingPathBatch::Create(color, path, viewMatrix, clipBounds);
1615 } 1538 }
1616 1539
1617 #endif 1540 #endif
OLDNEW
« no previous file with comments | « src/core/SkPathRef.cpp ('k') | tests/PathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698