| 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, |
| 1396 // Concave AA paths are expensive - try to avoid them for special cases | 1371 rects)) { |
| 1397 SkRect rects[2]; | 1372 fAARectRenderer->fillAANestedRects(target, &pipelineBuilder, col
or, viewMatrix, |
| 1373 rects); |
| 1374 return; |
| 1375 } |
| 1376 } |
| 1377 SkRect ovalRect; |
| 1378 bool isOval = path.isOval(&ovalRect); |
| 1398 | 1379 |
| 1399 if (is_nested_rects(target, &pipelineBuilder, color, viewMatrix, path, s
trokeRec, rects)) { | 1380 if (isOval && !path.isInverseFillType()) { |
| 1400 fAARectRenderer->fillAANestedRects(target, &pipelineBuilder, color,
viewMatrix, rects); | 1381 if (fOvalRenderer->drawOval(target, |
| 1401 return; | 1382 &pipelineBuilder, |
| 1383 color, |
| 1384 viewMatrix, |
| 1385 paint.isAntiAlias(), |
| 1386 ovalRect, |
| 1387 strokeRec)) { |
| 1388 return; |
| 1389 } |
| 1402 } | 1390 } |
| 1403 } | 1391 } |
| 1404 | 1392 this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.is
AntiAlias(), |
| 1405 SkRect ovalRect; | 1393 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 } | 1394 } |
| 1420 | 1395 |
| 1421 void GrContext::internalDrawPath(GrDrawTarget* target, | 1396 void GrContext::internalDrawPath(GrDrawTarget* target, |
| 1422 GrPipelineBuilder* pipelineBuilder, | 1397 GrPipelineBuilder* pipelineBuilder, |
| 1423 const SkMatrix& viewMatrix, | 1398 const SkMatrix& viewMatrix, |
| 1424 GrColor color, | 1399 GrColor color, |
| 1425 bool useAA, | 1400 bool useAA, |
| 1426 const SkPath& path, | 1401 const SkPath& path, |
| 1427 const GrStrokeInfo& strokeInfo) { | 1402 const GrStrokeInfo& strokeInfo) { |
| 1428 RETURN_IF_ABANDONED | 1403 RETURN_IF_ABANDONED |
| 1429 SkASSERT(!path.isEmpty()); | 1404 SkASSERT(!path.isEmpty()); |
| 1430 | 1405 |
| 1431 GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); | 1406 GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); |
| 1432 | 1407 |
| 1433 | 1408 |
| 1434 // An Assumption here is that path renderer would use some form of tweaking | 1409 // 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 | 1410 // 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 | 1411 // 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. | 1412 // thing WRT to the blend then we'll need some query on the PR. |
| 1438 bool useCoverageAA = useAA && | 1413 bool useCoverageAA = useAA && |
| 1439 !pipelineBuilder->getRenderTarget()->isMultisampled(); | 1414 !pipelineBuilder->getRenderTarget()->isMultisampled(); |
| 1440 | 1415 |
| 1441 | 1416 |
| 1442 GrPathRendererChain::DrawType type = | 1417 GrPathRendererChain::DrawType type = |
| 1443 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : | 1418 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : |
| 1444 GrPathRendererChain::kColor_DrawType; | 1419 GrPathRendererChain::kColor_DrawType; |
| 1445 | 1420 |
| 1446 const SkPath* pathPtr = &path; | 1421 const SkPath* pathPtr = &path; |
| 1447 SkTLazy<SkPath> tmpPath; | 1422 SkTLazy<SkPath> tmpPath; |
| 1448 SkTCopyOnFirstWrite<SkStrokeRec> stroke(strokeInfo.getStrokeRec()); | 1423 const GrStrokeInfo* strokeInfoPtr = &strokeInfo; |
| 1449 | 1424 |
| 1450 // Try a 1st time without stroking the path and without allowing the SW rend
erer | 1425 // 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, | 1426 GrPathRenderer* pr = this->getPathRenderer(target, pipelineBuilder, viewMatr
ix, *pathPtr, |
| 1452 *stroke, false, type); | 1427 *strokeInfoPtr, false, type); |
| 1428 |
| 1429 GrStrokeInfo dashlessStrokeInfo(strokeInfo, false); |
| 1430 if (NULL == pr && strokeInfo.isDashed()) { |
| 1431 // It didn't work above, so try again with dashed stroke converted to a
dashless stroke. |
| 1432 if (strokeInfo.applyDash(tmpPath.init(), &dashlessStrokeInfo, *pathPtr))
{ |
| 1433 pathPtr = tmpPath.get(); |
| 1434 if (pathPtr->isEmpty()) { |
| 1435 return; |
| 1436 } |
| 1437 strokeInfoPtr = &dashlessStrokeInfo; |
| 1438 } |
| 1439 pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr
, *strokeInfoPtr, |
| 1440 false, type); |
| 1441 } |
| 1453 | 1442 |
| 1454 if (NULL == pr) { | 1443 if (NULL == pr) { |
| 1455 if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, viewMatrix, N
ULL)) { | 1444 if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*strokeInfoPtr, viewMa
trix, NULL)) { |
| 1456 // It didn't work the 1st time, so try again with the stroked path | 1445 // It didn't work above, so try again with stroke converted to a fil
l. |
| 1457 stroke.writable()->setResScale(SkScalarAbs(viewMatrix.getMaxScale())
); | 1446 if (!tmpPath.isValid()) { |
| 1458 if (stroke->applyToPath(tmpPath.init(), *pathPtr)) { | 1447 tmpPath.init(); |
| 1448 } |
| 1449 SkStrokeRec* strokeRec = dashlessStrokeInfo.getStrokeRecPtr(); |
| 1450 strokeRec->setResScale(SkScalarAbs(viewMatrix.getMaxScale())); |
| 1451 if (strokeRec->applyToPath(tmpPath.get(), *pathPtr)) { |
| 1459 pathPtr = tmpPath.get(); | 1452 pathPtr = tmpPath.get(); |
| 1460 stroke.writable()->setFillStyle(); | |
| 1461 if (pathPtr->isEmpty()) { | 1453 if (pathPtr->isEmpty()) { |
| 1462 return; | 1454 return; |
| 1463 } | 1455 } |
| 1456 strokeRec->setFillStyle(); |
| 1457 strokeInfoPtr = &dashlessStrokeInfo; |
| 1464 } | 1458 } |
| 1465 } | 1459 } |
| 1466 | 1460 |
| 1467 // This time, allow SW renderer | 1461 // This time, allow SW renderer |
| 1468 pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr
, *stroke, true, | 1462 pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr
, *strokeInfoPtr, |
| 1469 type); | 1463 true, type); |
| 1470 } | 1464 } |
| 1471 | 1465 |
| 1472 if (NULL == pr) { | 1466 if (NULL == pr) { |
| 1473 #ifdef SK_DEBUG | 1467 #ifdef SK_DEBUG |
| 1474 SkDebugf("Unable to find path renderer compatible with path.\n"); | 1468 SkDebugf("Unable to find path renderer compatible with path.\n"); |
| 1475 #endif | 1469 #endif |
| 1476 return; | 1470 return; |
| 1477 } | 1471 } |
| 1478 | 1472 |
| 1479 pr->drawPath(target, pipelineBuilder, color, viewMatrix, *pathPtr, *stroke,
useCoverageAA); | 1473 pr->drawPath(target, pipelineBuilder, color, viewMatrix, *pathPtr, *strokeIn
foPtr, useCoverageAA); |
| 1480 } | 1474 } |
| 1481 | 1475 |
| 1482 //////////////////////////////////////////////////////////////////////////////// | 1476 //////////////////////////////////////////////////////////////////////////////// |
| 1483 | 1477 |
| 1484 void GrContext::flush(int flagsBitfield) { | 1478 void GrContext::flush(int flagsBitfield) { |
| 1485 if (NULL == fDrawBuffer) { | 1479 if (NULL == fDrawBuffer) { |
| 1486 return; | 1480 return; |
| 1487 } | 1481 } |
| 1488 | 1482 |
| 1489 if (kDiscard_FlushBit & flagsBitfield) { | 1483 if (kDiscard_FlushBit & flagsBitfield) { |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1866 /* | 1860 /* |
| 1867 * This method finds a path renderer that can draw the specified path on | 1861 * This method finds a path renderer that can draw the specified path on |
| 1868 * the provided target. | 1862 * the provided target. |
| 1869 * Due to its expense, the software path renderer has split out so it can | 1863 * Due to its expense, the software path renderer has split out so it can |
| 1870 * can be individually allowed/disallowed via the "allowSW" boolean. | 1864 * can be individually allowed/disallowed via the "allowSW" boolean. |
| 1871 */ | 1865 */ |
| 1872 GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target, | 1866 GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target, |
| 1873 const GrPipelineBuilder* pipelineBuil
der, | 1867 const GrPipelineBuilder* pipelineBuil
der, |
| 1874 const SkMatrix& viewMatrix, | 1868 const SkMatrix& viewMatrix, |
| 1875 const SkPath& path, | 1869 const SkPath& path, |
| 1876 const SkStrokeRec& stroke, | 1870 const GrStrokeInfo& stroke, |
| 1877 bool allowSW, | 1871 bool allowSW, |
| 1878 GrPathRendererChain::DrawType drawTyp
e, | 1872 GrPathRendererChain::DrawType drawTyp
e, |
| 1879 GrPathRendererChain::StencilSupport*
stencilSupport) { | 1873 GrPathRendererChain::StencilSupport*
stencilSupport) { |
| 1880 | 1874 |
| 1881 if (NULL == fPathRendererChain) { | 1875 if (NULL == fPathRendererChain) { |
| 1882 fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); | 1876 fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); |
| 1883 } | 1877 } |
| 1884 | 1878 |
| 1885 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target, | 1879 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target, |
| 1886 pipelineBuilder, | 1880 pipelineBuilder, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2031 } | 2025 } |
| 2032 } | 2026 } |
| 2033 | 2027 |
| 2034 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { | 2028 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { |
| 2035 fGpu->removeGpuTraceMarker(marker); | 2029 fGpu->removeGpuTraceMarker(marker); |
| 2036 if (fDrawBuffer) { | 2030 if (fDrawBuffer) { |
| 2037 fDrawBuffer->removeGpuTraceMarker(marker); | 2031 fDrawBuffer->removeGpuTraceMarker(marker); |
| 2038 } | 2032 } |
| 2039 } | 2033 } |
| 2040 | 2034 |
| OLD | NEW |