diff options
author | 2015-05-13 08:00:56 -0700 | |
---|---|---|
committer | 2015-05-13 08:00:56 -0700 | |
commit | 4c977868bbe100d6d95f9e53cf176d611eceb3dc (patch) | |
tree | 53540958162109720ff971cee4545ac90ce7a531 /src/gpu | |
parent | 28761fe4fb74e162a902323e900746b2a9e9c1db (diff) |
fix bounds for BW lines, AA Hairlines
BUG=skia:
Review URL: https://codereview.chromium.org/1123253003
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrAAHairLinePathRenderer.cpp | 4 | ||||
-rwxr-xr-x | src/gpu/GrContext.cpp | 25 |
2 files changed, 23 insertions, 6 deletions
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index c5d8ae1126..3508727e77 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -730,6 +730,10 @@ private: // compute bounds fBounds = geometry.fPath.getBounds(); geometry.fViewMatrix.mapRect(&fBounds); + + // This is b.c. hairlines are notionally infinitely thin so without expansion + // two overlapping lines could be reordered even though they hit the same pixels. + fBounds.outset(0.5f, 0.5f); } bool onCombineIfPossible(GrBatch* t) override { diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index e26c57f9f6..bf62538434 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -404,8 +404,8 @@ public: SkScalar fStrokeWidth; }; - static GrBatch* Create(const Geometry& geometry) { - return SkNEW_ARGS(StrokeRectBatch, (geometry)); + static GrBatch* Create(const Geometry& geometry, bool snapToPixelCenters) { + return SkNEW_ARGS(StrokeRectBatch, (geometry, snapToPixelCenters)); } const char* name() const override { return "StrokeRectBatch"; } @@ -501,7 +501,7 @@ public: SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } private: - StrokeRectBatch(const Geometry& geometry) { + StrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) { this->initClassID<StrokeRectBatch>(); fBatch.fHairline = geometry.fStrokeWidth == 0; @@ -513,6 +513,11 @@ private: SkScalar rad = SkScalarHalf(geometry.fStrokeWidth); fBounds.outset(rad, rad); geometry.fViewMatrix.mapRect(&fBounds); + + // If our caller snaps to pixel centers then we have to round out the bounds + if (snapToPixelCenters) { + fBounds.roundOut(); + } } /* create a triangle strip that strokes the specified rect. There are 8 @@ -661,13 +666,15 @@ void GrContext::drawRect(GrRenderTarget* rt, geometry.fRect = rect; geometry.fStrokeWidth = width; - SkAutoTUnref<GrBatch> batch(StrokeRectBatch::Create(geometry)); + // Non-AA hairlines are snapped to pixel centers to make which pixels are hit deterministic + bool snapToPixelCenters = (0 == width && !rt->isMultisampled()); + SkAutoTUnref<GrBatch> batch(StrokeRectBatch::Create(geometry, snapToPixelCenters)); // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of // hairline rects. We jam all the vertices to pixel centers to avoid this, but not when MSAA // is enabled because it can cause ugly artifacts. pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag, - 0 == width && !rt->isMultisampled()); + snapToPixelCenters); target->drawBatch(&pipelineBuilder, batch); } else { // filled BW rect @@ -1008,6 +1015,12 @@ void GrContext::drawVertices(GrRenderTarget* rt, viewMatrix.mapRect(&bounds); + // If we don't have AA then we outset for a half pixel in each direction to account for + // snapping + if (!paint.isAntiAlias()) { + bounds.outset(0.5f, 0.5f); + } + DrawVerticesBatch::Geometry geometry; geometry.fColor = paint.getColor(); SkAutoTUnref<GrBatch> batch(DrawVerticesBatch::Create(geometry, primitiveType, viewMatrix, @@ -1879,7 +1892,7 @@ BATCH_TEST_DEFINE(StrokeRect) { geometry.fRect = GrTest::TestRect(random); geometry.fStrokeWidth = random->nextBool() ? 0.0f : 1.0f; - return StrokeRectBatch::Create(geometry); + return StrokeRectBatch::Create(geometry, random->nextBool()); } static uint32_t seed_vertices(GrPrimitiveType type) { |