gfx/skia/trunk/src/effects/gradients/SkBitmapCache.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/effects/gradients/SkBitmapCache.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,153 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2010 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#include "SkBitmapCache.h"
    1.14 +
    1.15 +struct SkBitmapCache::Entry {
    1.16 +    Entry*      fPrev;
    1.17 +    Entry*      fNext;
    1.18 +
    1.19 +    void*       fBuffer;
    1.20 +    size_t      fSize;
    1.21 +    SkBitmap    fBitmap;
    1.22 +
    1.23 +    Entry(const void* buffer, size_t size, const SkBitmap& bm)
    1.24 +            : fPrev(NULL),
    1.25 +              fNext(NULL),
    1.26 +              fBitmap(bm) {
    1.27 +        fBuffer = sk_malloc_throw(size);
    1.28 +        fSize = size;
    1.29 +        memcpy(fBuffer, buffer, size);
    1.30 +    }
    1.31 +
    1.32 +    ~Entry() { sk_free(fBuffer); }
    1.33 +
    1.34 +    bool equals(const void* buffer, size_t size) const {
    1.35 +        return (fSize == size) && !memcmp(fBuffer, buffer, size);
    1.36 +    }
    1.37 +};
    1.38 +
    1.39 +SkBitmapCache::SkBitmapCache(int max) : fMaxEntries(max) {
    1.40 +    fEntryCount = 0;
    1.41 +    fHead = fTail = NULL;
    1.42 +
    1.43 +    this->validate();
    1.44 +}
    1.45 +
    1.46 +SkBitmapCache::~SkBitmapCache() {
    1.47 +    this->validate();
    1.48 +
    1.49 +    Entry* entry = fHead;
    1.50 +    while (entry) {
    1.51 +        Entry* next = entry->fNext;
    1.52 +        delete entry;
    1.53 +        entry = next;
    1.54 +    }
    1.55 +}
    1.56 +
    1.57 +SkBitmapCache::Entry* SkBitmapCache::detach(Entry* entry) const {
    1.58 +    if (entry->fPrev) {
    1.59 +        SkASSERT(fHead != entry);
    1.60 +        entry->fPrev->fNext = entry->fNext;
    1.61 +    } else {
    1.62 +        SkASSERT(fHead == entry);
    1.63 +        fHead = entry->fNext;
    1.64 +    }
    1.65 +    if (entry->fNext) {
    1.66 +        SkASSERT(fTail != entry);
    1.67 +        entry->fNext->fPrev = entry->fPrev;
    1.68 +    } else {
    1.69 +        SkASSERT(fTail == entry);
    1.70 +        fTail = entry->fPrev;
    1.71 +    }
    1.72 +    return entry;
    1.73 +}
    1.74 +
    1.75 +void SkBitmapCache::attachToHead(Entry* entry) const {
    1.76 +    entry->fPrev = NULL;
    1.77 +    entry->fNext = fHead;
    1.78 +    if (fHead) {
    1.79 +        fHead->fPrev = entry;
    1.80 +    } else {
    1.81 +        fTail = entry;
    1.82 +    }
    1.83 +    fHead = entry;
    1.84 +}
    1.85 +
    1.86 +bool SkBitmapCache::find(const void* buffer, size_t size, SkBitmap* bm) const {
    1.87 +    AutoValidate av(this);
    1.88 +
    1.89 +    Entry* entry = fHead;
    1.90 +    while (entry) {
    1.91 +        if (entry->equals(buffer, size)) {
    1.92 +            if (bm) {
    1.93 +                *bm = entry->fBitmap;
    1.94 +            }
    1.95 +            // move to the head of our list, so we purge it last
    1.96 +            this->detach(entry);
    1.97 +            this->attachToHead(entry);
    1.98 +            return true;
    1.99 +        }
   1.100 +        entry = entry->fNext;
   1.101 +    }
   1.102 +    return false;
   1.103 +}
   1.104 +
   1.105 +void SkBitmapCache::add(const void* buffer, size_t len, const SkBitmap& bm) {
   1.106 +    AutoValidate av(this);
   1.107 +
   1.108 +    if (fEntryCount == fMaxEntries) {
   1.109 +        SkASSERT(fTail);
   1.110 +        delete this->detach(fTail);
   1.111 +        fEntryCount -= 1;
   1.112 +    }
   1.113 +
   1.114 +    Entry* entry = SkNEW_ARGS(Entry, (buffer, len, bm));
   1.115 +    this->attachToHead(entry);
   1.116 +    fEntryCount += 1;
   1.117 +}
   1.118 +
   1.119 +///////////////////////////////////////////////////////////////////////////////
   1.120 +
   1.121 +#ifdef SK_DEBUG
   1.122 +
   1.123 +void SkBitmapCache::validate() const {
   1.124 +    SkASSERT(fEntryCount >= 0 && fEntryCount <= fMaxEntries);
   1.125 +
   1.126 +    if (fEntryCount > 0) {
   1.127 +        SkASSERT(NULL == fHead->fPrev);
   1.128 +        SkASSERT(NULL == fTail->fNext);
   1.129 +
   1.130 +        if (fEntryCount == 1) {
   1.131 +            SkASSERT(fHead == fTail);
   1.132 +        } else {
   1.133 +            SkASSERT(fHead != fTail);
   1.134 +        }
   1.135 +
   1.136 +        Entry* entry = fHead;
   1.137 +        int count = 0;
   1.138 +        while (entry) {
   1.139 +            count += 1;
   1.140 +            entry = entry->fNext;
   1.141 +        }
   1.142 +        SkASSERT(count == fEntryCount);
   1.143 +
   1.144 +        entry = fTail;
   1.145 +        while (entry) {
   1.146 +            count -= 1;
   1.147 +            entry = entry->fPrev;
   1.148 +        }
   1.149 +        SkASSERT(0 == count);
   1.150 +    } else {
   1.151 +        SkASSERT(NULL == fHead);
   1.152 +        SkASSERT(NULL == fTail);
   1.153 +    }
   1.154 +}
   1.155 +
   1.156 +#endif

mercurial