LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkGlyphCache.h (source / functions) Found Hit Coverage
Test: app.info Lines: 38 0 0.0 %
Date: 2012-06-02 Functions: 11 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2006 The Android Open Source Project
       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                 : #ifndef SkGlyphCache_DEFINED
      11                 : #define SkGlyphCache_DEFINED
      12                 : 
      13                 : #include "SkBitmap.h"
      14                 : #include "SkChunkAlloc.h"
      15                 : #include "SkDescriptor.h"
      16                 : #include "SkScalerContext.h"
      17                 : #include "SkTemplates.h"
      18                 : 
      19                 : class SkPaint;
      20                 : 
      21                 : class SkGlyphCache_Globals;
      22                 : 
      23                 : /** \class SkGlyphCache
      24                 : 
      25                 :     This class represents a strike: a specific combination of typeface, size,
      26                 :     matrix, etc., and holds the glyphs for that strike. Calling any of the
      27                 :     getUnichar.../getGlyphID... methods will return the requested glyph,
      28                 :     either instantly if it is already cahced, or by first generating it and then
      29                 :     adding it to the strike.
      30                 : 
      31                 :     The strikes are held in a global list, available to all threads. To interact
      32                 :     with one, call either VisitCache() or DetachCache().
      33                 : */
      34                 : class SkGlyphCache {
      35                 : public:
      36                 :     /** Returns a glyph with valid fAdvance and fDevKern fields.
      37                 :         The remaining fields may be valid, but that is not guaranteed. If you
      38                 :         require those, call getUnicharMetrics or getGlyphIDMetrics instead.
      39                 :     */
      40                 :     const SkGlyph& getUnicharAdvance(SkUnichar);
      41                 :     const SkGlyph& getGlyphIDAdvance(uint16_t);
      42                 : 
      43                 :     /** Returns a glyph with all fields valid except fImage and fPath, which
      44                 :         may be null. If they are null, call findImage or findPath for those.
      45                 :         If they are not null, then they are valid.
      46                 : 
      47                 :         This call is potentially slower than the matching ...Advance call. If
      48                 :         you only need the fAdvance/fDevKern fields, call those instead.
      49                 :     */
      50                 :     const SkGlyph& getUnicharMetrics(SkUnichar);
      51                 :     const SkGlyph& getGlyphIDMetrics(uint16_t);
      52                 : 
      53                 :     /** These are variants that take the device position of the glyph. Call
      54                 :         these only if you are drawing in subpixel mode. Passing 0, 0 is
      55                 :         effectively the same as calling the variants w/o the extra params, tho
      56                 :         a tiny bit slower.
      57                 :     */
      58                 :     const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y);
      59                 :     const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y);
      60                 : 
      61                 :     /** Return the glyphID for the specified Unichar. If the char has already
      62                 :         been seen, use the existing cache entry. If not, ask the scalercontext
      63                 :         to compute it for us.
      64                 :     */
      65                 :     uint16_t unicharToGlyph(SkUnichar);
      66                 : 
      67                 :     /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to
      68                 :         a character code of zero.
      69                 :     */
      70                 :     SkUnichar glyphToUnichar(uint16_t);
      71                 : 
      72                 :     /** Returns the number of glyphs for this strike.
      73                 :     */
      74                 :     unsigned getGlyphCount();
      75                 : 
      76                 :     /** Return the image associated with the glyph. If it has not been generated
      77                 :         this will trigger that.
      78                 :     */
      79                 :     const void* findImage(const SkGlyph&);
      80                 :     /** Return the Path associated with the glyph. If it has not been generated
      81                 :         this will trigger that.
      82                 :     */
      83                 :     const SkPath* findPath(const SkGlyph&);
      84                 : 
      85                 :     /** Return the vertical metrics for this strike.
      86                 :     */
      87               0 :     const SkPaint::FontMetrics& getFontMetricsY() const {
      88               0 :         return fFontMetricsY;
      89                 :     }
      90                 : 
      91                 :     const SkDescriptor& getDescriptor() const { return *fDesc; }
      92                 : 
      93                 :     SkMask::Format getMaskFormat() const {
      94                 :         return fScalerContext->getMaskFormat();
      95                 :     }
      96                 : 
      97                 :     bool isSubpixel() const {
      98                 :         return fScalerContext->isSubpixel();
      99                 :     }
     100                 : 
     101                 :     /*  AuxProc/Data allow a client to associate data with this cache entry.
     102                 :         Multiple clients can use this, as their data is keyed with a function
     103                 :         pointer. In addition to serving as a key, the function pointer is called
     104                 :         with the data when the glyphcache object is deleted, so the client can
     105                 :         cleanup their data as well. NOTE: the auxProc must not try to access
     106                 :         this glyphcache in any way, since it may be in the process of being
     107                 :         deleted.
     108                 :     */
     109                 : 
     110                 :     //! If the proc is found, return true and set *dataPtr to its data
     111                 :     bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const;
     112                 :     //! Add a proc/data pair to the glyphcache. proc should be non-null
     113                 :     void setAuxProc(void (*auxProc)(void*), void* auxData);
     114                 :     //! If found, remove the proc/data pair from the glyphcache (does not
     115                 :     //  call the proc)
     116                 :     void removeAuxProc(void (*auxProc)(void*));
     117                 : 
     118                 :     /** Call proc on all cache entries, stopping early if proc returns true.
     119                 :         The proc should not create or delete caches, since it could produce
     120                 :         deadlock.
     121                 :     */
     122                 :     static void VisitAllCaches(bool (*proc)(SkGlyphCache*, void*), void* ctx);
     123                 : 
     124                 :     /** Find a matching cache entry, and call proc() with it. If none is found
     125                 :         create a new one. If the proc() returns true, detach the cache and
     126                 :         return it, otherwise leave it and return NULL.
     127                 :     */
     128                 :     static SkGlyphCache* VisitCache(const SkDescriptor* desc,
     129                 :                                     bool (*proc)(const SkGlyphCache*, void*),
     130                 :                                     void* context);
     131                 : 
     132                 :     /** Given a strike that was returned by either VisitCache() or DetachCache()
     133                 :         add it back into the global cache list (after which the caller should
     134                 :         not reference it anymore.
     135                 :     */
     136                 :     static void AttachCache(SkGlyphCache*);
     137                 : 
     138                 :     /** Detach a strike from the global cache matching the specified descriptor.
     139                 :         Once detached, it can be queried/modified by the current thread, and
     140                 :         when finished, be reattached to the global cache with AttachCache().
     141                 :         While detached, if another request is made with the same descriptor,
     142                 :         a different strike will be generated. This is fine. It does mean we
     143                 :         can have more than 1 strike for the same descriptor, but that will
     144                 :         eventually get purged, and the win is that different thread will never
     145                 :         block each other while a strike is being used.
     146                 :     */
     147               0 :     static SkGlyphCache* DetachCache(const SkDescriptor* desc) {
     148               0 :         return VisitCache(desc, DetachProc, NULL);
     149                 :     }
     150                 : 
     151                 :     /** Return the approximate number of bytes used by the font cache
     152                 :     */
     153                 :     static size_t GetCacheUsed();
     154                 : 
     155                 :     /** This can be called to purge old font data, in an attempt to free
     156                 :         enough bytes such that the font cache is not using more than the
     157                 :         specified number of bytes. It is thread-safe, and may be called at
     158                 :         any time.
     159                 :         Return true if some amount of the cache was purged.
     160                 :     */
     161                 :     static bool SetCacheUsed(size_t bytesUsed);
     162                 : 
     163                 : #ifdef SK_DEBUG
     164                 :     void validate() const;
     165                 : #else
     166                 :     void validate() const {}
     167                 : #endif
     168                 : 
     169                 :     class AutoValidate : SkNoncopyable {
     170                 :     public:
     171               0 :         AutoValidate(const SkGlyphCache* cache) : fCache(cache) {
     172               0 :             if (fCache) {
     173               0 :                 fCache->validate();
     174                 :             }
     175               0 :         }
     176               0 :         ~AutoValidate() {
     177               0 :             if (fCache) {
     178               0 :                 fCache->validate();
     179                 :             }
     180               0 :         }
     181                 :         void forget() {
     182                 :             fCache = NULL;
     183                 :         }
     184                 :     private:
     185                 :         const SkGlyphCache* fCache;
     186                 :     };
     187                 : 
     188                 : private:
     189                 :     SkGlyphCache(const SkDescriptor*);
     190                 :     ~SkGlyphCache();
     191                 : 
     192                 :     enum MetricsType {
     193                 :         kJustAdvance_MetricsType,
     194                 :         kFull_MetricsType
     195                 :     };
     196                 : 
     197                 :     SkGlyph* lookupMetrics(uint32_t id, MetricsType);
     198               0 :     static bool DetachProc(const SkGlyphCache*, void*) { return true; }
     199                 : 
     200               0 :     void detach(SkGlyphCache** head) {
     201               0 :         if (fPrev) {
     202               0 :             fPrev->fNext = fNext;
     203                 :         } else {
     204               0 :             *head = fNext;
     205                 :         }
     206               0 :         if (fNext) {
     207               0 :             fNext->fPrev = fPrev;
     208                 :         }
     209               0 :         fPrev = fNext = NULL;
     210               0 :     }
     211                 : 
     212               0 :     void attachToHead(SkGlyphCache** head) {
     213               0 :         SkASSERT(NULL == fPrev && NULL == fNext);
     214               0 :         if (*head) {
     215               0 :             (*head)->fPrev = this;
     216               0 :             fNext = *head;
     217                 :         }
     218               0 :         *head = this;
     219               0 :     }
     220                 : 
     221                 :     SkGlyphCache*       fNext, *fPrev;
     222                 :     SkDescriptor*       fDesc;
     223                 :     SkScalerContext*    fScalerContext;
     224                 :     SkPaint::FontMetrics fFontMetricsY;
     225                 : 
     226                 :     enum {
     227                 :         kHashBits   = 12,
     228                 :         kHashCount  = 1 << kHashBits,
     229                 :         kHashMask   = kHashCount - 1
     230                 :     };
     231                 :     SkGlyph*            fGlyphHash[kHashCount];
     232                 :     SkTDArray<SkGlyph*> fGlyphArray;
     233                 :     SkChunkAlloc        fGlyphAlloc;
     234                 :     SkChunkAlloc        fImageAlloc;
     235                 : 
     236                 :     int fMetricsCount, fAdvanceCount;
     237                 : 
     238                 :     struct CharGlyphRec {
     239                 :         uint32_t    fID;    // unichar + subpixel
     240                 :         SkGlyph*    fGlyph;
     241                 :     };
     242                 :     // no reason to use the same kHashCount as fGlyphHash, but we do for now
     243                 :     CharGlyphRec    fCharToGlyphHash[kHashCount];
     244                 : 
     245                 :     enum {
     246                 :         // shift so that the top bits fall into kHashBits region
     247                 :         kShiftForHashIndex = SkGlyph::kSubShift +
     248                 :                              SkGlyph::kSubBits*2 -
     249                 :                              kHashBits
     250                 :     };
     251                 : 
     252               0 :     static inline unsigned ID2HashIndex(uint32_t id) {
     253               0 :         return (id ^ (id >> kShiftForHashIndex)) & kHashMask;
     254                 :     }
     255                 : 
     256                 :     // used to track (approx) how much ram is tied-up in this cache
     257                 :     size_t  fMemoryUsed;
     258                 : 
     259                 :     struct AuxProcRec {
     260                 :         AuxProcRec* fNext;
     261                 :         void (*fProc)(void*);
     262                 :         void* fData;
     263                 :     };
     264                 :     AuxProcRec* fAuxProcList;
     265                 :     void invokeAndRemoveAuxProcs();
     266                 : 
     267                 :     // This relies on the caller to have already acquired the mutex to access the global cache
     268                 :     static size_t InternalFreeCache(SkGlyphCache_Globals*, size_t bytesNeeded);
     269                 : 
     270                 :     inline static SkGlyphCache* FindTail(SkGlyphCache* head);
     271                 :     static size_t ComputeMemoryUsed(const SkGlyphCache* head);
     272                 : 
     273                 :     friend class SkGlyphCache_Globals;
     274                 : };
     275                 : 
     276                 : class SkAutoGlyphCache {
     277                 : public:
     278                 :     SkAutoGlyphCache(SkGlyphCache* cache) : fCache(cache) {}
     279                 :     SkAutoGlyphCache(const SkDescriptor* desc) {
     280                 :         fCache = SkGlyphCache::DetachCache(desc);
     281                 :     }
     282               0 :     SkAutoGlyphCache(const SkPaint& paint, const SkMatrix* matrix) {
     283               0 :         fCache = paint.detachCache(matrix);
     284               0 :     }
     285               0 :     ~SkAutoGlyphCache() {
     286               0 :         if (fCache) {
     287               0 :             SkGlyphCache::AttachCache(fCache);
     288                 :         }
     289               0 :     }
     290                 : 
     291               0 :     SkGlyphCache* getCache() const { return fCache; }
     292                 : 
     293                 :     void release() {
     294                 :         if (fCache) {
     295                 :             SkGlyphCache::AttachCache(fCache);
     296                 :             fCache = NULL;
     297                 :         }
     298                 :     }
     299                 : 
     300                 : private:
     301                 :     SkGlyphCache*   fCache;
     302                 : 
     303                 :     static bool DetachProc(const SkGlyphCache*, void*);
     304                 : };
     305                 : 
     306                 : #endif
     307                 : 

Generated by: LCOV version 1.7