Batch better in GrSmallPathRenderer and add perspective support.
Minor optimization to text regen also snuck in. Bug: skia: Change-Id: I0c5d97defdcf60b9ce663548c056db0e8bf7149b Reviewed-on: https://skia-review.googlesource.com/57942 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
7f9b215695
commit
5698c8a8a0
@ -320,7 +320,7 @@ sk_sp<GrGeometryProcessor> GrDistanceFieldA8TextGeoProc::TestCreate(GrProcessorT
|
||||
class GrGLDistanceFieldPathGeoProc : public GrGLSLGeometryProcessor {
|
||||
public:
|
||||
GrGLDistanceFieldPathGeoProc()
|
||||
: fViewMatrix(SkMatrix::InvalidMatrix())
|
||||
: fMatrix(SkMatrix::InvalidMatrix())
|
||||
, fAtlasSize({0,0}) {
|
||||
}
|
||||
|
||||
@ -352,21 +352,35 @@ public:
|
||||
// setup pass through color
|
||||
varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputColor);
|
||||
|
||||
// Setup position
|
||||
this->writeOutputPosition(vertBuilder,
|
||||
uniformHandler,
|
||||
gpArgs,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
dfTexEffect.viewMatrix(),
|
||||
&fViewMatrixUniform);
|
||||
if (dfTexEffect.matrix().hasPerspective()) {
|
||||
// Setup position
|
||||
this->writeOutputPosition(vertBuilder,
|
||||
uniformHandler,
|
||||
gpArgs,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
dfTexEffect.matrix(),
|
||||
&fMatrixUniform);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(vertBuilder,
|
||||
varyingHandler,
|
||||
uniformHandler,
|
||||
gpArgs->fPositionVar,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
args.fFPCoordTransformHandler);
|
||||
// emit transforms
|
||||
this->emitTransforms(vertBuilder,
|
||||
varyingHandler,
|
||||
uniformHandler,
|
||||
gpArgs->fPositionVar,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
args.fFPCoordTransformHandler);
|
||||
} else {
|
||||
// Setup position
|
||||
this->writeOutputPosition(vertBuilder, gpArgs, dfTexEffect.inPosition()->fName);
|
||||
|
||||
// emit transforms
|
||||
this->emitTransforms(vertBuilder,
|
||||
varyingHandler,
|
||||
uniformHandler,
|
||||
gpArgs->fPositionVar,
|
||||
dfTexEffect.inPosition()->fName,
|
||||
dfTexEffect.matrix(),
|
||||
args.fFPCoordTransformHandler);
|
||||
}
|
||||
|
||||
// Use highp to work around aliasing issues
|
||||
fragBuilder->codeAppendf("float2 uv = %s;", uv.fsIn());
|
||||
@ -450,11 +464,11 @@ public:
|
||||
|
||||
const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathGeoProc>();
|
||||
|
||||
if (!dfpgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfpgp.viewMatrix())) {
|
||||
fViewMatrix = dfpgp.viewMatrix();
|
||||
float viewMatrix[3 * 3];
|
||||
GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
|
||||
pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
|
||||
if (dfpgp.matrix().hasPerspective() && !fMatrix.cheapEqualTo(dfpgp.matrix())) {
|
||||
fMatrix = dfpgp.matrix();
|
||||
float matrix[3 * 3];
|
||||
GrGLSLGetMatrix<3>(matrix, fMatrix);
|
||||
pdman.setMatrix3f(fMatrixUniform, matrix);
|
||||
}
|
||||
|
||||
SkASSERT(dfpgp.numTextureSamplers() >= 1);
|
||||
@ -466,7 +480,11 @@ public:
|
||||
pdman.set2f(fAtlasSizeInvUniform, 1.0f / atlas->width(), 1.0f / atlas->height());
|
||||
}
|
||||
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
|
||||
if (dfpgp.matrix().hasPerspective()) {
|
||||
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
|
||||
} else {
|
||||
this->setTransformDataHelper(dfpgp.matrix(), pdman, &transformIter);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void GenKey(const GrGeometryProcessor& gp,
|
||||
@ -475,14 +493,15 @@ public:
|
||||
const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast<GrDistanceFieldPathGeoProc>();
|
||||
|
||||
uint32_t key = dfTexEffect.getFlags();
|
||||
key |= ComputePosKey(dfTexEffect.viewMatrix()) << 16;
|
||||
key |= ComputePosKey(dfTexEffect.matrix()) << 16;
|
||||
b->add32(key);
|
||||
b->add32(dfTexEffect.matrix().hasPerspective());
|
||||
b->add32(dfTexEffect.numTextureSamplers());
|
||||
}
|
||||
|
||||
private:
|
||||
SkMatrix fViewMatrix;
|
||||
UniformHandle fViewMatrixUniform;
|
||||
SkMatrix fMatrix; // view matrix if perspective, local matrix otherwise
|
||||
UniformHandle fMatrixUniform;
|
||||
|
||||
SkISize fAtlasSize;
|
||||
UniformHandle fAtlasSizeInvUniform;
|
||||
@ -493,17 +512,15 @@ private:
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
GrDistanceFieldPathGeoProc::GrDistanceFieldPathGeoProc(
|
||||
GrColor color,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkMatrix& matrix,
|
||||
const sk_sp<GrTextureProxy> proxies[kMaxTextures],
|
||||
const GrSamplerState& params,
|
||||
uint32_t flags,
|
||||
bool usesLocalCoords)
|
||||
uint32_t flags)
|
||||
: INHERITED(kGrDistanceFieldPathGeoProc_ClassID)
|
||||
, fColor(color)
|
||||
, fViewMatrix(viewMatrix)
|
||||
, fMatrix(matrix)
|
||||
, fFlags(flags & kNonLCD_DistanceFieldEffectMask)
|
||||
, fInColor(nullptr)
|
||||
, fUsesLocalCoords(usesLocalCoords) {
|
||||
, fInColor(nullptr) {
|
||||
SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask));
|
||||
fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
|
||||
fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
|
||||
@ -567,8 +584,7 @@ sk_sp<GrGeometryProcessor> GrDistanceFieldPathGeoProc::TestCreate(GrProcessorTes
|
||||
GrTest::TestMatrix(d->fRandom),
|
||||
proxies,
|
||||
samplerState,
|
||||
flags,
|
||||
d->fRandom->nextBool());
|
||||
flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -129,13 +129,11 @@ class GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
|
||||
public:
|
||||
static constexpr int kMaxTextures = 4;
|
||||
|
||||
static sk_sp<GrGeometryProcessor> Make(GrColor color, const SkMatrix& viewMatrix,
|
||||
static sk_sp<GrGeometryProcessor> Make(GrColor color, const SkMatrix& matrix,
|
||||
const sk_sp<GrTextureProxy> proxies[kMaxTextures],
|
||||
const GrSamplerState& params, uint32_t flags,
|
||||
bool usesLocalCoords) {
|
||||
const GrSamplerState& params, uint32_t flags) {
|
||||
return sk_sp<GrGeometryProcessor>(
|
||||
new GrDistanceFieldPathGeoProc(color, viewMatrix, proxies,
|
||||
params, flags, usesLocalCoords));
|
||||
new GrDistanceFieldPathGeoProc(color, matrix, proxies, params, flags));
|
||||
}
|
||||
|
||||
~GrDistanceFieldPathGeoProc() override {}
|
||||
@ -146,9 +144,8 @@ public:
|
||||
const Attribute* inColor() const { return fInColor; }
|
||||
const Attribute* inTextureCoords() const { return fInTextureCoords; }
|
||||
GrColor color() const { return fColor; }
|
||||
const SkMatrix& viewMatrix() const { return fViewMatrix; }
|
||||
const SkMatrix& matrix() const { return fMatrix; }
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
bool usesLocalCoords() const { return fUsesLocalCoords; }
|
||||
|
||||
void addNewProxies(const sk_sp<GrTextureProxy> proxies[kMaxTextures], const GrSamplerState& p);
|
||||
|
||||
@ -157,18 +154,17 @@ public:
|
||||
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
|
||||
|
||||
private:
|
||||
GrDistanceFieldPathGeoProc(GrColor, const SkMatrix& viewMatrix,
|
||||
GrDistanceFieldPathGeoProc(GrColor, const SkMatrix& matrix,
|
||||
const sk_sp<GrTextureProxy> proxies[kMaxTextures],
|
||||
const GrSamplerState&, uint32_t flags, bool usesLocalCoords);
|
||||
const GrSamplerState&, uint32_t flags);
|
||||
|
||||
GrColor fColor;
|
||||
SkMatrix fViewMatrix;
|
||||
SkMatrix fMatrix; // view matrix if perspective, local matrix otherwise
|
||||
TextureSampler fTextureSamplers[kMaxTextures];
|
||||
uint32_t fFlags;
|
||||
const Attribute* fInPosition;
|
||||
const Attribute* fInColor;
|
||||
const Attribute* fInTextureCoords;
|
||||
bool fUsesLocalCoords;
|
||||
|
||||
GR_DECLARE_GEOMETRY_PROCESSOR_TEST
|
||||
|
||||
|
@ -102,16 +102,12 @@ GrPathRenderer::CanDrawPath GrSmallPathRenderer::onCanDrawPath(const CanDrawPath
|
||||
if (args.fShape->inverseFilled()) {
|
||||
return CanDrawPath::kNo;
|
||||
}
|
||||
// currently don't support perspective
|
||||
if (args.fViewMatrix->hasPerspective()) {
|
||||
return CanDrawPath::kNo;
|
||||
}
|
||||
|
||||
// Only support paths with bounds within kMaxDim by kMaxDim,
|
||||
// scaled to have bounds within kMaxSize by kMaxSize.
|
||||
// The goal is to accelerate rendering of lots of small paths that may be scaling.
|
||||
SkScalar scaleFactors[2];
|
||||
if (!args.fViewMatrix->getMinMaxScales(scaleFactors)) {
|
||||
SkScalar scaleFactors[2] = { 1, 1 };
|
||||
if (!args.fViewMatrix->hasPerspective() && !args.fViewMatrix->getMinMaxScales(scaleFactors)) {
|
||||
return CanDrawPath::kNo;
|
||||
}
|
||||
SkRect bounds = args.fShape->styledBounds();
|
||||
@ -167,21 +163,10 @@ public:
|
||||
// only use distance fields on desktop and Android framework 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);
|
||||
}
|
||||
// always use distance fields if in perspective
|
||||
fUsesDistanceField = fUsesDistanceField || viewMatrix.hasPerspective();
|
||||
|
||||
fShapes.emplace_back(Entry{color, shape, translate});
|
||||
fShapes.emplace_back(Entry{color, shape, viewMatrix});
|
||||
|
||||
fAtlas = atlas;
|
||||
fShapeCache = shapeCache;
|
||||
@ -234,7 +219,6 @@ private:
|
||||
|
||||
void onPrepareDraws(Target* target) override {
|
||||
int instanceCount = fShapes.count();
|
||||
const SkMatrix& ctm = this->viewMatrix();
|
||||
|
||||
FlushInfo flushInfo;
|
||||
flushInfo.fPipeline = fHelper.makePipeline(target);
|
||||
@ -244,25 +228,37 @@ private:
|
||||
if (!atlasPageCount) {
|
||||
return;
|
||||
}
|
||||
const SkMatrix& ctm = fShapes[0].fViewMatrix;
|
||||
if (fUsesDistanceField) {
|
||||
uint32_t flags = 0;
|
||||
// Still need to key off of ctm to pick the right shader for the transformed quad
|
||||
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->getProxies(),
|
||||
GrSamplerState::ClampBilerp(), flags, fHelper.usesLocalCoords());
|
||||
} else {
|
||||
const SkMatrix* matrix;
|
||||
SkMatrix invert;
|
||||
if (fHelper.usesLocalCoords()) {
|
||||
if (!this->viewMatrix().invert(&invert)) {
|
||||
if (ctm.hasPerspective()) {
|
||||
matrix = &ctm;
|
||||
} else if (fHelper.usesLocalCoords()) {
|
||||
if (!ctm.invert(&invert)) {
|
||||
SkDebugf("Could not invert viewmatrix\n");
|
||||
return;
|
||||
}
|
||||
matrix = &invert;
|
||||
} else {
|
||||
matrix = &SkMatrix::I();
|
||||
}
|
||||
flushInfo.fGeometryProcessor = GrDistanceFieldPathGeoProc::Make(
|
||||
this->color(), *matrix, atlas->getProxies(),
|
||||
GrSamplerState::ClampBilerp(), flags);
|
||||
} else {
|
||||
SkMatrix invert;
|
||||
if (fHelper.usesLocalCoords()) {
|
||||
if (!ctm.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(
|
||||
@ -295,8 +291,17 @@ private:
|
||||
ShapeData* shapeData;
|
||||
if (fUsesDistanceField) {
|
||||
// get mip level
|
||||
SkScalar maxScale = SkScalarAbs(this->viewMatrix().getMaxScale());
|
||||
SkScalar maxScale;
|
||||
const SkRect& bounds = args.fShape.bounds();
|
||||
if (args.fViewMatrix.hasPerspective()) {
|
||||
// approximate the scale since we can't get it from the matrix
|
||||
SkRect xformedBounds;
|
||||
args.fViewMatrix.mapRect(&xformedBounds, bounds);
|
||||
maxScale = SkTMax(xformedBounds.width() / bounds.width(),
|
||||
xformedBounds.height() / bounds.height());
|
||||
} else {
|
||||
maxScale = SkScalarAbs(args.fViewMatrix.getMaxScale());
|
||||
}
|
||||
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.
|
||||
@ -355,7 +360,7 @@ private:
|
||||
}
|
||||
} else {
|
||||
// check to see if bitmap path is cached
|
||||
ShapeData::Key key(args.fShape, this->viewMatrix());
|
||||
ShapeData::Key key(args.fShape, args.fViewMatrix);
|
||||
shapeData = fShapeCache->find(key);
|
||||
if (nullptr == shapeData || !atlas->hasID(shapeData->fID)) {
|
||||
// Remove the stale cache entry
|
||||
@ -371,7 +376,7 @@ private:
|
||||
atlas,
|
||||
shapeData,
|
||||
args.fShape,
|
||||
this->viewMatrix())) {
|
||||
args.fViewMatrix)) {
|
||||
delete shapeData;
|
||||
continue;
|
||||
}
|
||||
@ -385,7 +390,7 @@ private:
|
||||
offset,
|
||||
args.fColor,
|
||||
vertexStride,
|
||||
args.fTranslate,
|
||||
args.fViewMatrix,
|
||||
shapeData);
|
||||
offset += kVerticesPerQuad * vertexStride;
|
||||
flushInfo.fInstancesToFlush++;
|
||||
@ -622,19 +627,41 @@ private:
|
||||
intptr_t offset,
|
||||
GrColor color,
|
||||
size_t vertexStride,
|
||||
const SkVector& preTranslate,
|
||||
const SkMatrix& ctm,
|
||||
const ShapeData* shapeData) const {
|
||||
SkPoint* positions = reinterpret_cast<SkPoint*>(offset);
|
||||
|
||||
SkRect bounds = shapeData->fBounds;
|
||||
SkRect translatedBounds(bounds);
|
||||
if (!fUsesDistanceField) {
|
||||
translatedBounds.offset(SkScalarTruncToScalar(ctm.get(SkMatrix::kMTransX)),
|
||||
SkScalarTruncToScalar(ctm.get(SkMatrix::kMTransY)));
|
||||
}
|
||||
|
||||
// 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,
|
||||
vertexStride);
|
||||
if (fUsesDistanceField && !ctm.hasPerspective()) {
|
||||
SkPoint quad[4];
|
||||
ctm.mapRectToQuad(quad, translatedBounds);
|
||||
intptr_t positionOffset = offset;
|
||||
SkPoint* position = (SkPoint*)positionOffset;
|
||||
*position = quad[0];
|
||||
positionOffset += vertexStride;
|
||||
position = (SkPoint*)positionOffset;
|
||||
*position = quad[3];
|
||||
positionOffset += vertexStride;
|
||||
position = (SkPoint*)positionOffset;
|
||||
*position = quad[2];
|
||||
positionOffset += vertexStride;
|
||||
position = (SkPoint*)positionOffset;
|
||||
*position = quad[1];
|
||||
} else {
|
||||
positions->setRectFan(translatedBounds.left(),
|
||||
translatedBounds.top(),
|
||||
translatedBounds.right(),
|
||||
translatedBounds.bottom(),
|
||||
vertexStride);
|
||||
}
|
||||
|
||||
// colors
|
||||
for (int i = 0; i < kVerticesPerQuad; i++) {
|
||||
@ -696,7 +723,6 @@ private:
|
||||
}
|
||||
|
||||
GrColor color() const { return fShapes[0].fColor; }
|
||||
const SkMatrix& viewMatrix() const { return fViewMatrix; }
|
||||
bool usesDistanceField() const { return fUsesDistanceField; }
|
||||
|
||||
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
|
||||
@ -709,28 +735,39 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO We can position on the cpu for distance field paths
|
||||
if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
|
||||
const SkMatrix& thisCtm = this->fShapes[0].fViewMatrix;
|
||||
const SkMatrix& thatCtm = that->fShapes[0].fViewMatrix;
|
||||
|
||||
if (thisCtm.hasPerspective() != thatCtm.hasPerspective()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->usesDistanceField() && fHelper.usesLocalCoords() &&
|
||||
!this->fShapes[0].fTranslate.equalsWithinTolerance(that->fShapes[0].fTranslate)) {
|
||||
// We can position on the cpu unless we're in perspective,
|
||||
// but also need to make sure local matrices are identical
|
||||
if ((thisCtm.hasPerspective() || fHelper.usesLocalCoords()) &&
|
||||
!thisCtm.cheapEqualTo(thatCtm)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Depending on the ctm we may have a different shader for SDF paths
|
||||
if (this->usesDistanceField()) {
|
||||
if (thisCtm.isScaleTranslate() != thatCtm.isScaleTranslate() ||
|
||||
thisCtm.isSimilarity() != thatCtm.isSimilarity()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fShapes.push_back_n(that->fShapes.count(), that->fShapes.begin());
|
||||
this->joinBounds(*that);
|
||||
return true;
|
||||
}
|
||||
|
||||
SkMatrix fViewMatrix;
|
||||
bool fUsesDistanceField;
|
||||
|
||||
struct Entry {
|
||||
GrColor fColor;
|
||||
GrShape fShape;
|
||||
SkVector fTranslate;
|
||||
SkMatrix fViewMatrix;
|
||||
};
|
||||
|
||||
SkSTArray<1, Entry> fShapes;
|
||||
|
@ -65,6 +65,7 @@ private:
|
||||
return *this;
|
||||
}
|
||||
|
||||
// for SDF paths
|
||||
void set(const GrShape& shape, uint32_t dim) {
|
||||
// Shapes' keys are for their pre-style geometry, but by now we shouldn't have any
|
||||
// relevant styling information.
|
||||
@ -76,13 +77,8 @@ private:
|
||||
shape.writeUnstyledKey(&fKey[1]);
|
||||
}
|
||||
|
||||
// for bitmap paths
|
||||
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());
|
||||
|
@ -166,6 +166,8 @@ void GrAtlasTextBlob::regenInOp(GrDrawOp::Target* target, GrAtlasGlyphCache* fon
|
||||
}
|
||||
|
||||
bool brokenRun = false;
|
||||
intptr_t vertex = reinterpret_cast<intptr_t>(fVertices);
|
||||
vertex += info->vertexStartIndex();
|
||||
for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
|
||||
GrGlyph* glyph = nullptr;
|
||||
if (regenTexCoords) {
|
||||
@ -196,12 +198,10 @@ void GrAtlasTextBlob::regenInOp(GrDrawOp::Target* target, GrAtlasGlyphCache* fon
|
||||
target->nextDrawToken());
|
||||
}
|
||||
|
||||
intptr_t vertex = reinterpret_cast<intptr_t>(fVertices);
|
||||
vertex += info->vertexStartIndex();
|
||||
vertex += vertexStride * glyphIdx * GrAtlasTextOp::kVerticesPerGlyph;
|
||||
regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertexStride,
|
||||
info->drawAsDistanceFields(), transX,
|
||||
transY, color);
|
||||
vertex += vertexStride * GrAtlasTextOp::kVerticesPerGlyph;
|
||||
helper->incGlyphCount();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user