| Index: src/gpu/text/GrAtlasTextBlob.h
|
| diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
|
| index ff371c16743d5e9e219e25e69263ee28c3fbfb8f..1c5ea5e60ea73d6e8253794e46813d4f922665c8 100644
|
| --- a/src/gpu/text/GrAtlasTextBlob.h
|
| +++ b/src/gpu/text/GrAtlasTextBlob.h
|
| @@ -45,6 +45,210 @@ class GrAtlasTextBlob : public SkNVRefCnt<GrAtlasTextBlob> {
|
| public:
|
| SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrAtlasTextBlob);
|
|
|
| + GrAtlasTextBlob()
|
| + : fMaxMinScale(-SK_ScalarMax)
|
| + , fMinMaxScale(SK_ScalarMax)
|
| + , fTextType(0) {}
|
| +
|
| + ~GrAtlasTextBlob() {
|
| + for (int i = 0; i < fRunCount; i++) {
|
| + fRuns[i].~Run();
|
| + }
|
| + }
|
| +
|
| + struct Key {
|
| + Key() {
|
| + sk_bzero(this, sizeof(Key));
|
| + }
|
| + uint32_t fUniqueID;
|
| + // Color may affect the gamma of the mask we generate, but in a fairly limited way.
|
| + // Each color is assigned to on of a fixed number of buckets based on its
|
| + // luminance. For each luminance bucket there is a "canonical color" that
|
| + // represents the bucket. This functionality is currently only supported for A8
|
| + SkColor fCanonicalColor;
|
| + SkPaint::Style fStyle;
|
| + SkPixelGeometry fPixelGeometry;
|
| + bool fHasBlur;
|
| +
|
| + bool operator==(const Key& other) const {
|
| + return 0 == memcmp(this, &other, sizeof(Key));
|
| + }
|
| + };
|
| +
|
| + static const Key& GetKey(const GrAtlasTextBlob& blob) {
|
| + return blob.fKey;
|
| + }
|
| +
|
| + static uint32_t Hash(const Key& key) {
|
| + return SkChecksum::Murmur3(&key, sizeof(Key));
|
| + }
|
| +
|
| + void operator delete(void* p) {
|
| + GrAtlasTextBlob* blob = reinterpret_cast<GrAtlasTextBlob*>(p);
|
| + blob->fPool->release(p);
|
| + }
|
| + void* operator new(size_t) {
|
| + SkFAIL("All blobs are created by placement new.");
|
| + return sk_malloc_throw(0);
|
| + }
|
| +
|
| + void* operator new(size_t, void* p) { return p; }
|
| + void operator delete(void* target, void* placement) {
|
| + ::operator delete(target, placement);
|
| + }
|
| +
|
| + bool hasDistanceField() const { return SkToBool(fTextType & kHasDistanceField_TextType); }
|
| + bool hasBitmap() const { return SkToBool(fTextType & kHasBitmap_TextType); }
|
| + void setHasDistanceField() { fTextType |= kHasDistanceField_TextType; }
|
| + void setHasBitmap() { fTextType |= kHasBitmap_TextType; }
|
| +
|
| + void push_back_run(int currRun) {
|
| + SkASSERT(currRun < fRunCount);
|
| + if (currRun > 0) {
|
| + Run::SubRunInfo& newRun = fRuns[currRun].fSubRunInfo.back();
|
| + Run::SubRunInfo& lastRun = fRuns[currRun - 1].fSubRunInfo.back();
|
| + newRun.setAsSuccessor(lastRun);
|
| + }
|
| + }
|
| +
|
| + // sets the last subrun of runIndex to use distance field text
|
| + void setSubRunHasDistanceFields(int runIndex, bool hasLCD) {
|
| + Run& run = fRuns[runIndex];
|
| + Run::SubRunInfo& subRun = run.fSubRunInfo.back();
|
| + subRun.setUseLCDText(hasLCD);
|
| + subRun.setDrawAsDistanceFields();
|
| + }
|
| +
|
| + void setRunDrawAsPaths(int runIndex) {
|
| + fRuns[runIndex].fDrawAsPaths = true;
|
| + }
|
| +
|
| + void setMinAndMaxScale(SkScalar scaledMax, SkScalar scaledMin) {
|
| + // we init fMaxMinScale and fMinMaxScale in the constructor
|
| + fMaxMinScale = SkMaxScalar(scaledMax, fMaxMinScale);
|
| + fMinMaxScale = SkMinScalar(scaledMin, fMinMaxScale);
|
| + }
|
| +
|
| + // inits the override descriptor on the current run. All following subruns must use this
|
| + // descriptor
|
| + void initOverride(int runIndex) {
|
| + Run& run = fRuns[runIndex];
|
| + // Push back a new subrun to fill and set the override descriptor
|
| + run.push_back();
|
| + run.fOverrideDescriptor.reset(new SkAutoDescriptor);
|
| + }
|
| +
|
| + SkGlyphCache* setupCache(int runIndex,
|
| + const SkSurfaceProps& props,
|
| + const SkPaint& skPaint,
|
| + const SkMatrix* viewMatrix,
|
| + bool noGamma);
|
| +
|
| + // Appends a glyph to the blob. If the glyph is too large, the glyph will be appended
|
| + // as a path.
|
| + void appendGlyph(int runIndex,
|
| + const SkRect& positions,
|
| + GrColor color,
|
| + GrBatchTextStrike* strike,
|
| + GrGlyph* glyph,
|
| + GrFontScaler* scaler, const SkGlyph& skGlyph,
|
| + SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
|
| +
|
| + static size_t GetVertexStride(GrMaskFormat maskFormat) {
|
| + switch (maskFormat) {
|
| + case kA8_GrMaskFormat:
|
| + return kGrayTextVASize;
|
| + case kARGB_GrMaskFormat:
|
| + return kColorTextVASize;
|
| + default:
|
| + return kLCDTextVASize;
|
| + }
|
| + }
|
| +
|
| + bool mustRegenerate(SkScalar* outTransX, SkScalar* outTransY, const SkPaint& paint,
|
| + GrColor color, const SkMaskFilter::BlurRec& blurRec,
|
| + const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
|
| +
|
| + // flush a GrAtlasTextBlob associated with a SkTextBlob
|
| + void flushCached(GrContext* context,
|
| + GrDrawContext* dc,
|
| + const SkTextBlob* blob,
|
| + const SkSurfaceProps& props,
|
| + const GrDistanceFieldAdjustTable* distanceAdjustTable,
|
| + const SkPaint& skPaint,
|
| + const GrPaint& grPaint,
|
| + SkDrawFilter* drawFilter,
|
| + const GrClip& clip,
|
| + const SkMatrix& viewMatrix,
|
| + const SkIRect& clipBounds,
|
| + SkScalar x, SkScalar y,
|
| + SkScalar transX, SkScalar transY);
|
| +
|
| + // flush a throwaway GrAtlasTextBlob *not* associated with an SkTextBlob
|
| + void flushThrowaway(GrContext* context,
|
| + GrDrawContext* dc,
|
| + const SkSurfaceProps& props,
|
| + const GrDistanceFieldAdjustTable* distanceAdjustTable,
|
| + const SkPaint& skPaint,
|
| + const GrPaint& grPaint,
|
| + const GrClip& clip,
|
| + const SkIRect& clipBounds);
|
| +
|
| + // 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 size_t kLCDTextVASize = kGrayTextVASize;
|
| + static const int kVerticesPerGlyph = 4;
|
| +
|
| +#ifdef CACHE_SANITY_CHECK
|
| + static void AssertEqual(const GrAtlasTextBlob&, const GrAtlasTextBlob&);
|
| + size_t fSize;
|
| +#endif
|
| +
|
| + // The color here is the GrPaint color, and it is used to determine whether we
|
| + // have to regenerate LCD text blobs.
|
| + // We use this color vs the SkPaint color because it has the colorfilter applied.
|
| + void initReusableBlob(GrColor color, const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
|
| + fPaintColor = color;
|
| + fViewMatrix = viewMatrix;
|
| + fX = x;
|
| + fY = y;
|
| + }
|
| +
|
| + void initThrowawayBlob(const SkMatrix& viewMatrix) {
|
| + fViewMatrix = viewMatrix;
|
| + }
|
| +
|
| + GrDrawBatch* test_createBatch(int glyphCount, int run, int subRun,
|
| + GrColor color, SkScalar transX, SkScalar transY,
|
| + const SkPaint& skPaint, const SkSurfaceProps& props,
|
| + const GrDistanceFieldAdjustTable* distanceAdjustTable,
|
| + GrBatchFontCache* cache);
|
| +
|
| +private:
|
| + void appendLargeGlyph(GrGlyph* glyph, GrFontScaler* scaler, const SkGlyph& skGlyph,
|
| + SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
|
| +
|
| + inline void flushRun(GrDrawContext* dc, GrPipelineBuilder* pipelineBuilder,
|
| + int run, GrColor color,
|
| + SkScalar transX, SkScalar transY,
|
| + const SkPaint& skPaint, const SkSurfaceProps& props,
|
| + const GrDistanceFieldAdjustTable* distanceAdjustTable,
|
| + GrBatchFontCache* cache);
|
| +
|
| + void flushBigGlyphs(GrContext* context, GrDrawContext* dc,
|
| + const GrClip& clip, const SkPaint& skPaint,
|
| + SkScalar transX, SkScalar transY,
|
| + const SkIRect& clipBounds);
|
| +
|
| + void flushRunAsPaths(GrContext* context,
|
| + GrDrawContext* dc,
|
| + const SkSurfaceProps& props,
|
| + const SkTextBlobRunIterator& it,
|
| + const GrClip& clip, const SkPaint& skPaint,
|
| + SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
|
| + const SkIRect& clipBounds, SkScalar x, SkScalar y);
|
| +
|
| /*
|
| * Each Run inside of the blob can have its texture coordinates regenerated if required.
|
| * To determine if regeneration is necessary, fAtlasGeneration is used. If there have been
|
| @@ -177,6 +381,13 @@ public:
|
| bool fDrawAsPaths;
|
| };
|
|
|
| + inline GrDrawBatch* createBatch(const Run::SubRunInfo& info,
|
| + int glyphCount, int run, int subRun,
|
| + GrColor color, SkScalar transX, SkScalar transY,
|
| + const SkPaint& skPaint, const SkSurfaceProps& props,
|
| + const GrDistanceFieldAdjustTable* distanceAdjustTable,
|
| + GrBatchFontCache* cache);
|
| +
|
| struct BigGlyph {
|
| BigGlyph(const SkPath& path, SkScalar vx, SkScalar vy, SkScalar scale, bool applyVM)
|
| : fPath(path)
|
| @@ -191,25 +402,6 @@ public:
|
| bool fApplyVM;
|
| };
|
|
|
| - struct Key {
|
| - Key() {
|
| - sk_bzero(this, sizeof(Key));
|
| - }
|
| - uint32_t fUniqueID;
|
| - // Color may affect the gamma of the mask we generate, but in a fairly limited way.
|
| - // Each color is assigned to on of a fixed number of buckets based on its
|
| - // luminance. For each luminance bucket there is a "canonical color" that
|
| - // represents the bucket. This functionality is currently only supported for A8
|
| - SkColor fCanonicalColor;
|
| - SkPaint::Style fStyle;
|
| - SkPixelGeometry fPixelGeometry;
|
| - bool fHasBlur;
|
| -
|
| - bool operator==(const Key& other) const {
|
| - return 0 == memcmp(this, &other, sizeof(Key));
|
| - }
|
| - };
|
| -
|
| struct StrokeInfo {
|
| SkScalar fFrameWidth;
|
| SkScalar fMiterLimit;
|
| @@ -243,169 +435,8 @@ public:
|
| int fRunCount;
|
| uint8_t fTextType;
|
|
|
| - GrAtlasTextBlob()
|
| - : fMaxMinScale(-SK_ScalarMax)
|
| - , fMinMaxScale(SK_ScalarMax)
|
| - , fTextType(0) {}
|
| -
|
| - ~GrAtlasTextBlob() {
|
| - for (int i = 0; i < fRunCount; i++) {
|
| - fRuns[i].~Run();
|
| - }
|
| - }
|
| -
|
| - static const Key& GetKey(const GrAtlasTextBlob& blob) {
|
| - return blob.fKey;
|
| - }
|
| -
|
| - static uint32_t Hash(const Key& key) {
|
| - return SkChecksum::Murmur3(&key, sizeof(Key));
|
| - }
|
| -
|
| - void operator delete(void* p) {
|
| - GrAtlasTextBlob* blob = reinterpret_cast<GrAtlasTextBlob*>(p);
|
| - blob->fPool->release(p);
|
| - }
|
| - void* operator new(size_t) {
|
| - SkFAIL("All blobs are created by placement new.");
|
| - return sk_malloc_throw(0);
|
| - }
|
| -
|
| - void* operator new(size_t, void* p) { return p; }
|
| - void operator delete(void* target, void* placement) {
|
| - ::operator delete(target, placement);
|
| - }
|
| -
|
| - bool hasDistanceField() const { return SkToBool(fTextType & kHasDistanceField_TextType); }
|
| - bool hasBitmap() const { return SkToBool(fTextType & kHasBitmap_TextType); }
|
| - void setHasDistanceField() { fTextType |= kHasDistanceField_TextType; }
|
| - void setHasBitmap() { fTextType |= kHasBitmap_TextType; }
|
| -
|
| - void push_back_run(int currRun) {
|
| - SkASSERT(currRun < fRunCount);
|
| - if (currRun > 0) {
|
| - Run::SubRunInfo& newRun = fRuns[currRun].fSubRunInfo.back();
|
| - Run::SubRunInfo& lastRun = fRuns[currRun - 1].fSubRunInfo.back();
|
| - newRun.setAsSuccessor(lastRun);
|
| - }
|
| - }
|
| -
|
| - // sets the last subrun of runIndex to use distance field text
|
| - void setSubRunHasDistanceFields(int runIndex, bool hasLCD) {
|
| - Run& run = fRuns[runIndex];
|
| - Run::SubRunInfo& subRun = run.fSubRunInfo.back();
|
| - subRun.setUseLCDText(hasLCD);
|
| - subRun.setDrawAsDistanceFields();
|
| - }
|
| -
|
| - // inits the override descriptor on the current run. All following subruns must use this
|
| - // descriptor
|
| - void initOverride(int runIndex) {
|
| - Run& run = fRuns[runIndex];
|
| - // Push back a new subrun to fill and set the override descriptor
|
| - run.push_back();
|
| - run.fOverrideDescriptor.reset(new SkAutoDescriptor);
|
| - }
|
| -
|
| - SkGlyphCache* setupCache(int runIndex,
|
| - const SkSurfaceProps& props,
|
| - const SkPaint& skPaint,
|
| - const SkMatrix* viewMatrix,
|
| - bool noGamma);
|
| -
|
| - // Appends a glyph to the blob. If the glyph is too large, the glyph will be appended
|
| - // as a path.
|
| - void appendGlyph(int runIndex,
|
| - const SkRect& positions,
|
| - GrColor color,
|
| - GrBatchTextStrike* strike,
|
| - GrGlyph* glyph,
|
| - GrFontScaler* scaler, const SkGlyph& skGlyph,
|
| - SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
|
| -
|
| - static size_t GetVertexStride(GrMaskFormat maskFormat) {
|
| - switch (maskFormat) {
|
| - case kA8_GrMaskFormat:
|
| - return kGrayTextVASize;
|
| - case kARGB_GrMaskFormat:
|
| - return kColorTextVASize;
|
| - default:
|
| - return kLCDTextVASize;
|
| - }
|
| - }
|
| -
|
| - bool mustRegenerate(SkScalar* outTransX, SkScalar* outTransY, const SkPaint& paint,
|
| - GrColor color, const SkMaskFilter::BlurRec& blurRec,
|
| - const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
|
| -
|
| - // flush a GrAtlasTextBlob associated with a SkTextBlob
|
| - void flushCached(GrContext* context,
|
| - GrDrawContext* dc,
|
| - const SkTextBlob* blob,
|
| - const SkSurfaceProps& props,
|
| - const GrDistanceFieldAdjustTable* distanceAdjustTable,
|
| - const SkPaint& skPaint,
|
| - const GrPaint& grPaint,
|
| - SkDrawFilter* drawFilter,
|
| - const GrClip& clip,
|
| - const SkMatrix& viewMatrix,
|
| - const SkIRect& clipBounds,
|
| - SkScalar x, SkScalar y,
|
| - SkScalar transX, SkScalar transY);
|
| -
|
| - // flush a throwaway GrAtlasTextBlob *not* associated with an SkTextBlob
|
| - void flushThrowaway(GrContext* context,
|
| - GrDrawContext* dc,
|
| - const SkSurfaceProps& props,
|
| - const GrDistanceFieldAdjustTable* distanceAdjustTable,
|
| - const SkPaint& skPaint,
|
| - const GrPaint& grPaint,
|
| - const GrClip& clip,
|
| - const SkIRect& clipBounds);
|
| -
|
| - // 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 size_t kLCDTextVASize = kGrayTextVASize;
|
| - static const int kVerticesPerGlyph = 4;
|
| -
|
| -#ifdef CACHE_SANITY_CHECK
|
| - static void AssertEqual(const GrAtlasTextBlob&, const GrAtlasTextBlob&);
|
| - size_t fSize;
|
| -#endif
|
| -
|
| - // We'd like to inline this and make it private, but there is some test code which calls it.
|
| - // TODO refactor this
|
| - GrDrawBatch* createBatch(const Run::SubRunInfo& info,
|
| - int glyphCount, int run, int subRun,
|
| - GrColor color, SkScalar transX, SkScalar transY,
|
| - const SkPaint& skPaint, const SkSurfaceProps& props,
|
| - const GrDistanceFieldAdjustTable* distanceAdjustTable,
|
| - GrBatchFontCache* cache);
|
| -
|
| -private:
|
| - void appendLargeGlyph(GrGlyph* glyph, GrFontScaler* scaler, const SkGlyph& skGlyph,
|
| - SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
|
| -
|
| - inline void flushRun(GrDrawContext* dc, GrPipelineBuilder* pipelineBuilder,
|
| - int run, GrColor color,
|
| - SkScalar transX, SkScalar transY,
|
| - const SkPaint& skPaint, const SkSurfaceProps& props,
|
| - const GrDistanceFieldAdjustTable* distanceAdjustTable,
|
| - GrBatchFontCache* cache);
|
| -
|
| - void flushBigGlyphs(GrContext* context, GrDrawContext* dc,
|
| - const GrClip& clip, const SkPaint& skPaint,
|
| - SkScalar transX, SkScalar transY,
|
| - const SkIRect& clipBounds);
|
| -
|
| - void flushRunAsPaths(GrContext* context,
|
| - GrDrawContext* dc,
|
| - const SkSurfaceProps& props,
|
| - const SkTextBlobRunIterator& it,
|
| - const GrClip& clip, const SkPaint& skPaint,
|
| - SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
|
| - const SkIRect& clipBounds, SkScalar x, SkScalar y);
|
| + friend class GrAtlasTextBatch; // We might be able to get rid of this friending
|
| + friend class GrTextBlobCache; // Needs to access the key
|
| };
|
|
|
| #endif
|
|
|