Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: src/gpu/GrStencilAndCoverTextContext.cpp

Issue 1374853004: Fix caching of nvpr glyphs (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: MSVC warnings Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | src/gpu/batches/GrDrawPathBatch.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrStencilAndCoverTextContext.cpp
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
index 0dc902928b0568abec3d296b4ba5d5c5f3c13860..ee1f1af4107ac17597732daeb5364d77581f8099 100644
--- a/src/gpu/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -81,8 +81,8 @@ void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget*
const SkIRect& clipBounds) {
TextRun run(skPaint);
GrPipelineBuilder pipelineBuilder(paint, rt, clip);
- run.setText(text, byteLength, x, y, fContext, &fSurfaceProps);
- run.draw(dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBounds,
+ run.setText(text, byteLength, x, y);
+ run.draw(fContext, dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBounds,
fFallbackTextContext, skPaint);
}
@@ -99,8 +99,8 @@ void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarg
const SkIRect& clipBounds) {
TextRun run(skPaint);
GrPipelineBuilder pipelineBuilder(paint, rt, clip);
- run.setPosText(text, byteLength, pos, scalarsPerPosition, offset, fContext, &fSurfaceProps);
- run.draw(dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBounds,
+ run.setPosText(text, byteLength, pos, scalarsPerPosition, offset);
+ run.draw(fContext, dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBounds,
fFallbackTextContext, skPaint);
}
@@ -137,8 +137,9 @@ void GrStencilAndCoverTextContext::drawTextBlob(GrDrawContext* dc, GrRenderTarge
TextBlob::Iter iter(blob);
for (TextRun* run = iter.get(); run; run = iter.next()) {
- run->draw(dc, &pipelineBuilder, paint.getColor(), viewMatrix, x, y, clipBounds,
+ run->draw(fContext, dc, &pipelineBuilder, paint.getColor(), viewMatrix, x, y, clipBounds,
fFallbackTextContext, skPaint);
+ run->releaseGlyphCache();
}
}
@@ -153,8 +154,7 @@ GrStencilAndCoverTextContext::findOrCreateTextBlob(const SkTextBlob* skBlob,
fLRUList.addToTail(*found);
return **found;
}
- TextBlob* blob = new TextBlob(skBlob->uniqueID(), skBlob, skPaint, fContext,
- &fSurfaceProps);
+ TextBlob* blob = new TextBlob(skBlob->uniqueID(), skBlob, skPaint);
this->purgeToFit(*blob);
fBlobIdCache.set(skBlob->uniqueID(), blob);
fLRUList.addToTail(blob);
@@ -171,7 +171,7 @@ GrStencilAndCoverTextContext::findOrCreateTextBlob(const SkTextBlob* skBlob,
fLRUList.addToTail(*found);
return **found;
}
- TextBlob* blob = new TextBlob(key, skBlob, skPaint, fContext, &fSurfaceProps);
+ TextBlob* blob = new TextBlob(key, skBlob, skPaint);
this->purgeToFit(*blob);
fBlobKeyCache.set(blob);
fLRUList.addToTail(blob);
@@ -181,9 +181,9 @@ GrStencilAndCoverTextContext::findOrCreateTextBlob(const SkTextBlob* skBlob,
}
void GrStencilAndCoverTextContext::purgeToFit(const TextBlob& blob) {
- static const int maxCacheSize = 4 * 1024 * 1024; // Allow up to 4 MB for caching text blobs.
+ static const size_t maxCacheSize = 4 * 1024 * 1024; // Allow up to 4 MB for caching text blobs.
- int maxSizeForNewBlob = maxCacheSize - blob.cpuMemorySize();
+ size_t maxSizeForNewBlob = maxCacheSize - blob.cpuMemorySize();
while (fCacheSize && fCacheSize > maxSizeForNewBlob) {
TextBlob* lru = fLRUList.head();
if (1 == lru->key().count()) {
@@ -200,8 +200,8 @@ void GrStencilAndCoverTextContext::purgeToFit(const TextBlob& blob) {
////////////////////////////////////////////////////////////////////////////////////////////////////
-void GrStencilAndCoverTextContext::TextBlob::init(const SkTextBlob* skBlob, const SkPaint& skPaint,
- GrContext* ctx, const SkSurfaceProps* props) {
+void GrStencilAndCoverTextContext::TextBlob::init(const SkTextBlob* skBlob,
+ const SkPaint& skPaint) {
fCpuMemorySize = sizeof(TextBlob);
SkPaint runPaint(skPaint);
for (SkTextBlob::RunIterator iter(skBlob); !iter.done(); iter.next()) {
@@ -214,18 +214,17 @@ void GrStencilAndCoverTextContext::TextBlob::init(const SkTextBlob* skBlob, cons
switch (iter.positioning()) {
case SkTextBlob::kDefault_Positioning:
- run->setText(text, byteLength, runOffset.fX, runOffset.fY, ctx, props);
+ run->setText(text, byteLength, runOffset.fX, runOffset.fY);
break;
case SkTextBlob::kHorizontal_Positioning:
- run->setPosText(text, byteLength, iter.pos(), 1, SkPoint::Make(0, runOffset.fY),
- ctx, props);
+ run->setPosText(text, byteLength, iter.pos(), 1, SkPoint::Make(0, runOffset.fY));
break;
case SkTextBlob::kFull_Positioning:
- run->setPosText(text, byteLength, iter.pos(), 2, SkPoint::Make(0, 0), ctx, props);
+ run->setPosText(text, byteLength, iter.pos(), 2, SkPoint::Make(0, 0));
break;
}
- fCpuMemorySize += run->cpuMemorySize();
+ fCpuMemorySize += run->computeSizeInCache();
}
}
@@ -260,7 +259,9 @@ private:
GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
: fStroke(fontAndStroke),
fFont(fontAndStroke),
- fTotalGlyphCount(0) {
+ fTotalGlyphCount(0),
+ fDetachedGlyphCache(nullptr),
+ fLastDrawnGlyphsID(SK_InvalidUniqueID) {
SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
// Setting to "fill" ensures that no strokes get baked into font outlines. (We use the GPU path
@@ -307,28 +308,55 @@ GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
fUsingRawGlyphPaths = false;
}
+ // Generate the key that will be used to cache the GPU glyph path objects.
+ if (fUsingRawGlyphPaths && fStroke.isFillStyle()) {
+ static const GrUniqueKey::Domain kRawFillPathGlyphDomain = GrUniqueKey::GenerateDomain();
+
+ const SkTypeface* typeface = fFont.getTypeface();
+ GrUniqueKey::Builder builder(&fGlyphPathsKey, kRawFillPathGlyphDomain, 1);
+ reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqueID() : 0;
+ } else {
+ static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::GenerateDomain();
+
+ int strokeDataCount = fStroke.computeUniqueKeyFragmentData32Cnt();
+ if (fUsingRawGlyphPaths) {
+ const SkTypeface* typeface = fFont.getTypeface();
+ GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain, 2 + strokeDataCount);
+ reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqueID() : 0;
+ reinterpret_cast<uint32_t&>(builder[1]) = strokeDataCount;
+ fStroke.asUniqueKeyFragment(&builder[2]);
+ } else {
+ SkGlyphCache* glyphCache = this->getGlyphCache();
+ const SkTypeface* typeface = glyphCache->getScalerContext()->getTypeface();
+ const SkDescriptor* desc = &glyphCache->getDescriptor();
+ int descDataCount = (desc->getLength() + 3) / 4;
+ GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain,
+ 2 + strokeDataCount + descDataCount);
+ reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqueID() : 0;
+ reinterpret_cast<uint32_t&>(builder[1]) = strokeDataCount | (descDataCount << 16);
+ fStroke.asUniqueKeyFragment(&builder[2]);
+ memcpy(&builder[2 + strokeDataCount], desc, desc->getLength());
+ }
+ }
+
// When drawing from canonically sized paths, the actual local coords are fTextRatio * coords.
fLocalMatrixTemplate.setScale(fTextRatio, fTextRatio);
}
GrStencilAndCoverTextContext::TextRun::~TextRun() {
+ this->releaseGlyphCache();
}
void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t byteLength,
- SkScalar x, SkScalar y, GrContext* ctx,
- const SkSurfaceProps* surfaceProps) {
+ SkScalar x, SkScalar y) {
SkASSERT(byteLength == 0 || text != nullptr);
- SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr);
- SkGlyphCache* glyphCache = autoGlyphCache.getCache();
-
- fTotalGlyphCount = fFont.countText(text, byteLength);
- fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache),
- GrPathRendering::kTranslate_PathTransformType,
- fTotalGlyphCount));
-
+ SkGlyphCache* glyphCache = this->getGlyphCache();
SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
+ fDraw.reset(GrPathRangeDraw::Create(GrPathRendering::kTranslate_PathTransformType,
+ fTotalGlyphCount = fFont.countText(text, byteLength)));
+
const char* stop = text + byteLength;
// Measure first if needed.
@@ -378,28 +406,21 @@ void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by
fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio);
}
- fDraw->loadGlyphPathsIfNeeded();
-
fFallbackTextBlob.reset(fallback.buildIfInitialized());
}
void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset, GrContext* ctx,
- const SkSurfaceProps* surfaceProps) {
+ const SkPoint& offset) {
SkASSERT(byteLength == 0 || text != nullptr);
SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
- SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr);
- SkGlyphCache* glyphCache = autoGlyphCache.getCache();
-
- fTotalGlyphCount = fFont.countText(text, byteLength);
- fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache),
- GrPathRendering::kTranslate_PathTransformType,
- fTotalGlyphCount));
-
+ SkGlyphCache* glyphCache = this->getGlyphCache();
SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
+ fDraw.reset(GrPathRangeDraw::Create(GrPathRendering::kTranslate_PathTransformType,
+ fTotalGlyphCount = fFont.countText(text, byteLength)));
+
const char* stop = text + byteLength;
SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
@@ -418,39 +439,24 @@ void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t
pos += scalarsPerPosition;
}
- fDraw->loadGlyphPathsIfNeeded();
-
fFallbackTextBlob.reset(fallback.buildIfInitialized());
}
-GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx,
- SkGlyphCache* glyphCache) {
- SkTypeface* typeface = fUsingRawGlyphPaths ? fFont.getTypeface()
- : glyphCache->getScalerContext()->getTypeface();
- const SkDescriptor* desc = fUsingRawGlyphPaths ? nullptr : &glyphCache->getDescriptor();
-
- static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::GenerateDomain();
- int strokeDataCount = fStroke.computeUniqueKeyFragmentData32Cnt();
- GrUniqueKey glyphKey;
- GrUniqueKey::Builder builder(&glyphKey, kPathGlyphDomain, 2 + strokeDataCount);
- reinterpret_cast<uint32_t&>(builder[0]) = desc ? desc->getChecksum() : 0;
- reinterpret_cast<uint32_t&>(builder[1]) = typeface ? typeface->uniqueID() : 0;
- if (strokeDataCount > 0) {
- fStroke.asUniqueKeyFragment(&builder[2]);
- }
- builder.finish();
-
- SkAutoTUnref<GrPathRange> glyphs(
- static_cast<GrPathRange*>(
- ctx->resourceProvider()->findAndRefResourceByUniqueKey(glyphKey)));
+GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx) const {
+ GrPathRange* glyphs = static_cast<GrPathRange*>(
+ ctx->resourceProvider()->findAndRefResourceByUniqueKey(fGlyphPathsKey));
if (nullptr == glyphs) {
- glyphs.reset(ctx->resourceProvider()->createGlyphs(typeface, desc, fStroke));
- ctx->resourceProvider()->assignUniqueKeyToResource(glyphKey, glyphs);
- } else {
- SkASSERT(nullptr == desc || glyphs->isEqualTo(*desc));
+ if (fUsingRawGlyphPaths) {
+ glyphs = ctx->resourceProvider()->createGlyphs(fFont.getTypeface(), nullptr, fStroke);
+ } else {
+ SkGlyphCache* cache = this->getGlyphCache();
+ glyphs = ctx->resourceProvider()->createGlyphs(cache->getScalerContext()->getTypeface(),
+ &cache->getDescriptor(),
+ fStroke);
+ }
+ ctx->resourceProvider()->assignUniqueKeyToResource(fGlyphPathsKey, glyphs);
}
-
- return glyphs.detach();
+ return glyphs;
}
inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& glyph,
@@ -468,7 +474,8 @@ inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl
}
}
-void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc,
+void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
+ GrDrawContext* dc,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& viewMatrix,
@@ -493,6 +500,13 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc,
*pipelineBuilder->stencil() = kStencilPass;
+ SkAutoTUnref<GrPathRange> glyphs(this->createGlyphs(ctx));
+ if (fLastDrawnGlyphsID != glyphs->getUniqueID()) {
+ // Either this is the first draw or the glyphs object was purged since last draw.
+ glyphs->loadPathsIfNeeded(fDraw->indices(), fDraw->count());
+ fLastDrawnGlyphsID = glyphs->getUniqueID();
+ }
+
SkMatrix drawMatrix(viewMatrix);
drawMatrix.preTranslate(x, y);
drawMatrix.preScale(fTextRatio, fTextRatio);
@@ -501,7 +515,7 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc,
localMatrix.setTranslateX(x);
localMatrix.setTranslateY(y);
- dc->drawPathsFromRange(pipelineBuilder, drawMatrix, localMatrix, color, fDraw,
+ dc->drawPathsFromRange(pipelineBuilder, drawMatrix, localMatrix, color, glyphs, fDraw,
GrPathRendering::kWinding_FillType);
}
@@ -518,8 +532,25 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc,
}
}
-int GrStencilAndCoverTextContext::TextRun::cpuMemorySize() const {
- int size = sizeof(TextRun) + fTotalGlyphCount * (sizeof(uint16_t) + 2 * sizeof(float));
+SkGlyphCache* GrStencilAndCoverTextContext::TextRun::getGlyphCache() const {
+ if (!fDetachedGlyphCache) {
+ fDetachedGlyphCache = fFont.detachCache(nullptr, nullptr, true /*ignoreGamma*/);
+ }
+ return fDetachedGlyphCache;
+}
+
+
+void GrStencilAndCoverTextContext::TextRun::releaseGlyphCache() const {
+ if (fDetachedGlyphCache) {
+ SkGlyphCache::AttachCache(fDetachedGlyphCache);
+ fDetachedGlyphCache = nullptr;
+ }
+}
+
+size_t GrStencilAndCoverTextContext::TextRun::computeSizeInCache() const {
+ size_t size = sizeof(TextRun) +
+ fGlyphPathsKey.size() +
+ fTotalGlyphCount * (sizeof(uint16_t) + 2 * sizeof(float));
if (fDraw) {
size += sizeof(GrPathRangeDraw);
}
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | src/gpu/batches/GrDrawPathBatch.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698