Index: src/gpu/GrAtlasTextContext.cpp |
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp |
index d77bc47a872bb082f9e6dd1e9e4ba361ee664f75..db6b795ac7be5cb7da1aa248b09ebe69b7304dec 100644 |
--- a/src/gpu/GrAtlasTextContext.cpp |
+++ b/src/gpu/GrAtlasTextContext.cpp |
@@ -60,10 +60,10 @@ static size_t get_vertex_stride(GrMaskFormat maskFormat) { |
}; |
// TODO |
-// More tests |
-// move to SkCache |
-// handle textblobs where the whole run is larger than the cache size |
-// TODO implement micro speedy hash map for fast refing of glyphs |
+// Gamma slotting to preserve color |
+// Better reuse on regeneration |
+// Telemetry tests |
+// possibly consider having a regeneration ratio on the textblob itself for animated textblobs |
GrAtlasTextContext::GrAtlasTextContext(GrContext* context, |
SkGpuDevice* gpuDevice, |
@@ -93,6 +93,7 @@ bool GrAtlasTextContext::canDraw(const GrRenderTarget*, |
bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTransY, |
const BitmapTextBlob& blob, const SkPaint& paint, |
+ const SkMaskFilter::BlurRec& blurRec, |
const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { |
// Color can affect the mask |
// TODO we can adjust the color within specific gamma slots |
@@ -115,6 +116,22 @@ bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTr |
return true; |
} |
+ // We only cache one masked version |
+ if (blob.fKey.fHasBlur && |
+ (blob.fBlurRec.fSigma != blurRec.fSigma || |
+ blob.fBlurRec.fStyle != blurRec.fStyle || |
+ blob.fBlurRec.fQuality != blurRec.fQuality)) { |
+ return true; |
+ } |
+ |
+ // Similarly, we only cache one version for each style |
+ if (blob.fKey.fStyle != SkPaint::kFill_Style && |
+ (blob.fStrokeInfo.fFrameWidth != paint.getStrokeWidth() || |
+ blob.fStrokeInfo.fMiterLimit != paint.getStrokeMiter() || |
+ blob.fStrokeInfo.fJoin != paint.getStrokeJoin())) { |
+ return true; |
+ } |
+ |
// We can update the positions in the cachedtextblobs without regenerating the whole blob, but |
// only for integer translations. |
// This cool bit of math will determine the necessary translation to apply to the already |
@@ -162,17 +179,22 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, |
const SkPaint& skPaint, const SkMatrix& viewMatrix, |
const SkTextBlob* blob, SkScalar x, SkScalar y, |
SkDrawFilter* drawFilter, const SkIRect& clipBounds) { |
- uint32_t uniqueID = blob->uniqueID(); |
SkAutoTUnref<BitmapTextBlob> cacheBlob; |
- // TODO start caching these, mix bits into the key |
+ |
+ SkMaskFilter::BlurRec blurRec; |
+ BitmapTextBlob::Key key; |
+ // It might be worth caching these things, but its not clear at this time |
+ // TODO for animated mask filters, this will fill up our cache. We need a safeguard here |
+ const SkMaskFilter* mf = skPaint.getMaskFilter(); |
bool canCache = !(skPaint.getPathEffect() || |
- skPaint.getMaskFilter() || |
- skPaint.getColorFilter() || |
- skPaint.getStyle() != SkPaint::kFill_Style || |
+ (mf && !mf->asABlur(&blurRec)) || |
drawFilter); |
if (canCache) { |
- cacheBlob.reset(SkSafeRef(fCache->find(uniqueID))); |
+ key.fUniqueID = blob->uniqueID(); |
+ key.fStyle = skPaint.getStyle(); |
+ key.fHasBlur = SkToBool(mf); |
+ cacheBlob.reset(SkSafeRef(fCache->find(key))); |
} |
SkIRect clipRect; |
@@ -182,12 +204,13 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, |
SkScalar transY = 0.f; |
if (cacheBlob) { |
- if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, viewMatrix, x, y)) { |
+ if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, viewMatrix, x, y)) { |
// We have to remake the blob because changes may invalidate our masks. |
// TODO we could probably get away reuse most of the time if the pointer is unique, |
// but we'd have to clear the subrun information |
fCache->remove(cacheBlob); |
- cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, kGrayTextVASize))); |
+ cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, skPaint, |
+ kGrayTextVASize))); |
this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, |
clipRect); |
} else { |
@@ -200,7 +223,8 @@ void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, |
} |
} else { |
if (canCache) { |
- cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, kGrayTextVASize))); |
+ cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, skPaint, |
+ kGrayTextVASize))); |
} else { |
cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); |
} |
@@ -224,7 +248,6 @@ void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
cacheBlob->fX = x; |
cacheBlob->fY = y; |
cacheBlob->fColor = skPaint.getColor(); |
- cacheBlob->fStyle = skPaint.getStyle(); |
// Regenerate textblob |
SkPaint runPaint = skPaint; |
@@ -302,7 +325,6 @@ void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, |
blob->fViewMatrix = viewMatrix; |
blob->fX = x; |
blob->fY = y; |
- blob->fStyle = skPaint.getStyle(); |
SkIRect clipRect; |
clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
@@ -413,7 +435,6 @@ void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, |
const SkPoint& offset, const SkIRect& regionClipBounds) { |
int glyphCount = skPaint.countText(text, byteLength); |
SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTextVASize)); |
- blob->fStyle = skPaint.getStyle(); |
blob->fViewMatrix = viewMatrix; |
SkIRect clipRect; |