diff options
author | 2015-12-10 07:44:50 -0800 | |
---|---|---|
committer | 2015-12-10 07:44:50 -0800 | |
commit | fd5f6c1b0d352b44ba08a677499c8c27b5aea7c7 (patch) | |
tree | 976b7a4255716458699cfc528ade7f708e425684 /src/gpu | |
parent | 067e90e72fdeba83eff7aeb917b2b25f74759282 (diff) |
Move 'mustRegenerate' function into GrAtlasTextBlob
BUG=skia:
Review URL: https://codereview.chromium.org/1515543003
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrAtlasTextBlob.cpp | 99 | ||||
-rw-r--r-- | src/gpu/GrAtlasTextBlob.h | 4 | ||||
-rw-r--r-- | src/gpu/GrAtlasTextContext.cpp | 102 | ||||
-rw-r--r-- | src/gpu/GrAtlasTextContext.h | 4 |
4 files changed, 105 insertions, 104 deletions
diff --git a/src/gpu/GrAtlasTextBlob.cpp b/src/gpu/GrAtlasTextBlob.cpp index 0f7368a924..1cd25e74de 100644 --- a/src/gpu/GrAtlasTextBlob.cpp +++ b/src/gpu/GrAtlasTextBlob.cpp @@ -86,6 +86,105 @@ void GrAtlasTextBlob::appendGlyph(int runIndex, subRun->glyphAppended(); } +bool GrAtlasTextBlob::mustRegenerate(SkScalar* outTransX, SkScalar* outTransY, + const SkPaint& paint, + GrColor color, const SkMaskFilter::BlurRec& blurRec, + const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { + // If we have LCD text then our canonical color will be set to transparent, in this case we have + // to regenerate the blob on any color change + // We use the grPaint to get any color filter effects + if (fKey.fCanonicalColor == SK_ColorTRANSPARENT && + fPaintColor != color) { + return true; + } + + if (fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { + return true; + } + + if (fViewMatrix.hasPerspective() && !fViewMatrix.cheapEqualTo(viewMatrix)) { + return true; + } + + // We only cache one masked version + if (fKey.fHasBlur && + (fBlurRec.fSigma != blurRec.fSigma || + fBlurRec.fStyle != blurRec.fStyle || + fBlurRec.fQuality != blurRec.fQuality)) { + return true; + } + + // Similarly, we only cache one version for each style + if (fKey.fStyle != SkPaint::kFill_Style && + (fStrokeInfo.fFrameWidth != paint.getStrokeWidth() || + fStrokeInfo.fMiterLimit != paint.getStrokeMiter() || + fStrokeInfo.fJoin != paint.getStrokeJoin())) { + return true; + } + + // Mixed blobs must be regenerated. We could probably figure out a way to do integer scrolls + // for mixed blobs if this becomes an issue. + if (this->hasBitmap() && this->hasDistanceField()) { + // Identical viewmatrices and we can reuse in all cases + if (fViewMatrix.cheapEqualTo(viewMatrix) && x == fX && y == fY) { + return false; + } + return true; + } + + if (this->hasBitmap()) { + if (fViewMatrix.getScaleX() != viewMatrix.getScaleX() || + fViewMatrix.getScaleY() != viewMatrix.getScaleY() || + fViewMatrix.getSkewX() != viewMatrix.getSkewX() || + fViewMatrix.getSkewY() != viewMatrix.getSkewY()) { + 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 + // generated vertex coordinates to move them to the correct position + SkScalar transX = viewMatrix.getTranslateX() + + viewMatrix.getScaleX() * (x - fX) + + viewMatrix.getSkewX() * (y - fY) - + fViewMatrix.getTranslateX(); + SkScalar transY = viewMatrix.getTranslateY() + + viewMatrix.getSkewY() * (x - fX) + + viewMatrix.getScaleY() * (y - fY) - + fViewMatrix.getTranslateY(); + if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY) ) { + return true; + } + + (*outTransX) = transX; + (*outTransY) = transY; + } else if (this->hasDistanceField()) { + // A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would result in a different + // distance field being generated, so we have to regenerate in those cases + SkScalar newMaxScale = viewMatrix.getMaxScale(); + SkScalar oldMaxScale = fViewMatrix.getMaxScale(); + SkScalar scaleAdjust = newMaxScale / oldMaxScale; + if (scaleAdjust < fMaxMinScale || scaleAdjust > fMinMaxScale) { + return true; + } + + (*outTransX) = x - fX; + (*outTransY) = y - fY; + } + + + // If we can reuse the blob, then make sure we update the blob's viewmatrix, and x/y + // offsets. Note, we offset the vertex bounds right before flushing + fViewMatrix = viewMatrix; + fX = x; + fY = y; + + // It is possible that a blob has neither distanceField nor bitmaptext. This is in the case + // when all of the runs inside the blob are drawn as paths. In this case, we always regenerate + // the blob anyways at flush time, so no need to regenerate explicitly + return false; +} + // TODO get this code building again #ifdef CACHE_SANITY_CHECK void GrAtlasTextBlob::AssertEqual(const GrAtlasTextBlob& l, const GrAtlasTextBlob& r) { diff --git a/src/gpu/GrAtlasTextBlob.h b/src/gpu/GrAtlasTextBlob.h index a400782977..3ec3c44999 100644 --- a/src/gpu/GrAtlasTextBlob.h +++ b/src/gpu/GrAtlasTextBlob.h @@ -300,6 +300,10 @@ struct GrAtlasTextBlob : public SkNVRefCnt<GrAtlasTextBlob> { } } + bool mustRegenerate(SkScalar* outTransX, SkScalar* outTransY, const SkPaint& paint, + GrColor color, const SkMaskFilter::BlurRec& blurRec, + const SkMatrix& viewMatrix, SkScalar x, SkScalar y); + // position + local coord static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16); static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + sizeof(SkIPoint16); diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index d7ccce54cf..615f7091cd 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -188,99 +188,6 @@ bool GrAtlasTextContext::HasLCD(const SkTextBlob* blob) { return false; } -bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTransY, - const GrAtlasTextBlob& blob, const SkPaint& paint, - GrColor color, const SkMaskFilter::BlurRec& blurRec, - const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { - // If we have LCD text then our canonical color will be set to transparent, in this case we have - // to regenerate the blob on any color change - // We use the grPaint to get any color filter effects - if (blob.fKey.fCanonicalColor == SK_ColorTRANSPARENT && - blob.fPaintColor != color) { - return true; - } - - if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { - return true; - } - - if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(viewMatrix)) { - 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; - } - - // Mixed blobs must be regenerated. We could probably figure out a way to do integer scrolls - // for mixed blobs if this becomes an issue. - if (blob.hasBitmap() && blob.hasDistanceField()) { - // Identical viewmatrices and we can reuse in all cases - if (blob.fViewMatrix.cheapEqualTo(viewMatrix) && x == blob.fX && y == blob.fY) { - return false; - } - return true; - } - - if (blob.hasBitmap()) { - if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() || - blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() || - blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() || - blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) { - 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 - // generated vertex coordinates to move them to the correct position - SkScalar transX = viewMatrix.getTranslateX() + - viewMatrix.getScaleX() * (x - blob.fX) + - viewMatrix.getSkewX() * (y - blob.fY) - - blob.fViewMatrix.getTranslateX(); - SkScalar transY = viewMatrix.getTranslateY() + - viewMatrix.getSkewY() * (x - blob.fX) + - viewMatrix.getScaleY() * (y - blob.fY) - - blob.fViewMatrix.getTranslateY(); - if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY) ) { - return true; - } - - (*outTransX) = transX; - (*outTransY) = transY; - } else if (blob.hasDistanceField()) { - // A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would result in a different - // distance field being generated, so we have to regenerate in those cases - SkScalar newMaxScale = viewMatrix.getMaxScale(); - SkScalar oldMaxScale = blob.fViewMatrix.getMaxScale(); - SkScalar scaleAdjust = newMaxScale / oldMaxScale; - if (scaleAdjust < blob.fMaxMinScale || scaleAdjust > blob.fMinMaxScale) { - return true; - } - - (*outTransX) = x - blob.fX; - (*outTransY) = y - blob.fY; - } - - // It is possible that a blob has neither distanceField nor bitmaptext. This is in the case - // when all of the runs inside the blob are drawn as paths. In this case, we always regenerate - // the blob anyways at flush time, so no need to regenerate explicitly - return false; -} - - inline SkGlyphCache* GrAtlasTextContext::setupCache(GrAtlasTextBlob::Run* run, const SkPaint& skPaint, const SkMatrix* viewMatrix, @@ -342,8 +249,8 @@ void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc, } if (cacheBlob) { - if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, grPaint.getColor(), blurRec, - viewMatrix, x, y)) { + if (cacheBlob->mustRegenerate(&transX, &transY, skPaint, grPaint.getColor(), 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 @@ -353,11 +260,6 @@ void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc, this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMatrix, blob, x, y, drawFilter, clip); } else { - // If we can reuse the blob, then make sure we update the blob's viewmatrix, and x/y - // offsets. Note, we offset the vertex bounds right before flushing - cacheBlob->fViewMatrix = viewMatrix; - cacheBlob->fX = x; - cacheBlob->fY = y; fCache->makeMRU(cacheBlob); #ifdef CACHE_SANITY_CHECK { diff --git a/src/gpu/GrAtlasTextContext.h b/src/gpu/GrAtlasTextContext.h index 04f3968a91..c85740d9e0 100644 --- a/src/gpu/GrAtlasTextContext.h +++ b/src/gpu/GrAtlasTextContext.h @@ -128,10 +128,6 @@ private: // sets up the descriptor on the blob and returns a detached cache. Client must attach inline static GrColor ComputeCanonicalColor(const SkPaint&, bool lcd); inline SkGlyphCache* setupCache(Run*, const SkPaint&, const SkMatrix* viewMatrix, bool noGamma); - static inline bool MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTransY, - const GrAtlasTextBlob&, const SkPaint&, GrColor, - const SkMaskFilter::BlurRec&, - const SkMatrix& viewMatrix, SkScalar x, SkScalar y); void regenerateTextBlob(GrAtlasTextBlob* bmp, const SkPaint& skPaint, GrColor, const SkMatrix& viewMatrix, const SkTextBlob* blob, SkScalar x, SkScalar y, |