From a442526622aa4357ac8263f78d9fd7eae2c70bc8 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Thu, 26 Jul 2018 13:37:53 -0400 Subject: Correctly distinguish hairline paths in the SW path renderer's cache We typically don't get hairline paths in the SW path renderer, but an upcoming change (https://skia-review.googlesource.com/c/skia/+/142272) makes it possible. Therefore, we need to distinguish between hairline and filled paths. Additionally, the CPU renderer draws hairline paths differently with round/square caps (extended by 1/2 pixel) than with butt caps, so include that in the key, too. Bug: skia:8188 Change-Id: I223c11f62ef1c13f0488f2ca8c19a19875fc3d9f Reviewed-on: https://skia-review.googlesource.com/143540 Reviewed-by: Brian Salomon Commit-Queue: Brian Osman --- src/gpu/GrSoftwarePathRenderer.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 213dbdb025..8b022739fd 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -291,31 +291,33 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) { SkScalar kx = args.fViewMatrix->get(SkMatrix::kMSkewX); SkScalar ky = args.fViewMatrix->get(SkMatrix::kMSkewY); static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); + GrUniqueKey::Builder builder(&maskKey, kDomain, 5 + args.fShape->unstyledKeySize(), + "SW Path Mask"); #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK // Fractional translate does not affect caching on Android. This is done for better cache // hit ratio and speed, but it is matching HWUI behavior, which doesn't consider the matrix // at all when caching paths. - GrUniqueKey::Builder builder(&maskKey, kDomain, 4 + args.fShape->unstyledKeySize(), - "SW Path Mask"); + SkFixed fracX = 0; + SkFixed fracY = 0; #else SkScalar tx = args.fViewMatrix->get(SkMatrix::kMTransX); SkScalar ty = args.fViewMatrix->get(SkMatrix::kMTransY); // Allow 8 bits each in x and y of subpixel positioning. SkFixed fracX = SkScalarToFixed(SkScalarFraction(tx)) & 0x0000FF00; SkFixed fracY = SkScalarToFixed(SkScalarFraction(ty)) & 0x0000FF00; - GrUniqueKey::Builder builder(&maskKey, kDomain, 5 + args.fShape->unstyledKeySize(), - "SW Path Mask"); #endif builder[0] = SkFloat2Bits(sx); builder[1] = SkFloat2Bits(sy); builder[2] = SkFloat2Bits(kx); builder[3] = SkFloat2Bits(ky); -#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK - args.fShape->writeUnstyledKey(&builder[4]); -#else - builder[4] = fracX | (fracY >> 8); + // Distinguish between hairline and filled paths. For hairlines, we also need to include + // the cap. (SW grows hairlines by 0.5 pixel with round and square caps). Note that + // stroke-and-fill of hairlines is turned into pure fill by SkStrokeRec, so this covers + // all cases we might see. + uint32_t styleBits = args.fShape->style().isSimpleHairline() ? + ((args.fShape->style().strokeRec().getCap() << 1) | 1) : 0; + builder[4] = fracX | (fracY >> 8) | (styleBits << 16); args.fShape->writeUnstyledKey(&builder[5]); -#endif } sk_sp proxy; -- cgit v1.2.3