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

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

Issue 1100073003: Extract gpu line dashing to GrDashLinePathRenderer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 8 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 /* 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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698