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

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

Issue 2127673002: Consolidate handling of infinitely thin primitives and aa bloat handing WRT batch bounds (Closed) Base URL: https://skia.googlesource.com/skia.git@AAStrokeRect
Patch Set: comments Created 4 years, 5 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
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 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 // rendered and the outset ensures the box will cover all partially cove red by the circle. 564 // rendered and the outset ensures the box will cover all partially cove red by the circle.
565 outerRadius += SK_ScalarHalf; 565 outerRadius += SK_ScalarHalf;
566 innerRadius -= SK_ScalarHalf; 566 innerRadius -= SK_ScalarHalf;
567 567
568 fGeoData.emplace_back(Geometry { 568 fGeoData.emplace_back(Geometry {
569 color, 569 color,
570 innerRadius, 570 innerRadius,
571 outerRadius, 571 outerRadius,
572 SkRect::MakeLTRB(center.fX - outerRadius, center.fY - outerRadius, 572 SkRect::MakeLTRB(center.fX - outerRadius, center.fY - outerRadius,
573 center.fX + outerRadius, center.fY + outerRadius) 573 center.fX + outerRadius, center.fY + outerRadius)
574 }); 574 });
robertphillips 2016/07/07 20:26:42 Isn't this wrong for stroked circles ?
bsalomon 2016/07/07 23:40:57 Ah, yes. Fixed.
575 this->setBounds(fGeoData.back().fDevBounds); 575 // Use the original radius for the bounds so that it does not include th e AA bloat
576 this->setBounds({center.fX - radius, center.fY - radius,
577 center.fX + radius, center.fY + radius},
578 HasAABloat::kYes, IsZeroArea::kNo);
576 fStroked = isStrokeOnly && innerRadius > 0; 579 fStroked = isStrokeOnly && innerRadius > 0;
577 } 580 }
578 581
579 const char* name() const override { return "CircleBatch"; } 582 const char* name() const override { return "CircleBatch"; }
580 583
581 SkString dumpInfo() const override { 584 SkString dumpInfo() const override {
582 SkString string; 585 SkString string;
583 for (int i = 0; i < fGeoData.count(); ++i) { 586 for (int i = 0; i < fGeoData.count(); ++i) {
584 string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %. 2f]," 587 string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %. 2f],"
585 "InnerRad: %.2f, OuterRad: %.2f\n", 588 "InnerRad: %.2f, OuterRad: %.2f\n",
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 681
679 if (this->fStroked != that->fStroked) { 682 if (this->fStroked != that->fStroked) {
680 return false; 683 return false;
681 } 684 }
682 685
683 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) { 686 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) {
684 return false; 687 return false;
685 } 688 }
686 689
687 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 690 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin());
688 this->joinBounds(that->bounds()); 691 this->joinBounds(*that);
689 return true; 692 return true;
690 } 693 }
691 694
692 struct Geometry { 695 struct Geometry {
693 GrColor fColor; 696 GrColor fColor;
694 SkScalar fInnerRadius; 697 SkScalar fInnerRadius;
695 SkScalar fOuterRadius; 698 SkScalar fOuterRadius;
696 SkRect fDevBounds; 699 SkRect fDevBounds;
697 }; 700 };
698 701
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 batch->fGeoData.emplace_back(Geometry { 773 batch->fGeoData.emplace_back(Geometry {
771 color, 774 color,
772 xRadius, 775 xRadius,
773 yRadius, 776 yRadius,
774 innerXRadius, 777 innerXRadius,
775 innerYRadius, 778 innerYRadius,
776 SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRadius, 779 SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRadius,
777 center.fX + xRadius, center.fY + yRadius) 780 center.fX + xRadius, center.fY + yRadius)
778 }); 781 });
779 782
783 batch->setBounds(batch->fGeoData.back().fDevBounds, HasAABloat::kYes, Is ZeroArea::kNo);
784
780 // Outset bounds to include half-pixel width antialiasing. 785 // Outset bounds to include half-pixel width antialiasing.
781 batch->fGeoData[0].fDevBounds.outset(SK_ScalarHalf, SK_ScalarHalf); 786 batch->fGeoData[0].fDevBounds.outset(SK_ScalarHalf, SK_ScalarHalf);
782 787
783 batch->fStroked = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; 788 batch->fStroked = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0;
784 batch->fViewMatrixIfUsingLocalCoords = viewMatrix; 789 batch->fViewMatrixIfUsingLocalCoords = viewMatrix;
785 batch->setBounds(batch->fGeoData.back().fDevBounds);
786 return batch; 790 return batch;
787 } 791 }
788 792
789 const char* name() const override { return "EllipseBatch"; } 793 const char* name() const override { return "EllipseBatch"; }
790 794
791 void computePipelineOptimizations(GrInitInvariantOutput* color, 795 void computePipelineOptimizations(GrInitInvariantOutput* color,
792 GrInitInvariantOutput* coverage, 796 GrInitInvariantOutput* coverage,
793 GrBatchToXPOverrides* overrides) const ove rride { 797 GrBatchToXPOverrides* overrides) const ove rride {
794 // When this is called on a batch, there is only one geometry bundle 798 // When this is called on a batch, there is only one geometry bundle
795 color->setKnownFourComponents(fGeoData[0].fColor); 799 color->setKnownFourComponents(fGeoData[0].fColor);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 891
888 if (fStroked != that->fStroked) { 892 if (fStroked != that->fStroked) {
889 return false; 893 return false;
890 } 894 }
891 895
892 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) { 896 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) {
893 return false; 897 return false;
894 } 898 }
895 899
896 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 900 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin());
897 this->joinBounds(that->bounds()); 901 this->joinBounds(*that);
898 return true; 902 return true;
899 } 903 }
900 904
901 struct Geometry { 905 struct Geometry {
902 GrColor fColor; 906 GrColor fColor;
903 SkScalar fXRadius; 907 SkScalar fXRadius;
904 SkScalar fYRadius; 908 SkScalar fYRadius;
905 SkScalar fInnerXRadius; 909 SkScalar fInnerXRadius;
906 SkScalar fInnerYRadius; 910 SkScalar fInnerYRadius;
907 SkRect fDevBounds; 911 SkRect fDevBounds;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 xRadius, 990 xRadius,
987 yRadius, 991 yRadius,
988 innerXRadius, 992 innerXRadius,
989 innerYRadius, 993 innerYRadius,
990 geoDx, 994 geoDx,
991 geoDy, 995 geoDy,
992 dieStyle, 996 dieStyle,
993 SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY - yRadius - geoDy, 997 SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY - yRadius - geoDy,
994 center.fX + xRadius + geoDx, center.fY + yRadius + geoDy) 998 center.fX + xRadius + geoDx, center.fY + yRadius + geoDy)
995 }); 999 });
996 SkRect devBounds = batch->fGeoData.back().fBounds; 1000 batch->setTransformedBounds(batch->fGeoData[0].fBounds, viewMatrix, HasA ABloat::kYes,
997 viewMatrix.mapRect(&devBounds); 1001 IsZeroArea::kNo);
998 batch->setBounds(devBounds);
999 return batch; 1002 return batch;
1000 } 1003 }
1001 1004
1002 const char* name() const override { return "DIEllipseBatch"; } 1005 const char* name() const override { return "DIEllipseBatch"; }
1003 1006
1004 void computePipelineOptimizations(GrInitInvariantOutput* color, 1007 void computePipelineOptimizations(GrInitInvariantOutput* color,
1005 GrInitInvariantOutput* coverage, 1008 GrInitInvariantOutput* coverage,
1006 GrBatchToXPOverrides* overrides) const ove rride { 1009 GrBatchToXPOverrides* overrides) const ove rride {
1007 // When this is called on a batch, there is only one geometry bundle 1010 // When this is called on a batch, there is only one geometry bundle
1008 color->setKnownFourComponents(fGeoData[0].fColor); 1011 color->setKnownFourComponents(fGeoData[0].fColor);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 if (this->style() != that->style()) { 1088 if (this->style() != that->style()) {
1086 return false; 1089 return false;
1087 } 1090 }
1088 1091
1089 // TODO rewrite to allow positioning on CPU 1092 // TODO rewrite to allow positioning on CPU
1090 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 1093 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
1091 return false; 1094 return false;
1092 } 1095 }
1093 1096
1094 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 1097 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin());
1095 this->joinBounds(that->bounds()); 1098 this->joinBounds(*that);
1096 return true; 1099 return true;
1097 } 1100 }
1098 1101
1099 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 1102 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
1100 DIEllipseStyle style() const { return fGeoData[0].fStyle; } 1103 DIEllipseStyle style() const { return fGeoData[0].fStyle; }
1101 1104
1102 struct Geometry { 1105 struct Geometry {
1103 SkMatrix fViewMatrix; 1106 SkMatrix fViewMatrix;
1104 GrColor fColor; 1107 GrColor fColor;
1105 SkScalar fXRadius; 1108 SkScalar fXRadius;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 } 1198 }
1196 1199
1197 // The radii are outset for two reasons. First, it allows the shader to simply perform 1200 // The radii are outset for two reasons. First, it allows the shader to simply perform
1198 // simpler computation because the computed alpha is zero, rather than 5 0%, at the radius. 1201 // simpler computation because the computed alpha is zero, rather than 5 0%, at the radius.
1199 // Second, the outer radius is used to compute the verts of the bounding box that is 1202 // Second, the outer radius is used to compute the verts of the bounding box that is
1200 // rendered and the outset ensures the box will cover all partially cove red by the rrect 1203 // rendered and the outset ensures the box will cover all partially cove red by the rrect
1201 // corners. 1204 // corners.
1202 outerRadius += SK_ScalarHalf; 1205 outerRadius += SK_ScalarHalf;
1203 innerRadius -= SK_ScalarHalf; 1206 innerRadius -= SK_ScalarHalf;
1204 1207
1205 // Expand the rect so all the pixels will be captured. 1208 this->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
1209
1210 // Expand the rect for aa to generate correct vertices.
1206 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 1211 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1207 1212
1208 fGeoData.emplace_back(Geometry { color, innerRadius, outerRadius, bounds }); 1213 fGeoData.emplace_back(Geometry { color, innerRadius, outerRadius, bounds });
1209 this->setBounds(bounds);
1210 } 1214 }
1211 1215
1212 const char* name() const override { return "RRectCircleBatch"; } 1216 const char* name() const override { return "RRectCircleBatch"; }
1213 1217
1214 void computePipelineOptimizations(GrInitInvariantOutput* color, 1218 void computePipelineOptimizations(GrInitInvariantOutput* color,
1215 GrInitInvariantOutput* coverage, 1219 GrInitInvariantOutput* coverage,
1216 GrBatchToXPOverrides* overrides) const ove rride { 1220 GrBatchToXPOverrides* overrides) const ove rride {
1217 // When this is called on a batch, there is only one geometry bundle 1221 // When this is called on a batch, there is only one geometry bundle
1218 color->setKnownFourComponents(fGeoData[0].fColor); 1222 color->setKnownFourComponents(fGeoData[0].fColor);
1219 coverage->setUnknownSingleComponent(); 1223 coverage->setUnknownSingleComponent();
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 1321
1318 if (fStroked != that->fStroked) { 1322 if (fStroked != that->fStroked) {
1319 return false; 1323 return false;
1320 } 1324 }
1321 1325
1322 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) { 1326 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) {
1323 return false; 1327 return false;
1324 } 1328 }
1325 1329
1326 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 1330 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin());
1327 this->joinBounds(that->bounds()); 1331 this->joinBounds(*that);
1328 return true; 1332 return true;
1329 } 1333 }
1330 1334
1331 struct Geometry { 1335 struct Geometry {
1332 GrColor fColor; 1336 GrColor fColor;
1333 SkScalar fInnerRadius; 1337 SkScalar fInnerRadius;
1334 SkScalar fOuterRadius; 1338 SkScalar fOuterRadius;
1335 SkRect fDevBounds; 1339 SkRect fDevBounds;
1336 }; 1340 };
1337 1341
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 innerXRadius = devXRadius - devStrokeWidths.fX; 1391 innerXRadius = devXRadius - devStrokeWidths.fX;
1388 innerYRadius = devYRadius - devStrokeWidths.fY; 1392 innerYRadius = devYRadius - devStrokeWidths.fY;
1389 stroked = (innerXRadius >= 0 && innerYRadius >= 0); 1393 stroked = (innerXRadius >= 0 && innerYRadius >= 0);
1390 } 1394 }
1391 1395
1392 devXRadius += devStrokeWidths.fX; 1396 devXRadius += devStrokeWidths.fX;
1393 devYRadius += devStrokeWidths.fY; 1397 devYRadius += devStrokeWidths.fY;
1394 bounds.outset(devStrokeWidths.fX, devStrokeWidths.fY); 1398 bounds.outset(devStrokeWidths.fX, devStrokeWidths.fY);
1395 } 1399 }
1396 1400
1397 // Expand the rect so all the pixels will be captured.
1398 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1399
1400 RRectEllipseRendererBatch* batch = new RRectEllipseRendererBatch(); 1401 RRectEllipseRendererBatch* batch = new RRectEllipseRendererBatch();
1401 batch->fStroked = stroked; 1402 batch->fStroked = stroked;
1402 batch->fViewMatrixIfUsingLocalCoords = viewMatrix; 1403 batch->fViewMatrixIfUsingLocalCoords = viewMatrix;
1404 batch->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
1405 // Expand the rect for aa in order to generate the correct vertices.
1406 bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1403 batch->fGeoData.emplace_back( 1407 batch->fGeoData.emplace_back(
1404 Geometry {color, devXRadius, devYRadius, innerXRadius, innerYRadius, bounds}); 1408 Geometry {color, devXRadius, devYRadius, innerXRadius, innerYRadius, bounds});
1405 batch->setBounds(bounds);
1406 return batch; 1409 return batch;
1407 } 1410 }
1408 1411
1409 const char* name() const override { return "RRectEllipseRendererBatch"; } 1412 const char* name() const override { return "RRectEllipseRendererBatch"; }
1410 1413
1411 void computePipelineOptimizations(GrInitInvariantOutput* color, 1414 void computePipelineOptimizations(GrInitInvariantOutput* color,
1412 GrInitInvariantOutput* coverage, 1415 GrInitInvariantOutput* coverage,
1413 GrBatchToXPOverrides* overrides) const ove rride { 1416 GrBatchToXPOverrides* overrides) const ove rride {
1414 // When this is called on a batch, there is only one geometry bundle 1417 // When this is called on a batch, there is only one geometry bundle
1415 color->setKnownFourComponents(fGeoData[0].fColor); 1418 color->setKnownFourComponents(fGeoData[0].fColor);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 1530
1528 if (fStroked != that->fStroked) { 1531 if (fStroked != that->fStroked) {
1529 return false; 1532 return false;
1530 } 1533 }
1531 1534
1532 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) { 1535 if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsing LocalCoords)) {
1533 return false; 1536 return false;
1534 } 1537 }
1535 1538
1536 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 1539 fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin());
1537 this->joinBounds(that->bounds()); 1540 this->joinBounds(*that);
1538 return true; 1541 return true;
1539 } 1542 }
1540 1543
1541 struct Geometry { 1544 struct Geometry {
1542 GrColor fColor; 1545 GrColor fColor;
1543 SkScalar fXRadius; 1546 SkScalar fXRadius;
1544 SkScalar fYRadius; 1547 SkScalar fYRadius;
1545 SkScalar fInnerXRadius; 1548 SkScalar fInnerXRadius;
1546 SkScalar fInnerYRadius; 1549 SkScalar fInnerYRadius;
1547 SkRect fDevBounds; 1550 SkRect fDevBounds;
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 } 1691 }
1689 1692
1690 DRAW_BATCH_TEST_DEFINE(RRectBatch) { 1693 DRAW_BATCH_TEST_DEFINE(RRectBatch) {
1691 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); 1694 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
1692 GrColor color = GrRandomColor(random); 1695 GrColor color = GrRandomColor(random);
1693 const SkRRect& rrect = GrTest::TestRRectSimple(random); 1696 const SkRRect& rrect = GrTest::TestRRectSimple(random);
1694 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra ndom)); 1697 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra ndom));
1695 } 1698 }
1696 1699
1697 #endif 1700 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698