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

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: address review comments Created 5 years, 7 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
« no previous file with comments | « src/gpu/GrClipMaskManager.cpp ('k') | src/gpu/GrDashLinePathRenderer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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,
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
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
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
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.cpp ('k') | src/gpu/GrDashLinePathRenderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698