aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/effects/GrDistanceFieldGeoProc.cpp4
-rw-r--r--src/gpu/ops/GrAADistanceFieldPathRenderer.cpp381
-rw-r--r--src/gpu/ops/GrAADistanceFieldPathRenderer.h37
3 files changed, 100 insertions, 322 deletions
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index 1c2ef6494a..89ec238efd 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -518,7 +518,7 @@ GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(
fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
kHigh_GrSLPrecision);
fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
- fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType);
+ fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2f_GrVertexAttribType);
this->addTextureSampler(&fTextureSampler);
}
@@ -542,7 +542,7 @@ GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(
fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
kHigh_GrSLPrecision);
fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
- fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2us_GrVertexAttribType);
+ fInTextureCoords = &this->addVertexAttrib("inTextureCoords", kVec2f_GrVertexAttribType);
this->addTextureSampler(&fTextureSampler);
}
diff --git a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
index d4b2b16cc9..7ed14ba7de 100644
--- a/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/ops/GrAADistanceFieldPathRenderer.cpp
@@ -18,7 +18,6 @@
#include "GrSWMaskHelper.h"
#include "GrSurfacePriv.h"
#include "GrTexturePriv.h"
-#include "effects/GrBitmapTextGeoProc.h"
#include "effects/GrDistanceFieldGeoProc.h"
#include "ops/GrMeshDrawOp.h"
@@ -166,36 +165,16 @@ private:
bool gammaCorrect)
: INHERITED(ClassID()) {
SkASSERT(shape.hasUnstyledKey());
- // Compute bounds
- this->setTransformedBounds(shape.bounds(), viewMatrix, HasAABloat::kYes, IsZeroArea::kNo);
-
-#ifdef SK_BUILD_FOR_ANDROID
- fUsesDistanceField = true;
-#else
- // only use distance fields on desktop to save space in the atlas
- fUsesDistanceField = this->bounds().width() > kMaxMIP || this->bounds().height() > kMaxMIP;
-#endif
fViewMatrix = viewMatrix;
- SkVector translate = SkVector::Make(0, 0);
- if (!fUsesDistanceField) {
- // In this case we don't apply a view matrix, so we need to remove the non-subpixel
- // translation and add it back when we generate the quad for the path
- SkScalar translateX = viewMatrix.getTranslateX();
- SkScalar translateY = viewMatrix.getTranslateY();
- translate = SkVector::Make(SkScalarFloorToScalar(translateX),
- SkScalarFloorToScalar(translateY));
- // Only store the fractional part of the translation in the view matrix
- fViewMatrix.setTranslateX(translateX - translate.fX);
- fViewMatrix.setTranslateY(translateY - translate.fY);
- }
-
- fShapes.emplace_back(Entry{color, shape, translate});
+ fShapes.emplace_back(Entry{color, shape});
fAtlas = atlas;
fShapeCache = shapeCache;
fShapeList = shapeList;
fGammaCorrect = gammaCorrect;
+ // Compute bounds
+ this->setTransformedBounds(shape.bounds(), viewMatrix, HasAABloat::kYes, IsZeroArea::kNo);
}
void getFragmentProcessorAnalysisInputs(FragmentProcessorAnalysisInputs* input) const override {
@@ -219,45 +198,34 @@ private:
void onPrepareDraws(Target* target) const override {
int instanceCount = fShapes.count();
+ SkMatrix invert;
+ if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) {
+ SkDebugf("Could not invert viewmatrix\n");
+ return;
+ }
+
const SkMatrix& ctm = this->viewMatrix();
+ uint32_t flags = 0;
+ flags |= ctm.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0;
+ flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
+ flags |= fGammaCorrect ? kGammaCorrect_DistanceFieldEffectFlag : 0;
+
+ GrSamplerParams params(SkShader::kRepeat_TileMode, GrSamplerParams::kBilerp_FilterMode);
FlushInfo flushInfo;
// Setup GrGeometryProcessor
GrDrawOpAtlas* atlas = fAtlas;
- if (fUsesDistanceField) {
- GrSamplerParams params(SkShader::kClamp_TileMode, GrSamplerParams::kBilerp_FilterMode);
-
- uint32_t flags = 0;
- flags |= ctm.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0;
- flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
- flags |= fGammaCorrect ? kGammaCorrect_DistanceFieldEffectFlag : 0;
-
- flushInfo.fGeometryProcessor = GrDistanceFieldPathGeoProc::Make(
- this->color(), this->viewMatrix(), atlas->getTexture(), params, flags,
- this->usesLocalCoords());
- } else {
- GrSamplerParams params(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode);
-
- SkMatrix invert;
- if (this->usesLocalCoords()) {
- if (!this->viewMatrix().invert(&invert)) {
- SkDebugf("Could not invert viewmatrix\n");
- return;
- }
- // for local coords, we need to add the translation back in that we removed
- // from the stored view matrix
- invert.preTranslate(-fShapes[0].fTranslate.fX, -fShapes[0].fTranslate.fY);
- }
-
- flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
- this->color(), atlas->getTexture(), params, kA8_GrMaskFormat, invert,
- this->usesLocalCoords());
- }
+ flushInfo.fGeometryProcessor = GrDistanceFieldPathGeoProc::Make(this->color(),
+ this->viewMatrix(),
+ atlas->getTexture(),
+ params,
+ flags,
+ this->usesLocalCoords());
// allocate vertices
size_t vertexStride = flushInfo.fGeometryProcessor->getVertexStride();
- SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(GrColor) + 2*sizeof(uint16_t));
+ SkASSERT(vertexStride == 2 * sizeof(SkPoint) + sizeof(GrColor));
const GrBuffer* vertexBuffer;
void* vertices = target->makeVertexSpace(vertexStride,
@@ -277,94 +245,65 @@ private:
for (int i = 0; i < instanceCount; i++) {
const Entry& args = fShapes[i];
- ShapeData* shapeData;
- SkScalar maxScale;
- if (fUsesDistanceField) {
- // get mip level
- maxScale = SkScalarAbs(this->viewMatrix().getMaxScale());
- const SkRect& bounds = args.fShape.bounds();
- SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
- // We try to create the DF at a 2^n scaled path resolution (1/2, 1, 2, 4, etc.)
- // In the majority of cases this will yield a crisper rendering.
- SkScalar mipScale = 1.0f;
- // Our mipscale is the maxScale clamped to the next highest power of 2
- if (maxScale <= SK_ScalarHalf) {
- SkScalar log = SkScalarFloorToScalar(SkScalarLog2(SkScalarInvert(maxScale)));
- mipScale = SkScalarPow(2, -log);
- } else if (maxScale > SK_Scalar1) {
- SkScalar log = SkScalarCeilToScalar(SkScalarLog2(maxScale));
- mipScale = SkScalarPow(2, log);
- }
- SkASSERT(maxScale <= mipScale);
-
- SkScalar mipSize = mipScale*SkScalarAbs(maxDim);
- // For sizes less than kIdealMinMIP we want to use as large a distance field as we can
- // so we can preserve as much detail as possible. However, we can't scale down more
- // than a 1/4 of the size without artifacts. So the idea is that we pick the mipsize
- // just bigger than the ideal, and then scale down until we are no more than 4x the
- // original mipsize.
- if (mipSize < kIdealMinMIP) {
- SkScalar newMipSize = mipSize;
- do {
- newMipSize *= 2;
- } while (newMipSize < kIdealMinMIP);
- while (newMipSize > 4 * mipSize) {
- newMipSize *= 0.25f;
- }
- mipSize = newMipSize;
+ // get mip level
+ SkScalar maxScale = SkScalarAbs(this->viewMatrix().getMaxScale());
+ const SkRect& bounds = args.fShape.bounds();
+ SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
+ // We try to create the DF at a power of two scaled path resolution (1/2, 1, 2, 4, etc)
+ // In the majority of cases this will yield a crisper rendering.
+ SkScalar mipScale = 1.0f;
+ // Our mipscale is the maxScale clamped to the next highest power of 2
+ if (maxScale <= SK_ScalarHalf) {
+ SkScalar log = SkScalarFloorToScalar(SkScalarLog2(SkScalarInvert(maxScale)));
+ mipScale = SkScalarPow(2, -log);
+ } else if (maxScale > SK_Scalar1) {
+ SkScalar log = SkScalarCeilToScalar(SkScalarLog2(maxScale));
+ mipScale = SkScalarPow(2, log);
+ }
+ SkASSERT(maxScale <= mipScale);
+
+ SkScalar mipSize = mipScale*SkScalarAbs(maxDim);
+ // For sizes less than kIdealMinMIP we want to use as large a distance field as we can
+ // so we can preserve as much detail as possible. However, we can't scale down more
+ // than a 1/4 of the size without artifacts. So the idea is that we pick the mipsize
+ // just bigger than the ideal, and then scale down until we are no more than 4x the
+ // original mipsize.
+ if (mipSize < kIdealMinMIP) {
+ SkScalar newMipSize = mipSize;
+ do {
+ newMipSize *= 2;
+ } while (newMipSize < kIdealMinMIP);
+ while (newMipSize > 4*mipSize) {
+ newMipSize *= 0.25f;
}
- SkScalar desiredDimension = SkTMin(mipSize, kMaxMIP);
-
- // check to see if df path is cached
- ShapeData::Key key(args.fShape, SkScalarCeilToInt(desiredDimension));
- shapeData = fShapeCache->find(key);
- if (nullptr == shapeData || !atlas->hasID(shapeData->fID)) {
- // Remove the stale cache entry
- if (shapeData) {
- fShapeCache->remove(shapeData->fKey);
- fShapeList->remove(shapeData);
- delete shapeData;
- }
- SkScalar scale = desiredDimension / maxDim;
-
- shapeData = new ShapeData;
- if (!this->addDFPathToAtlas(target,
- &flushInfo,
- atlas,
- shapeData,
- args.fShape,
- SkScalarCeilToInt(desiredDimension),
- scale)) {
- delete shapeData;
- SkDebugf("Can't rasterize path\n");
- continue;
- }
+ mipSize = newMipSize;
+ }
+ SkScalar desiredDimension = SkTMin(mipSize, kMaxMIP);
+
+ // check to see if path is cached
+ ShapeData::Key key(args.fShape, SkScalarCeilToInt(desiredDimension));
+ ShapeData* shapeData = fShapeCache->find(key);
+ if (nullptr == shapeData || !atlas->hasID(shapeData->fID)) {
+ // Remove the stale cache entry
+ if (shapeData) {
+ fShapeCache->remove(shapeData->fKey);
+ fShapeList->remove(shapeData);
+ delete shapeData;
}
- } else {
- // check to see if bitmap path is cached
- ShapeData::Key key(args.fShape, this->viewMatrix());
- shapeData = fShapeCache->find(key);
- if (nullptr == shapeData || !atlas->hasID(shapeData->fID)) {
- // Remove the stale cache entry
- if (shapeData) {
- fShapeCache->remove(shapeData->fKey);
- fShapeList->remove(shapeData);
- delete shapeData;
- }
-
- shapeData = new ShapeData;
- if (!this->addBMPathToAtlas(target,
- &flushInfo,
- atlas,
- shapeData,
- args.fShape,
- this->viewMatrix())) {
- delete shapeData;
- SkDebugf("Can't rasterize path\n");
- continue;
- }
+ SkScalar scale = desiredDimension/maxDim;
+
+ shapeData = new ShapeData;
+ if (!this->addPathToAtlas(target,
+ &flushInfo,
+ atlas,
+ shapeData,
+ args.fShape,
+ SkScalarCeilToInt(desiredDimension),
+ scale)) {
+ delete shapeData;
+ SkDebugf("Can't rasterize path\n");
+ continue;
}
- maxScale = 1;
}
atlas->setLastUseToken(shapeData->fID, target->nextDrawToken());
@@ -375,7 +314,6 @@ private:
args.fColor,
vertexStride,
maxScale,
- args.fTranslate,
shapeData);
offset += kVerticesPerQuad * vertexStride;
flushInfo.fInstancesToFlush++;
@@ -384,9 +322,9 @@ private:
this->flush(target, &flushInfo);
}
- bool addDFPathToAtlas(GrMeshDrawOp::Target* target, FlushInfo* flushInfo, GrDrawOpAtlas* atlas,
- ShapeData* shapeData, const GrShape& shape, uint32_t dimension,
- SkScalar scale) const {
+ bool addPathToAtlas(GrMeshDrawOp::Target* target, FlushInfo* flushInfo, GrDrawOpAtlas* atlas,
+ ShapeData* shapeData, const GrShape& shape, uint32_t dimension,
+ SkScalar scale) const {
const SkRect& bounds = shape.bounds();
// generate bounding rect for bitmap draw
@@ -501,121 +439,23 @@ private:
return true;
}
- bool addBMPathToAtlas(GrMeshDrawOp::Target* target, FlushInfo* flushInfo,
- GrDrawOpAtlas* atlas, ShapeData* shapeData,
- const GrShape& shape, const SkMatrix& ctm) const {
- const SkRect& bounds = shape.bounds();
- if (bounds.isEmpty()) {
- return false;
- }
- SkMatrix drawMatrix(ctm);
- drawMatrix.set(SkMatrix::kMTransX, SkScalarFraction(ctm.get(SkMatrix::kMTransX)));
- drawMatrix.set(SkMatrix::kMTransY, SkScalarFraction(ctm.get(SkMatrix::kMTransY)));
- SkRect shapeDevBounds;
- drawMatrix.mapRect(&shapeDevBounds, bounds);
- SkScalar dx = SkScalarFloorToScalar(shapeDevBounds.fLeft);
- SkScalar dy = SkScalarFloorToScalar(shapeDevBounds.fTop);
-
- // get integer boundary
- SkIRect devPathBounds;
- shapeDevBounds.roundOut(&devPathBounds);
- // pad to allow room for antialiasing
- const int intPad = SkScalarCeilToInt(kAntiAliasPad);
- // place devBounds at origin
- int width = devPathBounds.width() + 2 * intPad;
- int height = devPathBounds.height() + 2 * intPad;
- devPathBounds = SkIRect::MakeWH(width, height);
- SkScalar translateX = intPad - dx;
- SkScalar translateY = intPad - dy;
-
- SkASSERT(devPathBounds.fLeft == 0);
- SkASSERT(devPathBounds.fTop == 0);
- SkASSERT(devPathBounds.width() > 0);
- SkASSERT(devPathBounds.height() > 0);
-
- SkPath path;
- shape.asPath(&path);
- // setup bitmap backing
- SkAutoPixmapStorage dst;
- if (!dst.tryAlloc(SkImageInfo::MakeA8(devPathBounds.width(),
- devPathBounds.height()))) {
- return false;
- }
- sk_bzero(dst.writable_addr(), dst.getSafeSize());
-
- // rasterize path
- SkPaint paint;
- paint.setStyle(SkPaint::kFill_Style);
- paint.setAntiAlias(true);
-
- SkDraw draw;
- sk_bzero(&draw, sizeof(draw));
-
- SkRasterClip rasterClip;
- rasterClip.setRect(devPathBounds);
- draw.fRC = &rasterClip;
- drawMatrix.postTranslate(translateX, translateY);
- draw.fMatrix = &drawMatrix;
- draw.fDst = dst;
-
- draw.drawPathCoverage(path, paint);
-
- // add to atlas
- SkIPoint16 atlasLocation;
- GrDrawOpAtlas::AtlasID id;
- if (!atlas->addToAtlas(&id, target, dst.width(), dst.height(), dst.addr(),
- &atlasLocation)) {
- this->flush(target, flushInfo);
- if (!atlas->addToAtlas(&id, target, dst.width(), dst.height(), dst.addr(),
- &atlasLocation)) {
- return false;
- }
- }
-
- // add to cache
- shapeData->fKey.set(shape, drawMatrix);
- shapeData->fID = id;
-
- // set the bounds rect to the original bounds
- shapeData->fBounds = SkRect::Make(devPathBounds);
- shapeData->fBounds.offset(-translateX, -translateY);
-
- // set up path to texture coordinate transform
- shapeData->fScale = SK_Scalar1;
- shapeData->fTranslate.fX = atlasLocation.fX + translateX;
- shapeData->fTranslate.fY = atlasLocation.fY + translateY;
-
- fShapeCache->add(shapeData);
- fShapeList->addToTail(shapeData);
-#ifdef DF_PATH_TRACKING
- ++g_NumCachedPaths;
-#endif
- return true;
- }
-
void writePathVertices(GrDrawOp::Target* target,
GrDrawOpAtlas* atlas,
intptr_t offset,
GrColor color,
size_t vertexStride,
SkScalar maxScale,
- const SkVector& preTranslate,
const ShapeData* shapeData) const {
SkPoint* positions = reinterpret_cast<SkPoint*>(offset);
+ // outset bounds to include ~1 pixel of AA in device space
SkRect bounds = shapeData->fBounds;
- if (fUsesDistanceField) {
- // outset bounds to include ~1 pixel of AA in device space
- SkScalar outset = SkScalarInvert(maxScale);
- bounds.outset(outset, outset);
- }
+ SkScalar outset = SkScalarInvert(maxScale);
+ bounds.outset(outset, outset);
// vertex positions
// TODO make the vertex attributes a struct
- positions->setRectFan(bounds.left() + preTranslate.fX,
- bounds.top() + preTranslate.fY,
- bounds.right() + preTranslate.fX,
- bounds.bottom() + preTranslate.fY,
+ positions->setRectFan(bounds.left(), bounds.top(), bounds.right(), bounds.bottom(),
vertexStride);
// colors
@@ -642,32 +482,15 @@ private:
texRight += translate.fX;
texBottom += translate.fY;
- // convert texcoords to unsigned short format
+ // vertex texture coords
+ // TODO make these int16_t
+ SkPoint* textureCoords = (SkPoint*)(offset + sizeof(SkPoint) + sizeof(GrColor));
GrTexture* texture = atlas->getTexture();
- SkScalar uFactor = 65535.f / texture->width();
- SkScalar vFactor = 65535.f / texture->height();
- uint16_t l = (uint16_t)(texLeft*uFactor);
- uint16_t t = (uint16_t)(texTop*vFactor);
- uint16_t r = (uint16_t)(texRight*uFactor);
- uint16_t b = (uint16_t)(texBottom*vFactor);
-
- // set vertex texture coords
- intptr_t textureCoordOffset = offset + sizeof(SkPoint) + sizeof(GrColor);
- uint16_t* textureCoords = (uint16_t*) textureCoordOffset;
- textureCoords[0] = l;
- textureCoords[1] = t;
- textureCoordOffset += vertexStride;
- textureCoords = (uint16_t*)textureCoordOffset;
- textureCoords[0] = l;
- textureCoords[1] = b;
- textureCoordOffset += vertexStride;
- textureCoords = (uint16_t*)textureCoordOffset;
- textureCoords[0] = r;
- textureCoords[1] = b;
- textureCoordOffset += vertexStride;
- textureCoords = (uint16_t*)textureCoordOffset;
- textureCoords[0] = r;
- textureCoords[1] = t;
+ textureCoords->setRectFan(texLeft / texture->width(),
+ texTop / texture->height(),
+ texRight / texture->width(),
+ texBottom / texture->height(),
+ vertexStride);
}
void flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const {
@@ -687,7 +510,6 @@ private:
GrColor color() const { return fShapes[0].fColor; }
const SkMatrix& viewMatrix() const { return fViewMatrix; }
bool usesLocalCoords() const { return fUsesLocalCoords; }
- bool usesDistanceField() const { return fUsesDistanceField; }
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
AADistanceFieldPathOp* that = t->cast<AADistanceFieldPathOp>();
@@ -696,20 +518,11 @@ private:
return false;
}
- if (this->usesDistanceField() != that->usesDistanceField()) {
- return false;
- }
-
- // TODO We can position on the cpu for distance field paths
+ // TODO We can position on the cpu
if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
return false;
}
- if (!this->usesDistanceField() && this->usesLocalCoords() &&
- !this->fShapes[0].fTranslate.equalsWithinTolerance(that->fShapes[0].fTranslate)) {
- return false;
- }
-
fShapes.push_back_n(that->fShapes.count(), that->fShapes.begin());
this->joinBounds(*that);
return true;
@@ -717,12 +530,10 @@ private:
SkMatrix fViewMatrix;
bool fUsesLocalCoords;
- bool fUsesDistanceField;
struct Entry {
- GrColor fColor;
- GrShape fShape;
- SkVector fTranslate;
+ GrColor fColor;
+ GrShape fShape;
};
SkSTArray<1, Entry> fShapes;
diff --git a/src/gpu/ops/GrAADistanceFieldPathRenderer.h b/src/gpu/ops/GrAADistanceFieldPathRenderer.h
index 732888e3ba..202b114e23 100644
--- a/src/gpu/ops/GrAADistanceFieldPathRenderer.h
+++ b/src/gpu/ops/GrAADistanceFieldPathRenderer.h
@@ -38,7 +38,6 @@ private:
Key() {}
Key(const Key& that) { *this = that; }
Key(const GrShape& shape, uint32_t dim) { this->set(shape, dim); }
- Key(const GrShape& shape, const SkMatrix& ctm) { this->set(shape, ctm); }
Key& operator=(const Key& that) {
fKey.reset(that.fKey.count());
@@ -57,37 +56,6 @@ private:
shape.writeUnstyledKey(&fKey[1]);
}
- void set(const GrShape& shape, const SkMatrix& ctm) {
- GrUniqueKey maskKey;
- struct KeyData {
- SkScalar fFractionalTranslateX;
- SkScalar fFractionalTranslateY;
- };
-
- // Shapes' keys are for their pre-style geometry, but by now we shouldn't have any
- // relevant styling information.
- SkASSERT(shape.style().isSimpleFill());
- SkASSERT(shape.hasUnstyledKey());
- // We require the upper left 2x2 of the matrix to match exactly for a cache hit.
- SkScalar sx = ctm.get(SkMatrix::kMScaleX);
- SkScalar sy = ctm.get(SkMatrix::kMScaleY);
- SkScalar kx = ctm.get(SkMatrix::kMSkewX);
- SkScalar ky = ctm.get(SkMatrix::kMSkewY);
- SkScalar tx = ctm.get(SkMatrix::kMTransX);
- SkScalar ty = ctm.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;
- int shapeKeySize = shape.unstyledKeySize();
- fKey.reset(5 + shapeKeySize);
- fKey[0] = SkFloat2Bits(sx);
- fKey[1] = SkFloat2Bits(sy);
- fKey[2] = SkFloat2Bits(kx);
- fKey[3] = SkFloat2Bits(ky);
- fKey[4] = fracX | (fracY >> 8);
- shape.writeUnstyledKey(&fKey[5]);
- }
-
bool operator==(const Key& that) const {
return fKey.count() == that.fKey.count() &&
0 == memcmp(fKey.get(), that.fKey.get(), sizeof(uint32_t) * fKey.count());
@@ -97,9 +65,8 @@ private:
const uint32_t* data() const { return fKey.get(); }
private:
- // The key is composed of the GrShape's key, and either the dimensions of the DF
- // generated for the path (32x32 max, 64x64 max, 128x128 max) if an SDF image or
- // the matrix for the path with only fractional translation.
+ // The key is composed of the dimensions of the DF generated for the path (32x32 max,
+ // 64x64 max, 128x128 max) and the GrShape's key.
SkAutoSTArray<24, uint32_t> fKey;
};
Key fKey;