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 "GrBatch.h" | 10 #include "GrBatch.h" |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(GrProcessorTestData* d) { | 586 GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(GrProcessorTestData* d) { |
587 return DIEllipseEdgeEffect::Create(GrRandomColor(d->fRandom), | 587 return DIEllipseEdgeEffect::Create(GrRandomColor(d->fRandom), |
588 GrTest::TestMatrix(d->fRandom), | 588 GrTest::TestMatrix(d->fRandom), |
589 (Mode)(d->fRandom->nextRangeU(0,2)), | 589 (Mode)(d->fRandom->nextRangeU(0,2)), |
590 d->fRandom->nextBool()); | 590 d->fRandom->nextBool()); |
591 } | 591 } |
592 | 592 |
593 /////////////////////////////////////////////////////////////////////////////// | 593 /////////////////////////////////////////////////////////////////////////////// |
594 | 594 |
595 bool GrOvalRenderer::DrawOval(GrDrawTarget* target, | 595 bool GrOvalRenderer::DrawOval(GrDrawTarget* target, |
596 GrPipelineBuilder* pipelineBuilder, | 596 const GrPipelineBuilder& pipelineBuilder, |
597 GrColor color, | 597 GrColor color, |
598 const SkMatrix& viewMatrix, | 598 const SkMatrix& viewMatrix, |
599 bool useAA, | 599 bool useAA, |
600 const SkRect& oval, | 600 const SkRect& oval, |
601 const SkStrokeRec& stroke) | 601 const SkStrokeRec& stroke) { |
602 { | 602 bool useCoverageAA = useAA && !pipelineBuilder.getRenderTarget()->isUnifiedM
ultisampled(); |
603 bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isUnified
Multisampled(); | |
604 | 603 |
605 if (!useCoverageAA) { | 604 if (!useCoverageAA) { |
606 return false; | 605 return false; |
607 } | 606 } |
608 | 607 |
609 // we can draw circles | 608 // we can draw circles |
610 if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle(
viewMatrix)) { | 609 if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle(
viewMatrix)) { |
611 DrawCircle(target, pipelineBuilder, color, viewMatrix, useCoverageAA, ov
al, stroke); | 610 DrawCircle(target, pipelineBuilder, color, viewMatrix, useCoverageAA, ov
al, stroke); |
612 // if we have shader derivative support, render as device-independent | 611 // if we have shader derivative support, render as device-independent |
613 } else if (target->caps()->shaderCaps()->shaderDerivativeSupport()) { | 612 } else if (target->caps()->shaderCaps()->shaderDerivativeSupport()) { |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 geometry.fInnerRadius = innerRadius; | 816 geometry.fInnerRadius = innerRadius; |
818 geometry.fOuterRadius = outerRadius; | 817 geometry.fOuterRadius = outerRadius; |
819 geometry.fStroke = isStrokeOnly && innerRadius > 0; | 818 geometry.fStroke = isStrokeOnly && innerRadius > 0; |
820 geometry.fDevBounds = SkRect::MakeLTRB(center.fX - outerRadius, center.fY -
outerRadius, | 819 geometry.fDevBounds = SkRect::MakeLTRB(center.fX - outerRadius, center.fY -
outerRadius, |
821 center.fX + outerRadius, center.fY +
outerRadius); | 820 center.fX + outerRadius, center.fY +
outerRadius); |
822 | 821 |
823 return CircleBatch::Create(geometry); | 822 return CircleBatch::Create(geometry); |
824 } | 823 } |
825 | 824 |
826 void GrOvalRenderer::DrawCircle(GrDrawTarget* target, | 825 void GrOvalRenderer::DrawCircle(GrDrawTarget* target, |
827 GrPipelineBuilder* pipelineBuilder, | 826 const GrPipelineBuilder& pipelineBuilder, |
828 GrColor color, | 827 GrColor color, |
829 const SkMatrix& viewMatrix, | 828 const SkMatrix& viewMatrix, |
830 bool useCoverageAA, | 829 bool useCoverageAA, |
831 const SkRect& circle, | 830 const SkRect& circle, |
832 const SkStrokeRec& stroke) { | 831 const SkStrokeRec& stroke) { |
833 SkAutoTUnref<GrBatch> batch(create_circle_batch(color, viewMatrix, useCovera
geAA, circle, | 832 SkAutoTUnref<GrBatch> batch(create_circle_batch(color, viewMatrix, useCovera
geAA, circle, |
834 stroke)); | 833 stroke)); |
835 target->drawBatch(*pipelineBuilder, batch); | 834 target->drawBatch(pipelineBuilder, batch); |
836 } | 835 } |
837 | 836 |
838 /////////////////////////////////////////////////////////////////////////////// | 837 /////////////////////////////////////////////////////////////////////////////// |
839 | 838 |
840 class EllipseBatch : public GrBatch { | 839 class EllipseBatch : public GrBatch { |
841 public: | 840 public: |
842 struct Geometry { | 841 struct Geometry { |
843 GrColor fColor; | 842 GrColor fColor; |
844 SkMatrix fViewMatrix; | 843 SkMatrix fViewMatrix; |
845 SkScalar fXRadius; | 844 SkScalar fXRadius; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 geometry.fInnerXRadius = innerXRadius; | 1072 geometry.fInnerXRadius = innerXRadius; |
1074 geometry.fInnerYRadius = innerYRadius; | 1073 geometry.fInnerYRadius = innerYRadius; |
1075 geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; | 1074 geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; |
1076 geometry.fDevBounds = SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRad
ius, | 1075 geometry.fDevBounds = SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRad
ius, |
1077 center.fX + xRadius, center.fY + yRad
ius); | 1076 center.fX + xRadius, center.fY + yRad
ius); |
1078 | 1077 |
1079 return EllipseBatch::Create(geometry); | 1078 return EllipseBatch::Create(geometry); |
1080 } | 1079 } |
1081 | 1080 |
1082 bool GrOvalRenderer::DrawEllipse(GrDrawTarget* target, | 1081 bool GrOvalRenderer::DrawEllipse(GrDrawTarget* target, |
1083 GrPipelineBuilder* pipelineBuilder, | 1082 const GrPipelineBuilder& pipelineBuilder, |
1084 GrColor color, | 1083 GrColor color, |
1085 const SkMatrix& viewMatrix, | 1084 const SkMatrix& viewMatrix, |
1086 bool useCoverageAA, | 1085 bool useCoverageAA, |
1087 const SkRect& ellipse, | 1086 const SkRect& ellipse, |
1088 const SkStrokeRec& stroke) { | 1087 const SkStrokeRec& stroke) { |
1089 SkAutoTUnref<GrBatch> batch(create_ellipse_batch(color, viewMatrix, useCover
ageAA, ellipse, | 1088 SkAutoTUnref<GrBatch> batch(create_ellipse_batch(color, viewMatrix, useCover
ageAA, ellipse, |
1090 stroke)); | 1089 stroke)); |
1091 if (!batch) { | 1090 if (!batch) { |
1092 return false; | 1091 return false; |
1093 } | 1092 } |
1094 | 1093 |
1095 target->drawBatch(*pipelineBuilder, batch); | 1094 target->drawBatch(pipelineBuilder, batch); |
1096 return true; | 1095 return true; |
1097 } | 1096 } |
1098 | 1097 |
1099 ////////////////////////////////////////////////////////////////////////////////
///////////////// | 1098 ////////////////////////////////////////////////////////////////////////////////
///////////////// |
1100 | 1099 |
1101 class DIEllipseBatch : public GrBatch { | 1100 class DIEllipseBatch : public GrBatch { |
1102 public: | 1101 public: |
1103 struct Geometry { | 1102 struct Geometry { |
1104 GrColor fColor; | 1103 GrColor fColor; |
1105 SkMatrix fViewMatrix; | 1104 SkMatrix fViewMatrix; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 geometry.fMode = mode; | 1317 geometry.fMode = mode; |
1319 geometry.fBounds = SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY -
yRadius - geoDy, | 1318 geometry.fBounds = SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY -
yRadius - geoDy, |
1320 center.fX + xRadius + geoDx, center.fY +
yRadius + geoDy); | 1319 center.fX + xRadius + geoDx, center.fY +
yRadius + geoDy); |
1321 | 1320 |
1322 SkRect devBounds = geometry.fBounds; | 1321 SkRect devBounds = geometry.fBounds; |
1323 viewMatrix.mapRect(&devBounds); | 1322 viewMatrix.mapRect(&devBounds); |
1324 return DIEllipseBatch::Create(geometry, devBounds); | 1323 return DIEllipseBatch::Create(geometry, devBounds); |
1325 } | 1324 } |
1326 | 1325 |
1327 bool GrOvalRenderer::DrawDIEllipse(GrDrawTarget* target, | 1326 bool GrOvalRenderer::DrawDIEllipse(GrDrawTarget* target, |
1328 GrPipelineBuilder* pipelineBuilder, | 1327 const GrPipelineBuilder& pipelineBuilder, |
1329 GrColor color, | 1328 GrColor color, |
1330 const SkMatrix& viewMatrix, | 1329 const SkMatrix& viewMatrix, |
1331 bool useCoverageAA, | 1330 bool useCoverageAA, |
1332 const SkRect& ellipse, | 1331 const SkRect& ellipse, |
1333 const SkStrokeRec& stroke) { | 1332 const SkStrokeRec& stroke) { |
1334 SkAutoTUnref<GrBatch> batch(create_diellipse_batch(color, viewMatrix, useCov
erageAA, ellipse, | 1333 SkAutoTUnref<GrBatch> batch(create_diellipse_batch(color, viewMatrix, useCov
erageAA, ellipse, |
1335 stroke)); | 1334 stroke)); |
1336 if (!batch) { | 1335 if (!batch) { |
1337 return false; | 1336 return false; |
1338 } | 1337 } |
1339 target->drawBatch(*pipelineBuilder, batch); | 1338 target->drawBatch(pipelineBuilder, batch); |
1340 return true; | 1339 return true; |
1341 } | 1340 } |
1342 | 1341 |
1343 /////////////////////////////////////////////////////////////////////////////// | 1342 /////////////////////////////////////////////////////////////////////////////// |
1344 | 1343 |
1345 static const uint16_t gRRectIndices[] = { | 1344 static const uint16_t gRRectIndices[] = { |
1346 // corners | 1345 // corners |
1347 0, 1, 5, 0, 5, 4, | 1346 0, 1, 5, 0, 5, 4, |
1348 2, 3, 7, 2, 7, 6, | 1347 2, 3, 7, 2, 7, 6, |
1349 8, 9, 13, 8, 13, 12, | 1348 8, 9, 13, 8, 13, 12, |
(...skipping 27 matching lines...) Expand all Loading... |
1377 gStrokeRRectOnlyIndexBufferKey); | 1376 gStrokeRRectOnlyIndexBufferKey); |
1378 } else { | 1377 } else { |
1379 return resourceProvider->refOrCreateInstancedIndexBuffer( | 1378 return resourceProvider->refOrCreateInstancedIndexBuffer( |
1380 gRRectIndices, kIndicesPerRRect, kNumRRectsInIndexBuffer, kVertsPerR
Rect, | 1379 gRRectIndices, kIndicesPerRRect, kNumRRectsInIndexBuffer, kVertsPerR
Rect, |
1381 gRRectOnlyIndexBufferKey); | 1380 gRRectOnlyIndexBufferKey); |
1382 | 1381 |
1383 } | 1382 } |
1384 } | 1383 } |
1385 | 1384 |
1386 bool GrOvalRenderer::DrawDRRect(GrDrawTarget* target, | 1385 bool GrOvalRenderer::DrawDRRect(GrDrawTarget* target, |
1387 GrPipelineBuilder* pipelineBuilder, | 1386 const GrPipelineBuilder& pipelineBuilder, |
1388 GrColor color, | 1387 GrColor color, |
1389 const SkMatrix& viewMatrix, | 1388 const SkMatrix& viewMatrix, |
1390 bool useAA, | 1389 bool useAA, |
1391 const SkRRect& origOuter, | 1390 const SkRRect& origOuter, |
1392 const SkRRect& origInner) { | 1391 const SkRRect& origInner) { |
1393 bool applyAA = useAA && | 1392 bool applyAA = useAA && !pipelineBuilder.getRenderTarget()->isUnifiedMultisa
mpled(); |
1394 !pipelineBuilder->getRenderTarget()->isUnifiedMultisampled(); | |
1395 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; | 1393 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; |
1396 if (!origInner.isEmpty()) { | 1394 if (!origInner.isEmpty()) { |
1397 SkTCopyOnFirstWrite<SkRRect> inner(origInner); | 1395 SkTCopyOnFirstWrite<SkRRect> inner(origInner); |
1398 if (!viewMatrix.isIdentity()) { | 1396 if (!viewMatrix.isIdentity()) { |
1399 if (!origInner.transform(viewMatrix, inner.writable())) { | 1397 if (!origInner.transform(viewMatrix, inner.writable())) { |
1400 return false; | 1398 return false; |
1401 } | 1399 } |
1402 } | 1400 } |
1403 GrPrimitiveEdgeType edgeType = applyAA ? | 1401 GrPrimitiveEdgeType edgeType = applyAA ? |
1404 kInverseFillAA_GrProcessorEdgeType : | 1402 kInverseFillAA_GrProcessorEdgeType : |
1405 kInverseFillBW_GrProcessorEdgeType; | 1403 kInverseFillBW_GrProcessorEdgeType; |
1406 // TODO this needs to be a geometry processor | 1404 // TODO this needs to be a geometry processor |
1407 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); | 1405 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); |
1408 if (NULL == fp) { | 1406 if (NULL == fp) { |
1409 return false; | 1407 return false; |
1410 } | 1408 } |
1411 arfp.set(pipelineBuilder); | 1409 arfp.set(&pipelineBuilder); |
1412 pipelineBuilder->addCoverageProcessor(fp)->unref(); | 1410 arfp.addCoverageProcessor(fp)->unref(); |
1413 } | 1411 } |
1414 | 1412 |
1415 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); | 1413 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); |
1416 if (DrawRRect(target, pipelineBuilder, color, viewMatrix, useAA, origOuter,
fillRec)) { | 1414 if (DrawRRect(target, pipelineBuilder, color, viewMatrix, useAA, origOuter,
fillRec)) { |
1417 return true; | 1415 return true; |
1418 } | 1416 } |
1419 | 1417 |
1420 SkASSERT(!origOuter.isEmpty()); | 1418 SkASSERT(!origOuter.isEmpty()); |
1421 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); | 1419 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); |
1422 if (!viewMatrix.isIdentity()) { | 1420 if (!viewMatrix.isIdentity()) { |
1423 if (!origOuter.transform(viewMatrix, outer.writable())) { | 1421 if (!origOuter.transform(viewMatrix, outer.writable())) { |
1424 return false; | 1422 return false; |
1425 } | 1423 } |
1426 } | 1424 } |
1427 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : | 1425 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : |
1428 kFillBW_GrProcessorEdgeType; | 1426 kFillBW_GrProcessorEdgeType; |
1429 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); | 1427 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); |
1430 if (NULL == effect) { | 1428 if (NULL == effect) { |
1431 return false; | 1429 return false; |
1432 } | 1430 } |
1433 if (!arfp.isSet()) { | 1431 if (!arfp.isSet()) { |
1434 arfp.set(pipelineBuilder); | 1432 arfp.set(&pipelineBuilder); |
1435 } | 1433 } |
1436 | 1434 |
1437 SkMatrix invert; | 1435 SkMatrix invert; |
1438 if (!viewMatrix.invert(&invert)) { | 1436 if (!viewMatrix.invert(&invert)) { |
1439 return false; | 1437 return false; |
1440 } | 1438 } |
1441 | 1439 |
1442 pipelineBuilder->addCoverageProcessor(effect)->unref(); | 1440 arfp.addCoverageProcessor(effect)->unref(); |
1443 SkRect bounds = outer->getBounds(); | 1441 SkRect bounds = outer->getBounds(); |
1444 if (applyAA) { | 1442 if (applyAA) { |
1445 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); | 1443 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
1446 } | 1444 } |
1447 target->drawBWRect(*pipelineBuilder, color, SkMatrix::I(), bounds, NULL, &in
vert); | 1445 target->drawBWRect(pipelineBuilder, color, SkMatrix::I(), bounds, NULL, &inv
ert); |
1448 return true; | 1446 return true; |
1449 } | 1447 } |
1450 | 1448 |
1451 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 1449 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
1452 | 1450 |
1453 class RRectCircleRendererBatch : public GrBatch { | 1451 class RRectCircleRendererBatch : public GrBatch { |
1454 public: | 1452 public: |
1455 struct Geometry { | 1453 struct Geometry { |
1456 GrColor fColor; | 1454 GrColor fColor; |
1457 SkMatrix fViewMatrix; | 1455 SkMatrix fViewMatrix; |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1945 geometry.fInnerXRadius = innerXRadius; | 1943 geometry.fInnerXRadius = innerXRadius; |
1946 geometry.fInnerYRadius = innerYRadius; | 1944 geometry.fInnerYRadius = innerYRadius; |
1947 geometry.fStroke = isStrokeOnly; | 1945 geometry.fStroke = isStrokeOnly; |
1948 geometry.fDevBounds = bounds; | 1946 geometry.fDevBounds = bounds; |
1949 | 1947 |
1950 return RRectEllipseRendererBatch::Create(geometry); | 1948 return RRectEllipseRendererBatch::Create(geometry); |
1951 } | 1949 } |
1952 } | 1950 } |
1953 | 1951 |
1954 bool GrOvalRenderer::DrawRRect(GrDrawTarget* target, | 1952 bool GrOvalRenderer::DrawRRect(GrDrawTarget* target, |
1955 GrPipelineBuilder* pipelineBuilder, | 1953 const GrPipelineBuilder& pipelineBuilder, |
1956 GrColor color, | 1954 GrColor color, |
1957 const SkMatrix& viewMatrix, | 1955 const SkMatrix& viewMatrix, |
1958 bool useAA, | 1956 bool useAA, |
1959 const SkRRect& rrect, | 1957 const SkRRect& rrect, |
1960 const SkStrokeRec& stroke) { | 1958 const SkStrokeRec& stroke) { |
1961 if (rrect.isOval()) { | 1959 if (rrect.isOval()) { |
1962 return DrawOval(target, pipelineBuilder, color, viewMatrix, useAA, rrect
.getBounds(), | 1960 return DrawOval(target, pipelineBuilder, color, viewMatrix, useAA, rrect
.getBounds(), |
1963 stroke); | 1961 stroke); |
1964 } | 1962 } |
1965 | 1963 |
1966 bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isUnified
Multisampled(); | 1964 bool useCoverageAA = useAA && !pipelineBuilder.getRenderTarget()->isUnifiedM
ultisampled(); |
1967 | 1965 |
1968 // only anti-aliased rrects for now | 1966 // only anti-aliased rrects for now |
1969 if (!useCoverageAA) { | 1967 if (!useCoverageAA) { |
1970 return false; | 1968 return false; |
1971 } | 1969 } |
1972 | 1970 |
1973 if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { | 1971 if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { |
1974 return false; | 1972 return false; |
1975 } | 1973 } |
1976 | 1974 |
1977 SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, str
oke)); | 1975 SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, str
oke)); |
1978 if (!batch) { | 1976 if (!batch) { |
1979 return false; | 1977 return false; |
1980 } | 1978 } |
1981 | 1979 |
1982 target->drawBatch(*pipelineBuilder, batch); | 1980 target->drawBatch(pipelineBuilder, batch); |
1983 return true; | 1981 return true; |
1984 } | 1982 } |
1985 | 1983 |
1986 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 1984 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
1987 | 1985 |
1988 #ifdef GR_TEST_UTILS | 1986 #ifdef GR_TEST_UTILS |
1989 | 1987 |
1990 BATCH_TEST_DEFINE(CircleBatch) { | 1988 BATCH_TEST_DEFINE(CircleBatch) { |
1991 SkMatrix viewMatrix = GrTest::TestMatrix(random); | 1989 SkMatrix viewMatrix = GrTest::TestMatrix(random); |
1992 GrColor color = GrRandomColor(random); | 1990 GrColor color = GrRandomColor(random); |
(...skipping 21 matching lines...) Expand all Loading... |
2014 } | 2012 } |
2015 | 2013 |
2016 BATCH_TEST_DEFINE(RRectBatch) { | 2014 BATCH_TEST_DEFINE(RRectBatch) { |
2017 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); | 2015 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); |
2018 GrColor color = GrRandomColor(random); | 2016 GrColor color = GrRandomColor(random); |
2019 const SkRRect& rrect = GrTest::TestRRectSimple(random); | 2017 const SkRRect& rrect = GrTest::TestRRectSimple(random); |
2020 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra
ndom)); | 2018 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra
ndom)); |
2021 } | 2019 } |
2022 | 2020 |
2023 #endif | 2021 #endif |
OLD | NEW |