Start objectifying GrAtlasTextBlob

BUG=skia:

Review URL: https://codereview.chromium.org/1503193002
This commit is contained in:
joshualitt 2015-12-07 11:32:50 -08:00 committed by Commit bot
parent 573ce20f42
commit 3660d53451
4 changed files with 90 additions and 56 deletions

View File

@ -77,7 +77,6 @@ struct GrAtlasTextBlob : public SkRefCnt {
, fVertexEndIndex(0)
, fGlyphStartIndex(0)
, fGlyphEndIndex(0)
, fTextRatio(1.0f)
, fMaskFormat(kA8_GrMaskFormat)
, fDrawAsDistanceFields(false)
, fUseLCDText(false) {}
@ -89,18 +88,44 @@ struct GrAtlasTextBlob : public SkRefCnt {
, fVertexEndIndex(that.fVertexEndIndex)
, fGlyphStartIndex(that.fGlyphStartIndex)
, fGlyphEndIndex(that.fGlyphEndIndex)
, fTextRatio(that.fTextRatio)
, fMaskFormat(that.fMaskFormat)
, fDrawAsDistanceFields(that.fDrawAsDistanceFields)
, fUseLCDText(that.fUseLCDText) {
}
// Distance field text cannot draw coloremoji, and so has to fall back. However,
// though the distance field text and the coloremoji may share the same run, they
// will have different descriptors. If fOverrideDescriptor is non-nullptr, then it
// will be used in place of the run's descriptor to regen texture coords
// TODO we could have a descriptor cache, it would reduce the size of these blobs
// significantly, and then the subrun could just have a refed pointer to the
// correct descriptor.
void resetBulkUseToken() { fBulkUseToken.reset(); }
GrBatchAtlas::BulkUseTokenUpdater* bulkUseToken() { return &fBulkUseToken; }
void setStrike(GrBatchTextStrike* strike) { fStrike.reset(SkRef(strike)); }
GrBatchTextStrike* strike() const { return fStrike.get(); }
void setAtlasGeneration(uint64_t atlasGeneration) { fAtlasGeneration = atlasGeneration;}
uint64_t atlasGeneration() const { return fAtlasGeneration; }
size_t byteCount() const { return fVertexEndIndex - fVertexStartIndex; }
void setVertexStartIndex(size_t vertStartIndex) { fVertexStartIndex = vertStartIndex;}
size_t vertexStartIndex() const { return fVertexStartIndex; }
void setVertexEndIndex(size_t vertEndIndex) { fVertexEndIndex = vertEndIndex; }
size_t vertexEndIndex() const { return fVertexEndIndex; }
void appendVertices(size_t vertexStride) {
fVertexEndIndex += vertexStride * kVerticesPerGlyph;
}
uint32_t glyphCount() const { return fGlyphEndIndex - fGlyphStartIndex; }
void setGlyphStartIndex(uint32_t glyphStartIndex) { fGlyphStartIndex = glyphStartIndex;}
uint32_t glyphStartIndex() const { return fGlyphStartIndex; }
void setGlyphEndIndex(uint32_t glyphEndIndex) { fGlyphEndIndex = glyphEndIndex; }
uint32_t glyphEndIndex() const { return fGlyphEndIndex; }
void glyphAppended() { fGlyphEndIndex++; }
void setMaskFormat(GrMaskFormat format) { fMaskFormat = format; }
GrMaskFormat maskFormat() const { return fMaskFormat; }
// df properties
void setUseLCDText(bool useLCDText) { fUseLCDText = useLCDText; }
bool hasUseLCDText() const { return fUseLCDText; }
void setDrawAsDistanceFields() { fDrawAsDistanceFields = true; }
bool drawAsDistanceFields() const { return fDrawAsDistanceFields; }
private:
GrBatchAtlas::BulkUseTokenUpdater fBulkUseToken;
SkAutoTUnref<GrBatchTextStrike> fStrike;
uint64_t fAtlasGeneration;
@ -108,7 +133,6 @@ struct GrAtlasTextBlob : public SkRefCnt {
size_t fVertexEndIndex;
uint32_t fGlyphStartIndex;
uint32_t fGlyphEndIndex;
SkScalar fTextRatio; // df property
GrMaskFormat fMaskFormat;
bool fDrawAsDistanceFields; // df property
bool fUseLCDText; // df property
@ -119,11 +143,11 @@ struct GrAtlasTextBlob : public SkRefCnt {
SubRunInfo& newSubRun = fSubRunInfo.push_back();
SubRunInfo& prevSubRun = fSubRunInfo.fromBack(1);
newSubRun.fGlyphStartIndex = prevSubRun.fGlyphEndIndex;
newSubRun.fGlyphEndIndex = prevSubRun.fGlyphEndIndex;
newSubRun.setGlyphStartIndex(prevSubRun.glyphEndIndex());
newSubRun.setGlyphEndIndex(prevSubRun.glyphEndIndex());
newSubRun.fVertexStartIndex = prevSubRun.fVertexEndIndex;
newSubRun.fVertexEndIndex = prevSubRun.fVertexEndIndex;
newSubRun.setVertexStartIndex(prevSubRun.vertexEndIndex());
newSubRun.setVertexEndIndex(prevSubRun.vertexEndIndex());
return newSubRun;
}
static const int kMinSubRuns = 1;
@ -131,6 +155,11 @@ struct GrAtlasTextBlob : public SkRefCnt {
SkRect fVertexBounds;
SkSTArray<kMinSubRuns, SubRunInfo> fSubRunInfo;
SkAutoDescriptor fDescriptor;
// Distance field text cannot draw coloremoji, and so has to fall back. However,
// though the distance field text and the coloremoji may share the same run, they
// will have different descriptors. If fOverrideDescriptor is non-nullptr, then it
// will be used in place of the run's descriptor to regen texture coords
SkAutoTDelete<SkAutoDescriptor> fOverrideDescriptor; // df properties
GrColor fColor;
bool fInitialized;
@ -240,6 +269,12 @@ struct GrAtlasTextBlob : public SkRefCnt {
bool hasBitmap() const { return SkToBool(fTextType & kHasBitmap_TextType); }
void setHasDistanceField() { fTextType |= kHasDistanceField_TextType; }
void setHasBitmap() { fTextType |= kHasBitmap_TextType; }
void appendGlyph(Run::SubRunInfo* subrun, GrGlyph* glyph) {
this->fGlyphs[subrun->glyphEndIndex()] = glyph;
subrun->glyphAppended();
}
static const int kVerticesPerGlyph = 4;
#ifdef CACHE_SANITY_CHECK
static void AssertEqual(const GrAtlasTextBlob&, const GrAtlasTextBlob&);

View File

@ -466,11 +466,11 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back();
PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back();
newRun.fVertexStartIndex = lastRun.fVertexEndIndex;
newRun.fVertexEndIndex = lastRun.fVertexEndIndex;
newRun.setVertexStartIndex(lastRun.vertexEndIndex());
newRun.setVertexEndIndex(lastRun.vertexEndIndex());
newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex;
newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex;
newRun.setGlyphStartIndex(lastRun.glyphEndIndex());
newRun.setGlyphEndIndex(lastRun.glyphEndIndex());
}
if (this->canDrawAsDistanceFields(runPaint, viewMatrix)) {
@ -480,8 +480,8 @@ void GrAtlasTextContext::regenerateTextBlob(GrAtlasTextBlob* cacheBlob,
this->initDistanceFieldPaint(cacheBlob, &dfPaint, &textRatio, viewMatrix);
Run& runIdx = cacheBlob->fRuns[run];
PerSubRunInfo& subRun = runIdx.fSubRunInfo.back();
subRun.fUseLCDText = runPaint.isLCDRenderText();
subRun.fDrawAsDistanceFields = true;
subRun.setUseLCDText(runPaint.isLCDRenderText());
subRun.setDrawAsDistanceFields();
SkTDArray<char> fallbackTxt;
SkTDArray<SkScalar> fallbackPos;
@ -641,8 +641,8 @@ GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint,
blob->fViewMatrix = viewMatrix;
Run& run = blob->fRuns[0];
PerSubRunInfo& subRun = run.fSubRunInfo.back();
subRun.fUseLCDText = origPaint.isLCDRenderText();
subRun.fDrawAsDistanceFields = true;
subRun.setUseLCDText(origPaint.isLCDRenderText());
subRun.setDrawAsDistanceFields();
return blob;
}
@ -1007,11 +1007,11 @@ void GrAtlasTextContext::bmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
GrMaskFormat format = glyph->fMaskFormat;
PerSubRunInfo* subRun = &run.fSubRunInfo.back();
if (run.fInitialized && subRun->fMaskFormat != format) {
if (run.fInitialized && subRun->maskFormat() != format) {
subRun = &run.push_back();
subRun->fStrike.reset(SkRef(fCurrStrike));
subRun->setStrike(fCurrStrike);
} else if (!run.fInitialized) {
subRun->fStrike.reset(SkRef(fCurrStrike));
subRun->setStrike(SkRef(fCurrStrike));
}
run.fInitialized = true;
@ -1023,7 +1023,7 @@ void GrAtlasTextContext::bmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
r.fTop = SkIntToScalar(y);
r.fRight = r.fLeft + SkIntToScalar(width);
r.fBottom = r.fTop + SkIntToScalar(height);
subRun->fMaskFormat = format;
subRun->setMaskFormat(format);
this->appendGlyphCommon(blob, &run, subRun, r, color, vertexStride, kA8_GrMaskFormat == format,
glyph);
}
@ -1075,16 +1075,16 @@ bool GrAtlasTextContext::dfAppendGlyph(GrAtlasTextBlob* blob, int runIndex,
PerSubRunInfo* subRun = &run.fSubRunInfo.back();
if (!run.fInitialized) {
subRun->fStrike.reset(SkRef(fCurrStrike));
subRun->setStrike(fCurrStrike);
}
run.fInitialized = true;
SkASSERT(glyph->fMaskFormat == kA8_GrMaskFormat);
subRun->fMaskFormat = kA8_GrMaskFormat;
subRun->setMaskFormat(kA8_GrMaskFormat);
size_t vertexStride = GrAtlasTextBatch::GetVertexStrideDf(kA8_GrMaskFormat,
subRun->fUseLCDText);
subRun->hasUseLCDText());
bool useColorVerts = !subRun->fUseLCDText;
bool useColorVerts = !subRun->hasUseLCDText();
this->appendGlyphCommon(blob, &run, subRun, glyphRect, color, vertexStride, useColorVerts,
glyph);
return true;
@ -1110,11 +1110,11 @@ inline void GrAtlasTextContext::appendGlyphCommon(GrAtlasTextBlob* blob, Run* ru
const SkRect& positions, GrColor color,
size_t vertexStride, bool useVertexColor,
GrGlyph* glyph) {
blob->fGlyphs[subRun->fGlyphEndIndex] = glyph;
blob->appendGlyph(subRun, glyph);
run->fVertexBounds.joinNonEmptyArg(positions);
run->fColor = color;
intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->fVertexEndIndex);
intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->vertexEndIndex());
if (useVertexColor) {
// V0
@ -1163,9 +1163,7 @@ inline void GrAtlasTextContext::appendGlyphCommon(GrAtlasTextBlob* blob, Run* ru
position = reinterpret_cast<SkPoint*>(vertex);
position->set(positions.fRight, positions.fTop);
}
subRun->fGlyphEndIndex++;
subRun->fVertexEndIndex += vertexStride * GrAtlasTextBatch::kVerticesPerGlyph;
subRun->appendVertices(vertexStride);
}
void GrAtlasTextContext::flushRunAsPaths(GrDrawContext* dc,
@ -1211,7 +1209,7 @@ GrAtlasTextContext::createBatch(GrAtlasTextBlob* cacheBlob, const PerSubRunInfo&
int glyphCount, int run, int subRun,
GrColor color, SkScalar transX, SkScalar transY,
const SkPaint& skPaint) {
GrMaskFormat format = info.fMaskFormat;
GrMaskFormat format = info.maskFormat();
GrColor subRunColor;
if (kARGB_GrMaskFormat == format) {
uint8_t paintAlpha = skPaint.getAlpha();
@ -1221,7 +1219,7 @@ GrAtlasTextContext::createBatch(GrAtlasTextBlob* cacheBlob, const PerSubRunInfo&
}
GrAtlasTextBatch* batch;
if (info.fDrawAsDistanceFields) {
if (info.drawAsDistanceFields()) {
SkColor filteredColor;
SkColorFilter* colorFilter = skPaint.getColorFilter();
if (colorFilter) {
@ -1232,7 +1230,7 @@ GrAtlasTextContext::createBatch(GrAtlasTextBlob* cacheBlob, const PerSubRunInfo&
bool useBGR = SkPixelGeometryIsBGR(fSurfaceProps.pixelGeometry());
batch = GrAtlasTextBatch::CreateDistanceField(glyphCount, fContext->getBatchFontCache(),
fDistanceAdjustTable, filteredColor,
info.fUseLCDText, useBGR);
info.hasUseLCDText(), useBGR);
} else {
batch = GrAtlasTextBatch::CreateBitmap(format, glyphCount, fContext->getBatchFontCache());
}
@ -1254,7 +1252,7 @@ inline void GrAtlasTextContext::flushRun(GrDrawContext* dc, GrPipelineBuilder* p
const SkPaint& skPaint) {
for (int subRun = 0; subRun < cacheBlob->fRuns[run].fSubRunInfo.count(); subRun++) {
const PerSubRunInfo& info = cacheBlob->fRuns[run].fSubRunInfo[subRun];
int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
int glyphCount = info.glyphCount();
if (0 == glyphCount) {
continue;
}

View File

@ -135,7 +135,7 @@ inline void GrAtlasTextBatch::regenBlob(Target* target, FlushInfo* flushInfo, Bl
static_assert(!regenGlyphs || regenTexCoords, "must regenTexCoords along regenGlyphs");
GrBatchTextStrike* strike = nullptr;
if (regenTexCoords) {
info->fBulkUseToken.reset();
info->resetBulkUseToken();
// We can reuse if we have a valid strike and our descriptors / typeface are the
// same. The override descriptor is only for the non distance field text within
@ -151,14 +151,14 @@ inline void GrAtlasTextBatch::regenBlob(Target* target, FlushInfo* flushInfo, Bl
*desc = newDesc;
*cache = SkGlyphCache::DetachCache(run->fTypeface, *desc);
*scaler = GrTextContext::GetGrFontScaler(*cache);
strike = info->fStrike;
strike = info->strike();
*typeface = run->fTypeface;
}
if (regenGlyphs) {
strike = fFontCache->getStrike(*scaler);
} else {
strike = info->fStrike;
strike = info->strike();
}
}
@ -166,7 +166,7 @@ inline void GrAtlasTextBatch::regenBlob(Target* target, FlushInfo* flushInfo, Bl
for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
GrGlyph* glyph = nullptr;
if (regenTexCoords) {
size_t glyphOffset = glyphIdx + info->fGlyphStartIndex;
size_t glyphOffset = glyphIdx + info->glyphStartIndex();
if (regenGlyphs) {
// Get the id from the old glyph, and use the new strike to lookup
@ -190,12 +190,12 @@ inline void GrAtlasTextBatch::regenBlob(Target* target, FlushInfo* flushInfo, Bl
this->maskFormat());
SkASSERT(success);
}
fFontCache->addGlyphToBulkAndSetUseToken(&info->fBulkUseToken, glyph,
fFontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph,
target->currentToken());
}
intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices);
vertex += info->fVertexStartIndex;
vertex += info->vertexStartIndex();
vertex += vertexStride * glyphIdx * GrAtlasTextBatch::kVerticesPerGlyph;
regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertexStride,
this->usesDistanceFields(), transX,
@ -207,10 +207,10 @@ inline void GrAtlasTextBatch::regenBlob(Target* target, FlushInfo* flushInfo, Bl
run->fColor = color;
if (regenTexCoords) {
if (regenGlyphs) {
info->fStrike.reset(SkRef(strike));
info->setStrike(strike);
}
info->fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAtlasGeneration :
fFontCache->atlasGeneration(this->maskFormat());
info->setAtlasGeneration(brokenRun ? GrBatchAtlas::kInvalidAtlasGeneration :
fFontCache->atlasGeneration(this->maskFormat()));
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -378,8 +378,8 @@ void GrAtlasTextBatch::onPrepareDraws(Target* target) const {
// new strike, we instead keep our ref to the old strike and use the packed ids from
// it. These ids will still be valid as long as we hold the ref. When we are done
// updating our cache of the GrGlyph*s, we drop our ref on the old strike
bool regenerateGlyphs = info.fStrike->isAbandoned();
bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen ||
bool regenerateGlyphs = info.strike()->isAbandoned();
bool regenerateTextureCoords = info.atlasGeneration() != currentAtlasGen ||
regenerateGlyphs;
bool regenerateColors;
if (usesDistanceFields) {
@ -388,7 +388,7 @@ void GrAtlasTextBatch::onPrepareDraws(Target* target) const {
regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != args.fColor;
}
bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f;
int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
int glyphCount = info.glyphCount();
uint32_t regenMaskBits = kNoRegen;
regenMaskBits |= regeneratePositions ? kRegenPos : 0;
@ -416,13 +416,14 @@ void GrAtlasTextBatch::onPrepareDraws(Target* target) const {
// set use tokens for all of the glyphs in our subrun. This is only valid if we
// have a valid atlas generation
fFontCache->setUseTokenBulk(info.fBulkUseToken, target->currentToken(), maskFormat);
fFontCache->setUseTokenBulk(*info.bulkUseToken(), target->currentToken(),
maskFormat);
break;
}
// now copy all vertices
size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex;
memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCount);
size_t byteCount = info.byteCount();
memcpy(currVertex, blob->fVertices + info.vertexStartIndex(), byteCount);
currVertex += byteCount;
}

View File

@ -20,7 +20,7 @@ public:
// position + local coord
static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16);
static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + sizeof(SkIPoint16);
static const int kVerticesPerGlyph = 4;
static const int kVerticesPerGlyph = GrAtlasTextBlob::kVerticesPerGlyph;
static const int kIndicesPerGlyph = 6;
typedef GrAtlasTextContext::DistanceAdjustTable DistanceAdjustTable;
@ -89,7 +89,7 @@ public:
// We don't yet position distance field text on the cpu, so we have to map the vertex bounds
// into device space
const Run& run = geo.fBlob->fRuns[geo.fRun];
if (run.fSubRunInfo[geo.fSubRun].fDrawAsDistanceFields) {
if (run.fSubRunInfo[geo.fSubRun].drawAsDistanceFields()) {
SkRect bounds = run.fVertexBounds;
fBatch.fViewMatrix.mapRect(&bounds);
this->setBounds(bounds);