OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrContext.h" | 9 #include "GrContext.h" |
10 | 10 |
(...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1336 const GrStrokeInfo& strokeInfo) { | 1336 const GrStrokeInfo& strokeInfo) { |
1337 RETURN_IF_ABANDONED | 1337 RETURN_IF_ABANDONED |
1338 if (path.isEmpty()) { | 1338 if (path.isEmpty()) { |
1339 if (path.isInverseFillType()) { | 1339 if (path.isInverseFillType()) { |
1340 this->drawPaint(rt, clip, paint, viewMatrix); | 1340 this->drawPaint(rt, clip, paint, viewMatrix); |
1341 } | 1341 } |
1342 return; | 1342 return; |
1343 } | 1343 } |
1344 | 1344 |
1345 GrColor color = paint.getColor(); | 1345 GrColor color = paint.getColor(); |
1346 if (strokeInfo.isDashed()) { | |
1347 SkPoint pts[2]; | |
1348 if (path.isLine(pts)) { | |
1349 AutoCheckFlush acf(this); | |
1350 GrPipelineBuilder pipelineBuilder; | |
1351 GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, cli p, &paint, &acf); | |
1352 if (NULL == target) { | |
1353 return; | |
1354 } | |
1355 | |
1356 if (GrDashingEffect::DrawDashLine(fGpu, target, &pipelineBuilder, co lor, viewMatrix, | |
1357 pts, paint, strokeInfo)) { | |
1358 return; | |
1359 } | |
1360 } | |
1361 | |
1362 // Filter dashed path into new path with the dashing applied | |
1363 const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); | |
1364 SkTLazy<SkPath> effectPath; | |
1365 GrStrokeInfo newStrokeInfo(strokeInfo, false); | |
1366 SkStrokeRec* stroke = newStrokeInfo.getStrokeRecPtr(); | |
1367 if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, NULL, in fo)) { | |
1368 this->drawPath(rt, clip, paint, viewMatrix, *effectPath.get(), newSt rokeInfo); | |
1369 return; | |
1370 } | |
1371 | |
1372 this->drawPath(rt, clip, paint, viewMatrix, path, newStrokeInfo); | |
1373 return; | |
1374 } | |
1375 | 1346 |
1376 // Note that internalDrawPath may sw-rasterize the path into a scratch textu re. | 1347 // Note that internalDrawPath may sw-rasterize the path into a scratch textu re. |
1377 // Scratch textures can be recycled after they are returned to the texture | 1348 // Scratch textures can be recycled after they are returned to the texture |
1378 // cache. This presents a potential hazard for buffered drawing. However, | 1349 // cache. This presents a potential hazard for buffered drawing. However, |
1379 // the writePixels that uploads to the scratch will perform a flush so we're | 1350 // the writePixels that uploads to the scratch will perform a flush so we're |
1380 // OK. | 1351 // OK. |
1381 AutoCheckFlush acf(this); | 1352 AutoCheckFlush acf(this); |
1382 GrPipelineBuilder pipelineBuilder; | 1353 GrPipelineBuilder pipelineBuilder; |
1383 GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &pain t, &acf); | 1354 GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &pain t, &acf); |
1384 if (NULL == target) { | 1355 if (NULL == target) { |
1385 return; | 1356 return; |
1386 } | 1357 } |
1387 | 1358 |
1388 GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isC onvex()); | 1359 GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isC onvex()); |
1389 | 1360 |
1390 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); | 1361 if (!strokeInfo.isDashed()) { |
1362 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); | |
1363 bool useCoverageAA = paint.isAntiAlias() && | |
1364 !pipelineBuilder.getRenderTarget()->isMultisampled(); | |
1391 | 1365 |
1392 bool useCoverageAA = paint.isAntiAlias() && | 1366 if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) { |
1393 !pipelineBuilder.getRenderTarget()->isMultisampled(); | 1367 // Concave AA paths are expensive - try to avoid them for special ca ses |
1368 SkRect rects[2]; | |
1394 | 1369 |
1395 if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) { | 1370 if (is_nested_rects(target, &pipelineBuilder, color, viewMatrix, pat h, strokeRec, rects)) { |
bsalomon
2015/04/24 15:56:46
nit, 100 col wraps in here.
Kimmo Kinnunen
2015/04/27 06:12:25
Done.
| |
1396 // Concave AA paths are expensive - try to avoid them for special cases | 1371 fAARectRenderer->fillAANestedRects(target, &pipelineBuilder, col or, viewMatrix, rects); |
1397 SkRect rects[2]; | 1372 return; |
1373 } | |
1374 } | |
1375 SkRect ovalRect; | |
1376 bool isOval = path.isOval(&ovalRect); | |
1398 | 1377 |
1399 if (is_nested_rects(target, &pipelineBuilder, color, viewMatrix, path, s trokeRec, rects)) { | 1378 if (isOval && !path.isInverseFillType()) { |
1400 fAARectRenderer->fillAANestedRects(target, &pipelineBuilder, color, viewMatrix, rects); | 1379 if (fOvalRenderer->drawOval(target, |
1401 return; | 1380 &pipelineBuilder, |
1381 color, | |
1382 viewMatrix, | |
1383 paint.isAntiAlias(), | |
1384 ovalRect, | |
1385 strokeRec)) { | |
1386 return; | |
1387 } | |
1402 } | 1388 } |
1403 } | 1389 } |
1404 | 1390 this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.is AntiAlias(), |
1405 SkRect ovalRect; | 1391 path, strokeInfo); |
1406 bool isOval = path.isOval(&ovalRect); | |
1407 | |
1408 if (!isOval || path.isInverseFillType() || | |
1409 !fOvalRenderer->drawOval(target, | |
1410 &pipelineBuilder, | |
1411 color, | |
1412 viewMatrix, | |
1413 paint.isAntiAlias(), | |
1414 ovalRect, | |
1415 strokeRec)) { | |
1416 this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, pain t.isAntiAlias(), | |
1417 path, strokeInfo); | |
1418 } | |
1419 } | 1392 } |
1420 | 1393 |
1421 void GrContext::internalDrawPath(GrDrawTarget* target, | 1394 void GrContext::internalDrawPath(GrDrawTarget* target, |
1422 GrPipelineBuilder* pipelineBuilder, | 1395 GrPipelineBuilder* pipelineBuilder, |
1423 const SkMatrix& viewMatrix, | 1396 const SkMatrix& viewMatrix, |
1424 GrColor color, | 1397 GrColor color, |
1425 bool useAA, | 1398 bool useAA, |
1426 const SkPath& path, | 1399 const SkPath& path, |
1427 const GrStrokeInfo& strokeInfo) { | 1400 const GrStrokeInfo& strokeInfo) { |
1428 RETURN_IF_ABANDONED | 1401 RETURN_IF_ABANDONED |
1429 SkASSERT(!path.isEmpty()); | 1402 SkASSERT(!path.isEmpty()); |
1430 | 1403 |
1431 GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); | 1404 GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); |
1432 | 1405 |
1433 | 1406 |
1434 // An Assumption here is that path renderer would use some form of tweaking | 1407 // An Assumption here is that path renderer would use some form of tweaking |
1435 // the src color (either the input alpha or in the frag shader) to implement | 1408 // the src color (either the input alpha or in the frag shader) to implement |
1436 // aa. If we have some future driver-mojo path AA that can do the right | 1409 // aa. If we have some future driver-mojo path AA that can do the right |
1437 // thing WRT to the blend then we'll need some query on the PR. | 1410 // thing WRT to the blend then we'll need some query on the PR. |
1438 bool useCoverageAA = useAA && | 1411 bool useCoverageAA = useAA && |
1439 !pipelineBuilder->getRenderTarget()->isMultisampled(); | 1412 !pipelineBuilder->getRenderTarget()->isMultisampled(); |
1440 | 1413 |
1441 | 1414 |
1442 GrPathRendererChain::DrawType type = | 1415 GrPathRendererChain::DrawType type = |
1443 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : | 1416 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : |
1444 GrPathRendererChain::kColor_DrawType; | 1417 GrPathRendererChain::kColor_DrawType; |
1445 | 1418 |
1446 const SkPath* pathPtr = &path; | 1419 const SkPath* pathPtr = &path; |
1447 SkTLazy<SkPath> tmpPath; | 1420 SkTLazy<SkPath> tmpPath; |
1448 SkTCopyOnFirstWrite<SkStrokeRec> stroke(strokeInfo.getStrokeRec()); | 1421 const GrStrokeInfo* strokeInfoPtr = &strokeInfo; |
1449 | 1422 |
1450 // Try a 1st time without stroking the path and without allowing the SW rend erer | 1423 // Try a 1st time without stroking the path and without allowing the SW rend erer |
1451 GrPathRenderer* pr = this->getPathRenderer(target, pipelineBuilder, viewMatr ix, *pathPtr, | 1424 GrPathRenderer* pr = this->getPathRenderer(target, pipelineBuilder, viewMatr ix, *pathPtr, |
1452 *stroke, false, type); | 1425 *strokeInfoPtr, false, type); |
1426 | |
1427 GrStrokeInfo dashlessStrokeInfo(strokeInfo, false); | |
1428 if (NULL == pr && strokeInfo.isDashed()) { | |
1429 // It didn't work above, so try again with dashed stroke converted to a dashless stroke. | |
1430 if (strokeInfo.applyDash(tmpPath.init(), &dashlessStrokeInfo, *pathPtr)) { | |
1431 pathPtr = tmpPath.get(); | |
1432 if (pathPtr->isEmpty()) { | |
1433 return; | |
1434 } | |
1435 strokeInfoPtr = &dashlessStrokeInfo; | |
1436 } | |
1437 pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr , *strokeInfoPtr, false, | |
bsalomon
2015/04/24 15:56:46
nit wrap
Kimmo Kinnunen
2015/04/27 06:12:25
Done.
| |
1438 type); | |
1439 } | |
1453 | 1440 |
1454 if (NULL == pr) { | 1441 if (NULL == pr) { |
1455 if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, viewMatrix, N ULL)) { | 1442 if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*strokeInfoPtr, viewMa trix, NULL)) { |
1456 // It didn't work the 1st time, so try again with the stroked path | 1443 // It didn't work above, so try again with stroke converted to a fil l. |
1457 stroke.writable()->setResScale(SkScalarAbs(viewMatrix.getMaxScale()) ); | 1444 if (!tmpPath.isValid()) { |
1458 if (stroke->applyToPath(tmpPath.init(), *pathPtr)) { | 1445 tmpPath.init(); |
1446 } | |
1447 SkStrokeRec* strokeRec = dashlessStrokeInfo.getStrokeRecPtr(); | |
1448 strokeRec->setResScale(SkScalarAbs(viewMatrix.getMaxScale())); | |
1449 if (strokeRec->applyToPath(tmpPath.get(), *pathPtr)) { | |
1459 pathPtr = tmpPath.get(); | 1450 pathPtr = tmpPath.get(); |
1460 stroke.writable()->setFillStyle(); | |
1461 if (pathPtr->isEmpty()) { | 1451 if (pathPtr->isEmpty()) { |
1462 return; | 1452 return; |
1463 } | 1453 } |
1454 strokeRec->setFillStyle(); | |
1455 strokeInfoPtr = &dashlessStrokeInfo; | |
1464 } | 1456 } |
1465 } | 1457 } |
1466 | 1458 |
1467 // This time, allow SW renderer | 1459 // This time, allow SW renderer |
1468 pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr , *stroke, true, | 1460 pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr , *strokeInfoPtr, true, |
1469 type); | 1461 type); |
1470 } | 1462 } |
1471 | 1463 |
1472 if (NULL == pr) { | 1464 if (NULL == pr) { |
1473 #ifdef SK_DEBUG | 1465 #ifdef SK_DEBUG |
1474 SkDebugf("Unable to find path renderer compatible with path.\n"); | 1466 SkDebugf("Unable to find path renderer compatible with path.\n"); |
1475 #endif | 1467 #endif |
1476 return; | 1468 return; |
1477 } | 1469 } |
1478 | 1470 |
1479 pr->drawPath(target, pipelineBuilder, color, viewMatrix, *pathPtr, *stroke, useCoverageAA); | 1471 pr->drawPath(target, pipelineBuilder, color, viewMatrix, *pathPtr, *strokeIn foPtr, useCoverageAA); |
1480 } | 1472 } |
1481 | 1473 |
1482 //////////////////////////////////////////////////////////////////////////////// | 1474 //////////////////////////////////////////////////////////////////////////////// |
1483 | 1475 |
1484 void GrContext::flush(int flagsBitfield) { | 1476 void GrContext::flush(int flagsBitfield) { |
1485 if (NULL == fDrawBuffer) { | 1477 if (NULL == fDrawBuffer) { |
1486 return; | 1478 return; |
1487 } | 1479 } |
1488 | 1480 |
1489 if (kDiscard_FlushBit & flagsBitfield) { | 1481 if (kDiscard_FlushBit & flagsBitfield) { |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1866 /* | 1858 /* |
1867 * This method finds a path renderer that can draw the specified path on | 1859 * This method finds a path renderer that can draw the specified path on |
1868 * the provided target. | 1860 * the provided target. |
1869 * Due to its expense, the software path renderer has split out so it can | 1861 * Due to its expense, the software path renderer has split out so it can |
1870 * can be individually allowed/disallowed via the "allowSW" boolean. | 1862 * can be individually allowed/disallowed via the "allowSW" boolean. |
1871 */ | 1863 */ |
1872 GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target, | 1864 GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target, |
1873 const GrPipelineBuilder* pipelineBuil der, | 1865 const GrPipelineBuilder* pipelineBuil der, |
1874 const SkMatrix& viewMatrix, | 1866 const SkMatrix& viewMatrix, |
1875 const SkPath& path, | 1867 const SkPath& path, |
1876 const SkStrokeRec& stroke, | 1868 const GrStrokeInfo& stroke, |
1877 bool allowSW, | 1869 bool allowSW, |
1878 GrPathRendererChain::DrawType drawTyp e, | 1870 GrPathRendererChain::DrawType drawTyp e, |
1879 GrPathRendererChain::StencilSupport* stencilSupport) { | 1871 GrPathRendererChain::StencilSupport* stencilSupport) { |
1880 | 1872 |
1881 if (NULL == fPathRendererChain) { | 1873 if (NULL == fPathRendererChain) { |
1882 fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); | 1874 fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); |
1883 } | 1875 } |
1884 | 1876 |
1885 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target, | 1877 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target, |
1886 pipelineBuilder, | 1878 pipelineBuilder, |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2031 } | 2023 } |
2032 } | 2024 } |
2033 | 2025 |
2034 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { | 2026 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { |
2035 fGpu->removeGpuTraceMarker(marker); | 2027 fGpu->removeGpuTraceMarker(marker); |
2036 if (fDrawBuffer) { | 2028 if (fDrawBuffer) { |
2037 fDrawBuffer->removeGpuTraceMarker(marker); | 2029 fDrawBuffer->removeGpuTraceMarker(marker); |
2038 } | 2030 } |
2039 } | 2031 } |
2040 | 2032 |
OLD | NEW |