Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkScaledImageCache_DEFINED
      9 #define SkScaledImageCache_DEFINED
     10 
     11 #include "SkBitmap.h"
     12 
     13 class SkMipMap;
     14 
     15 /**
     16  *  Cache object for bitmaps (with possible scale in X Y as part of the key).
     17  *
     18  *  Multiple caches can be instantiated, but each instance is not implicitly
     19  *  thread-safe, so if a given instance is to be shared across threads, the
     20  *  caller must manage the access itself (e.g. via a mutex).
     21  *
     22  *  As a convenience, a global instance is also defined, which can be safely
     23  *  access across threads via the static methods (e.g. FindAndLock, etc.).
     24  */
     25 class SkScaledImageCache {
     26 public:
     27     struct ID;
     28 
     29     /*
     30      *  The following static methods are thread-safe wrappers around a global
     31      *  instance of this cache.
     32      */
     33 
     34     static ID* FindAndLock(const SkBitmap& original, SkScalar scaleX,
     35                            SkScalar scaleY, SkBitmap* scaled);
     36     static ID* FindAndLockMip(const SkBitmap& original, SkMipMap const**);
     37 
     38     static ID* AddAndLock(const SkBitmap& original, SkScalar scaleX,
     39                           SkScalar scaleY, const SkBitmap& scaled);
     40     static ID* AddAndLockMip(const SkBitmap& original, const SkMipMap*);
     41 
     42     static void Unlock(ID*);
     43 
     44     static size_t GetBytesUsed();
     45     static size_t GetByteLimit();
     46     static size_t SetByteLimit(size_t newLimit);
     47 
     48     ///////////////////////////////////////////////////////////////////////////
     49 
     50     SkScaledImageCache(size_t byteLimit);
     51     ~SkScaledImageCache();
     52 
     53     /**
     54      *  Search the cache for a scaled version of original. If found, return it
     55      *  in scaled, and return its ID pointer. Use the returned ptr to unlock
     56      *  the cache when you are done using scaled.
     57      *
     58      *  If a match is not found, scaled will be unmodifed, and NULL will be
     59      *  returned.
     60      */
     61     ID* findAndLock(const SkBitmap& original, SkScalar scaleX,
     62                     SkScalar scaleY, SkBitmap* scaled);
     63     ID* findAndLockMip(const SkBitmap& original, SkMipMap const**);
     64 
     65     /**
     66      *  To add a new (scaled) bitmap to the cache, call AddAndLock. Use the
     67      *  returned ptr to unlock the cache when you are done using scaled.
     68      */
     69     ID* addAndLock(const SkBitmap& original, SkScalar scaleX,
     70                    SkScalar scaleY, const SkBitmap& scaled);
     71     ID* addAndLockMip(const SkBitmap& original, const SkMipMap*);
     72 
     73     /**
     74      *  Given a non-null ID ptr returned by either findAndLock or addAndLock,
     75      *  this releases the associated resources to be available to be purged
     76      *  if needed. After this, the cached bitmap should no longer be
     77      *  referenced by the caller.
     78      */
     79     void unlock(ID*);
     80 
     81     size_t getBytesUsed() const { return fBytesUsed; }
     82     size_t getByteLimit() const { return fByteLimit; }
     83 
     84     /**
     85      *  Set the maximum number of bytes available to this cache. If the current
     86      *  cache exceeds this new value, it will be purged to try to fit within
     87      *  this new limit.
     88      */
     89     size_t setByteLimit(size_t newLimit);
     90 
     91 public:
     92     struct Rec;
     93 private:
     94     Rec*    fHead;
     95     Rec*    fTail;
     96 
     97     class Hash;
     98     Hash*   fHash;
     99 
    100     size_t  fBytesUsed;
    101     size_t  fByteLimit;
    102     int     fCount;
    103 
    104     Rec* findAndLock(const SkBitmap& original, SkScalar sx, SkScalar sy);
    105 
    106     void purgeAsNeeded();
    107 
    108     // linklist management
    109     void moveToHead(Rec*);
    110     void addToHead(Rec*);
    111     void detach(Rec*);
    112 #ifdef SK_DEBUG
    113     void validate() const;
    114 #else
    115     void validate() const {}
    116 #endif
    117 };
    118 
    119 #endif
    120