From 328a33fc7abd9b6de99409a9b6e44c5c372609d5 Mon Sep 17 00:00:00 2001 From: Jim Van Verth Date: Fri, 20 Oct 2017 12:14:22 -0400 Subject: Use uint16_t instead of SkIPoint16 when clipping texCoords for text. The texCoords and texture indices are packed into two uint16_t, so that should be used instead of SkIPoint16 for clipping. This CL also cleans up the clipping code a little, and keeps everything in int arithmetic (since the positions and coords are pixel/texel aligned). Bug: skia:6990 Change-Id: I9a237f7df32467adb6a56ddeca6352cbd4f8dd6f Reviewed-on: https://skia-review.googlesource.com/62360 Reviewed-by: Robert Phillips Commit-Queue: Jim Van Verth --- src/gpu/ops/GrAtlasTextOp.cpp | 113 +++++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp index e8a0115ad5..257fb3b9e9 100644 --- a/src/gpu/ops/GrAtlasTextOp.cpp +++ b/src/gpu/ops/GrAtlasTextOp.cpp @@ -83,10 +83,11 @@ static void clip_quads(const SkIRect& clipRect, SkPoint* blobPositionLT = reinterpret_cast(blobVertices); SkPoint* blobPositionRB = reinterpret_cast(blobVertices + 3*vertexStride); - SkRect positionRect = SkRect::MakeLTRB(blobPositionLT->fX, - blobPositionLT->fY, - blobPositionRB->fX, - blobPositionRB->fY); + // positions for bitmap glyphs are pixel boundary aligned + SkIRect positionRect = SkIRect::MakeLTRB(blobPositionLT->fX, + blobPositionLT->fY, + blobPositionRB->fX, + blobPositionRB->fY); if (clipRect.contains(positionRect)) { memcpy(currVertex, blobVertices, 4 * vertexStride); currVertex += 4 * vertexStride; @@ -95,82 +96,82 @@ static void clip_quads(const SkIRect& clipRect, // In the LCD case the color will be garbage, but we'll overwrite it with the texcoords // and it avoids a lot of conditionals. SkColor color = *reinterpret_cast(blobVertices + sizeof(SkPoint)); - size_t coordOffset = vertexStride - sizeof(SkIPoint16); - SkIPoint16* blobCoordsLT = reinterpret_cast(blobVertices + coordOffset); - SkIPoint16* blobCoordsRB = reinterpret_cast(blobVertices + - 3*vertexStride + - coordOffset); - SkIRect coordsRect = SkIRect::MakeLTRB(blobCoordsLT->fX / 2, - blobCoordsLT->fY / 2, - blobCoordsRB->fX / 2, - blobCoordsRB->fY / 2); - int pageIndexX = blobCoordsLT->fX & 0x1; - int pageIndexY = blobCoordsLT->fY & 0x1; - - SkASSERT(positionRect.width() == coordsRect.width()); + size_t coordOffset = vertexStride - 2*sizeof(uint16_t); + uint16_t* blobCoordsLT = reinterpret_cast(blobVertices + coordOffset); + uint16_t* blobCoordsRB = reinterpret_cast(blobVertices + 3*vertexStride + + coordOffset); + // Pull out the texel coordinates and texture index bits + uint16_t coordsRectL = blobCoordsLT[0] >> 1; + uint16_t coordsRectT = blobCoordsLT[1] >> 1; + uint16_t coordsRectR = blobCoordsRB[0] >> 1; + uint16_t coordsRectB = blobCoordsRB[1] >> 1; + uint16_t pageIndexX = blobCoordsLT[0] & 0x1; + uint16_t pageIndexY = blobCoordsLT[1] & 0x1; + + int positionRectWidth = positionRect.width(); + int positionRectHeight = positionRect.height(); + SkASSERT(positionRectWidth == (coordsRectR - coordsRectL)); + SkASSERT(positionRectHeight == (coordsRectB - coordsRectT)); // Clip position and texCoords to the clipRect - if (positionRect.fLeft < clipRect.fLeft) { - coordsRect.fLeft += clipRect.fLeft - positionRect.fLeft; - positionRect.fLeft = clipRect.fLeft; - } - if (positionRect.fTop < clipRect.fTop) { - coordsRect.fTop += clipRect.fTop - positionRect.fTop; - positionRect.fTop = clipRect.fTop; - } - if (positionRect.fRight > clipRect.fRight) { - coordsRect.fRight += clipRect.fRight - positionRect.fRight; - positionRect.fRight = clipRect.fRight; - } - if (positionRect.fBottom > clipRect.fBottom) { - coordsRect.fBottom += clipRect.fBottom - positionRect.fBottom; - positionRect.fBottom = clipRect.fBottom; - } - if (positionRect.fLeft > positionRect.fRight) { - positionRect.fLeft = positionRect.fRight; - } - if (positionRect.fTop > positionRect.fBottom) { - positionRect.fTop = positionRect.fBottom; - } - coordsRect.fLeft = 2 * coordsRect.fLeft | pageIndexX; - coordsRect.fTop = 2 * coordsRect.fTop | pageIndexY; - coordsRect.fRight = 2 * coordsRect.fRight | pageIndexX; - coordsRect.fBottom = 2 * coordsRect.fBottom | pageIndexY; - + unsigned int delta; + delta = SkTMin(SkTMax(clipRect.fLeft - positionRect.fLeft, 0), positionRectWidth); + coordsRectL += delta; + positionRect.fLeft += delta; + + delta = SkTMin(SkTMax(clipRect.fTop - positionRect.fTop, 0), positionRectHeight); + coordsRectT += delta; + positionRect.fTop += delta; + + delta = SkTMin(SkTMax(positionRect.fRight - clipRect.fRight, 0), positionRectWidth); + coordsRectR -= delta; + positionRect.fRight -= delta; + + delta = SkTMin(SkTMax(positionRect.fBottom - clipRect.fBottom, 0), positionRectHeight); + coordsRectB -= delta; + positionRect.fBottom -= delta; + + // Repack texel coordinates and index + coordsRectL = coordsRectL << 1 | pageIndexX; + coordsRectT = coordsRectT << 1 | pageIndexY; + coordsRectR = coordsRectR << 1 | pageIndexX; + coordsRectB = coordsRectB << 1 | pageIndexY; + + // Set new positions and coords SkPoint* currPosition = reinterpret_cast(currVertex); currPosition->fX = positionRect.fLeft; currPosition->fY = positionRect.fTop; *(reinterpret_cast(currVertex + sizeof(SkPoint))) = color; - SkIPoint16* currCoords = reinterpret_cast(currVertex + coordOffset); - currCoords->fX = coordsRect.fLeft; - currCoords->fY = coordsRect.fTop; + uint16_t* currCoords = reinterpret_cast(currVertex + coordOffset); + currCoords[0] = coordsRectL; + currCoords[1] = coordsRectT; currVertex += vertexStride; currPosition = reinterpret_cast(currVertex); currPosition->fX = positionRect.fLeft; currPosition->fY = positionRect.fBottom; *(reinterpret_cast(currVertex + sizeof(SkPoint))) = color; - currCoords = reinterpret_cast(currVertex + coordOffset); - currCoords->fX = coordsRect.fLeft; - currCoords->fY = coordsRect.fBottom; + currCoords = reinterpret_cast(currVertex + coordOffset); + currCoords[0] = coordsRectL; + currCoords[1] = coordsRectB; currVertex += vertexStride; currPosition = reinterpret_cast(currVertex); currPosition->fX = positionRect.fRight; currPosition->fY = positionRect.fTop; *(reinterpret_cast(currVertex + sizeof(SkPoint))) = color; - currCoords = reinterpret_cast(currVertex + coordOffset); - currCoords->fX = coordsRect.fRight; - currCoords->fY = coordsRect.fTop; + currCoords = reinterpret_cast(currVertex + coordOffset); + currCoords[0] = coordsRectR; + currCoords[1] = coordsRectT; currVertex += vertexStride; currPosition = reinterpret_cast(currVertex); currPosition->fX = positionRect.fRight; currPosition->fY = positionRect.fBottom; *(reinterpret_cast(currVertex + sizeof(SkPoint))) = color; - currCoords = reinterpret_cast(currVertex + coordOffset); - currCoords->fX = coordsRect.fRight; - currCoords->fY = coordsRect.fBottom; + currCoords = reinterpret_cast(currVertex + coordOffset); + currCoords[0] = coordsRectR; + currCoords[1] = coordsRectB; currVertex += vertexStride; } -- cgit v1.2.3