Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2010 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 #ifndef GrTextStrike_DEFINED
     12 #define GrTextStrike_DEFINED
     13 
     14 #include "GrAllocPool.h"
     15 #include "GrFontScaler.h"
     16 #include "SkTDynamicHash.h"
     17 #include "GrGlyph.h"
     18 #include "GrDrawTarget.h"
     19 #include "GrAtlas.h"
     20 
     21 class GrFontCache;
     22 class GrGpu;
     23 class GrFontPurgeListener;
     24 
     25 /**
     26  *  The textcache maps a hostfontscaler instance to a dictionary of
     27  *  glyphid->strike
     28  */
     29 class GrTextStrike {
     30 public:
     31     GrTextStrike(GrFontCache*, const GrFontDescKey* fontScalerKey, GrMaskFormat, GrAtlas*);
     32     ~GrTextStrike();
     33 
     34     const GrFontDescKey* getFontScalerKey() const { return fFontScalerKey; }
     35     GrFontCache* getFontCache() const { return fFontCache; }
     36     GrMaskFormat getMaskFormat() const { return fMaskFormat; }
     37     GrTexture*   getTexture() const { return fAtlas->getTexture(); }
     38 
     39     inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
     40     // returns true if glyph (or glyph+padding for distance field)
     41     // is too large to ever fit in texture atlas subregions (GrPlots)
     42     bool glyphTooLargeForAtlas(GrGlyph*);
     43     // returns true if glyph successfully added to texture atlas, false otherwise
     44     bool addGlyphToAtlas(GrGlyph*, GrFontScaler*);
     45 
     46     // testing
     47     int countGlyphs() const { return fCache.count(); }
     48 
     49     // remove any references to this plot
     50     void removePlot(const GrPlot* plot);
     51 
     52     static const GrFontDescKey& GetKey(const GrTextStrike& ts) {
     53         return *(ts.fFontScalerKey);
     54     }
     55     static uint32_t Hash(const GrFontDescKey& key) {
     56         return key.getHash();
     57     }
     58 
     59 public:
     60     // for easy removal from list
     61     GrTextStrike*   fPrev;
     62     GrTextStrike*   fNext;
     63 
     64 private:
     65     SkTDynamicHash<GrGlyph, GrGlyph::PackedID> fCache;
     66     const GrFontDescKey* fFontScalerKey;
     67     GrTAllocPool<GrGlyph> fPool;
     68 
     69     GrFontCache*    fFontCache;
     70     GrAtlas*        fAtlas;
     71     GrMaskFormat    fMaskFormat;
     72     bool            fUseDistanceField;
     73 
     74     GrAtlas::ClientPlotUsage fPlotUsage;
     75 
     76     GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
     77 
     78     friend class GrFontCache;
     79 };
     80 
     81 class GrFontCache {
     82 public:
     83     GrFontCache(GrGpu*);
     84     ~GrFontCache();
     85 
     86     inline GrTextStrike* getStrike(GrFontScaler*, bool useDistanceField);
     87 
     88     void freeAll();
     89 
     90     // make an unused plot available
     91     bool freeUnusedPlot(GrTextStrike* preserveStrike);
     92 
     93     // testing
     94     int countStrikes() const { return fCache.count(); }
     95     GrTextStrike* getHeadStrike() const { return fHead; }
     96 
     97     void updateTextures() {
     98         for (int i = 0; i < kAtlasCount; ++i) {
     99             if (fAtlases[i]) {
    100                 fAtlases[i]->uploadPlotsToTexture();
    101             }
    102         }
    103     }
    104 
    105 #ifdef SK_DEBUG
    106     void validate() const;
    107 #else
    108     void validate() const {}
    109 #endif
    110 
    111     void dump() const;
    112 
    113     enum AtlasType {
    114         kA8_AtlasType,   //!< 1-byte per pixel
    115         k565_AtlasType,  //!< 2-bytes per pixel
    116         k8888_AtlasType, //!< 4-bytes per pixel
    117 
    118         kLast_AtlasType = k8888_AtlasType
    119     };
    120     static const int kAtlasCount = kLast_AtlasType + 1;
    121 
    122 private:
    123     friend class GrFontPurgeListener;
    124 
    125     SkTDynamicHash<GrTextStrike, GrFontDescKey> fCache;
    126     // for LRU
    127     GrTextStrike* fHead;
    128     GrTextStrike* fTail;
    129 
    130     GrGpu*      fGpu;
    131     GrAtlas*    fAtlases[kAtlasCount];
    132 
    133     GrTextStrike* generateStrike(GrFontScaler*);
    134     inline void detachStrikeFromList(GrTextStrike*);
    135     void purgeStrike(GrTextStrike* strike);
    136 };
    137 
    138 #endif
    139