121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com/*
321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com * Copyright 2012 Google Inc.
421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com *
521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com * Use of this source code is governed by a BSD-style license that can be
621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com * found in the LICENSE file.
721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com */
821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com#ifndef SkBitmapHeap_DEFINED
921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com#define SkBitmapHeap_DEFINED
1021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
1121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com#include "SkBitmap.h"
1221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com#include "SkFlattenable.h"
1321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com#include "SkRefCnt.h"
1421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com#include "SkTDArray.h"
1521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com#include "SkThread.h"
1621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
1721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com/**
1821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com * SkBitmapHeapEntry provides users of SkBitmapHeap (using internal storage) with a means to...
1921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com *  (1) get access a bitmap in the heap
2021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com *  (2) indicate they are done with bitmap by releasing their reference (if they were an owner).
2121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com */
2221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.comclass SkBitmapHeapEntry : SkNoncopyable {
2321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.compublic:
2421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    ~SkBitmapHeapEntry();
2521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
2621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    int32_t getSlot() { return fSlot; }
2721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
2821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    SkBitmap* getBitmap() { return &fBitmap; }
2921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
3021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    void releaseRef() {
3121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        sk_atomic_dec(&fRefCount);
3221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    }
3321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
3421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.comprivate:
3521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    SkBitmapHeapEntry();
3621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
3721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    void addReferences(int count);
3821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
3921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    int32_t fSlot;
4021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    int32_t fRefCount;
4121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
4221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    SkBitmap fBitmap;
4321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    // Keep track of the bytes allocated for this bitmap. When replacing the
4421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    // bitmap or removing this HeapEntry we know how much memory has been
4521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    // reclaimed.
4621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    size_t fBytesAllocated;
4721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
4821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    friend class SkBitmapHeap;
49013c5d9107a4abd50e879ca66cf60b0c3a8256d4scroggo@google.com    friend class SkBitmapHeapTester;
5021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com};
5121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
5221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
5321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.comclass SkBitmapHeapReader : public SkRefCnt {
5421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.compublic:
55a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com    SK_DECLARE_INST_COUNT(SkBitmapHeapReader)
56a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
5721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    SkBitmapHeapReader() : INHERITED() {}
5821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    virtual SkBitmap* getBitmap(int32_t slot) const = 0;
5921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    virtual void releaseRef(int32_t slot) = 0;
6021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.comprivate:
6121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    typedef SkRefCnt INHERITED;
6221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com};
6321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
6421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
6521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com/**
6621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com * TODO: stores immutable bitmaps into a heap
6721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com */
6821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.comclass SkBitmapHeap : public SkBitmapHeapReader {
6921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.compublic:
7021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    class ExternalStorage : public SkRefCnt {
7121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     public:
72a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        SK_DECLARE_INST_COUNT(ExternalStorage)
73a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
7421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        virtual bool insert(const SkBitmap& bitmap, int32_t slot) = 0;
75a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com
76a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com     private:
77a22e2117e44efa4298dd0eb6df304a8166c8e9c3robertphillips@google.com        typedef SkRefCnt INHERITED;
7821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    };
7921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
8021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    static const int32_t UNLIMITED_SIZE = -1;
8121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    static const int32_t IGNORE_OWNERS  = -1;
8221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    static const int32_t INVALID_SLOT   = -1;
8321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
8421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    /**
8521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Constructs a heap that is responsible for allocating and managing its own storage.  In the
8621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * case where we choose to allow the heap to grow indefinitely (i.e. UNLIMITED_SIZE) we
8721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * guarantee that once allocated in the heap a bitmap's index in the heap is immutable.
8821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Otherwise we guarantee the bitmaps placement in the heap until its owner count goes to zero.
8921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *
9021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @param preferredSize  Specifies the preferred maximum number of bitmaps to store. This is
9121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *   not a hard limit as it can grow larger if the number of bitmaps in the heap with active
9221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *   owners exceeds this limit.
9321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @param ownerCount  The number of owners to assign to each inserted bitmap. NOTE: while a
9421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *   bitmap in the heap has a least one owner it can't be removed.
9521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     */
9621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    SkBitmapHeap(int32_t preferredSize = UNLIMITED_SIZE, int32_t ownerCount = IGNORE_OWNERS);
9721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
9821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    /**
9921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Constructs a heap that defers the responsibility of storing the bitmaps to an external
10021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * function. This is especially useful if the bitmaps will be used in a separate process as the
10121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * external storage can ensure the data is properly shuttled to the appropriate processes.
10221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *
10321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Our LRU implementation assumes that inserts into the external storage are consumed in the
10421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * order that they are inserted (i.e. SkPipe). This ensures that we don't need to query the
10521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * external storage to see if a slot in the heap is eligible to be overwritten.
10621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *
10721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @param externalStorage  The class responsible for storing the bitmaps inserted into the heap
10821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @param heapSize  The maximum size of the heap. Because of the sequential limitation imposed
10921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *   by our LRU implementation we can guarantee that the heap will never grow beyond this size.
11021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     */
11121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    SkBitmapHeap(ExternalStorage* externalStorage, int32_t heapSize = UNLIMITED_SIZE);
11221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
113d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org    virtual ~SkBitmapHeap();
11421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
11521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    /**
11621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Retrieves the bitmap from the specified slot in the heap
11721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *
11821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @return  The bitmap located at that slot or NULL if external storage is being used.
11921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     */
12036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkBitmap* getBitmap(int32_t slot) const override {
12121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        SkASSERT(fExternalStorage == NULL);
12221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        SkBitmapHeapEntry* entry = getEntry(slot);
12321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        if (entry) {
12421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com            return &entry->fBitmap;
12521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        }
12621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        return NULL;
12721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    }
12821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
12921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    /**
13021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Retrieves the bitmap from the specified slot in the heap
13121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *
13221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @return  The bitmap located at that slot or NULL if external storage is being used.
13321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     */
13436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void releaseRef(int32_t slot) override {
13521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        SkASSERT(fExternalStorage == NULL);
13621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        if (fOwnerCount != IGNORE_OWNERS) {
13721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com            SkBitmapHeapEntry* entry = getEntry(slot);
13821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com            if (entry) {
13921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com                entry->releaseRef();
14021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com            }
14121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        }
14221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    }
14321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
14421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    /**
14521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Inserts a bitmap into the heap. The stored version of bitmap is guaranteed to be immutable
14621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * and is not dependent on the lifecycle of the provided bitmap.
14721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *
14821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @param bitmap  the bitmap to be inserted into the heap
14921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @return  the slot in the heap where the bitmap is stored or INVALID_SLOT if the bitmap could
15021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *          not be added to the heap. If it was added the slot will remain valid...
15121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *            (1) indefinitely if no owner count has been specified.
15221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *            (2) until all owners have called releaseRef on the appropriate SkBitmapHeapEntry*
15321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     */
15421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    int32_t insert(const SkBitmap& bitmap);
15521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
15621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    /**
15721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Retrieves an entry from the heap at a given slot.
15821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *
15921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @param slot  the slot in the heap where a bitmap was stored.
16021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @return  a SkBitmapHeapEntry that wraps the bitmap or NULL if external storage is used.
16121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     */
16221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    SkBitmapHeapEntry* getEntry(int32_t slot) const {
16321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        SkASSERT(slot <= fStorage.count());
16421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        if (fExternalStorage != NULL) {
16521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com            return NULL;
16621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        }
16721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        return fStorage[slot];
16821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    }
16921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
17021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    /**
17121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Returns a count of the number of items currently in the heap
17221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     */
17321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    int count() const {
1743e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        SkASSERT(fExternalStorage != NULL ||
1753e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com                 fStorage.count() - fUnusedSlots.count() == fLookupTable.count());
17621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        return fLookupTable.count();
17721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    }
17821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
17921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    /**
18021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Returns the total number of bytes allocated by the bitmaps in the heap
18121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     */
18221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    size_t bytesAllocated() const {
18321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        return fBytesAllocated;
18421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    }
18521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
18610dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    /**
18710dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com     * Attempt to reduce the storage allocated.
18810dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com     * @param bytesToFree minimum number of bytes that should be attempted to
18910dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com     *   be freed.
19010dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com     * @return number of bytes actually freed.
19110dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com     */
19210dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    size_t freeMemoryIfPossible(size_t bytesToFree);
19310dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com
1947ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com    /**
1957ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     * Defer any increments of owner counts until endAddingOwnersDeferral is called. So if an
1967ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     * existing SkBitmap is inserted into the SkBitmapHeap, its corresponding SkBitmapHeapEntry will
1977ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     * not have addReferences called on it, and the client does not need to make a corresponding
1987ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     * call to releaseRef. Only meaningful if this SkBitmapHeap was created with an owner count not
1997ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     * equal to IGNORE_OWNERS.
2007ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     */
2017ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com    void deferAddingOwners();
202fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2037ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com    /**
2047ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     * Resume adding references when duplicate SkBitmaps are inserted.
2057ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     * @param add If true, add references to the SkBitmapHeapEntrys whose SkBitmaps were re-inserted
2067ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     *            while deferring.
2077ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com     */
2087ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com    void endAddingOwnersDeferral(bool add);
209fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
21021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.comprivate:
21121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    struct LookupEntry {
2123e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        LookupEntry(const SkBitmap& bm)
2133e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        : fGenerationId(bm.getGenerationID())
214672588b684d484dce6ae251e9e163e4a46924322reed@google.com        , fPixelOrigin(bm.pixelRefOrigin())
2153e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        , fWidth(bm.width())
2163e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        , fHeight(bm.height())
2173e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        , fMoreRecentlyUsed(NULL)
2183e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        , fLessRecentlyUsed(NULL){}
2193e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com
2203e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        const uint32_t fGenerationId; // SkPixelRef GenerationID.
221672588b684d484dce6ae251e9e163e4a46924322reed@google.com        const SkIPoint fPixelOrigin;
2223e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        const uint32_t fWidth;
2233e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        const uint32_t fHeight;
2243e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com
2253e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        // TODO: Generalize the LRU caching mechanism
2263e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        LookupEntry* fMoreRecentlyUsed;
2273e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        LookupEntry* fLessRecentlyUsed;
22821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
22921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        uint32_t fStorageSlot; // slot of corresponding bitmap in fStorage.
23021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
2313e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com        /**
23220f7f173e05b60f541910d0c1da9850ac73e2958bsalomon@google.com         * Compare two LookupEntry pointers for sorting and searching.
2333e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com         */
23420f7f173e05b60f541910d0c1da9850ac73e2958bsalomon@google.com        static bool Less(const LookupEntry& a, const LookupEntry& b);
23521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    };
23621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
23721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    /**
2383e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * Remove the entry from the lookup table. Also deletes the entry pointed
2393e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * to by the table. Therefore, if a pointer to that one was passed in, the
2403e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * pointer should no longer be used, since the object to which it points has
2413e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * been deleted.
24210dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com     * @return The index in the lookup table of the entry before removal.
24310dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com     */
2443e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    int removeEntryFromLookupTable(LookupEntry*);
24510dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com
24610dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    /**
24721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * Searches for the bitmap in the lookup table and returns the bitmaps index within the table.
24821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * If the bitmap was not already in the table it is added.
24921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *
25010dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com     * @param key    The key to search the lookup table, created from a bitmap.
25121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     * @param entry  A pointer to a SkBitmapHeapEntry* that if non-null AND the bitmap is found
25221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     *               in the lookup table is populated with the entry from the heap storage.
25321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com     */
25410dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    int findInLookupTable(const LookupEntry& key, SkBitmapHeapEntry** entry);
25521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
2563e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    LookupEntry* findEntryToReplace(const SkBitmap& replacement);
25721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    bool copyBitmap(const SkBitmap& originalBitmap, SkBitmap& copiedBitmap);
2583e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com
2593e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    /**
2603e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * Remove a LookupEntry from the LRU, in preparation for either deleting or appending as most
2613e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * recent. Points the LookupEntry's old neighbors at each other, and sets fLeastRecentlyUsed
2623e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * (if there is still an entry left). Sets LookupEntry's fMoreRecentlyUsed to NULL and leaves
2633e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * its fLessRecentlyUsed unmodified.
2643e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     */
2653e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    void removeFromLRU(LookupEntry* entry);
2663e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com
2673e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    /**
2683e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * Append a LookupEntry to the end of the LRU cache, marking it as the most
2693e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * recently used. Assumes that the LookupEntry is already in fLookupTable,
2703e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * but is not in the LRU cache. If it is in the cache, removeFromLRU should
2713e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     * be called first.
2723e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com     */
2733e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    void appendToLRU(LookupEntry*);
27421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
27521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    // searchable index that maps to entries in the heap
2763e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    SkTDArray<LookupEntry*> fLookupTable;
27721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
27821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    // heap storage
27921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    SkTDArray<SkBitmapHeapEntry*> fStorage;
28010dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    // Used to mark slots in fStorage as deleted without actually deleting
28110dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    // the slot so as not to mess up the numbering.
28210dccde54a769b8d472bccf8c1993034b93ef58dscroggo@google.com    SkTDArray<int> fUnusedSlots;
28321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    ExternalStorage* fExternalStorage;
28421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
2853e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    LookupEntry* fMostRecentlyUsed;
2863e26bd0c357d849ff40b092decd7a5c46ec2ada4scroggo@google.com    LookupEntry* fLeastRecentlyUsed;
28721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
28821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    const int32_t fPreferredCount;
28921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    const int32_t fOwnerCount;
29021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    size_t fBytesAllocated;
29121830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
2927ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com    bool fDeferAddingOwners;
2937ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com    SkTDArray<int> fDeferredEntries;
2947ca24437c71af06fc06ab5f6f261b185882fa440scroggo@google.com
29521830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    typedef SkBitmapHeapReader INHERITED;
29621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com};
29721830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
29821830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com#endif // SkBitmapHeap_DEFINED
299