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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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  */
    10 #include "SkBitmapCache.h"
    12 struct SkBitmapCache::Entry {
    13     Entry*      fPrev;
    14     Entry*      fNext;
    16     void*       fBuffer;
    17     size_t      fSize;
    18     SkBitmap    fBitmap;
    20     Entry(const void* buffer, size_t size, const SkBitmap& bm)
    21             : fPrev(NULL),
    22               fNext(NULL),
    23               fBitmap(bm) {
    24         fBuffer = sk_malloc_throw(size);
    25         fSize = size;
    26         memcpy(fBuffer, buffer, size);
    27     }
    29     ~Entry() { sk_free(fBuffer); }
    31     bool equals(const void* buffer, size_t size) const {
    32         return (fSize == size) && !memcmp(fBuffer, buffer, size);
    33     }
    34 };
    36 SkBitmapCache::SkBitmapCache(int max) : fMaxEntries(max) {
    37     fEntryCount = 0;
    38     fHead = fTail = NULL;
    40     this->validate();
    41 }
    43 SkBitmapCache::~SkBitmapCache() {
    44     this->validate();
    46     Entry* entry = fHead;
    47     while (entry) {
    48         Entry* next = entry->fNext;
    49         delete entry;
    50         entry = next;
    51     }
    52 }
    54 SkBitmapCache::Entry* SkBitmapCache::detach(Entry* entry) const {
    55     if (entry->fPrev) {
    56         SkASSERT(fHead != entry);
    57         entry->fPrev->fNext = entry->fNext;
    58     } else {
    59         SkASSERT(fHead == entry);
    60         fHead = entry->fNext;
    61     }
    62     if (entry->fNext) {
    63         SkASSERT(fTail != entry);
    64         entry->fNext->fPrev = entry->fPrev;
    65     } else {
    66         SkASSERT(fTail == entry);
    67         fTail = entry->fPrev;
    68     }
    69     return entry;
    70 }
    72 void SkBitmapCache::attachToHead(Entry* entry) const {
    73     entry->fPrev = NULL;
    74     entry->fNext = fHead;
    75     if (fHead) {
    76         fHead->fPrev = entry;
    77     } else {
    78         fTail = entry;
    79     }
    80     fHead = entry;
    81 }
    83 bool SkBitmapCache::find(const void* buffer, size_t size, SkBitmap* bm) const {
    84     AutoValidate av(this);
    86     Entry* entry = fHead;
    87     while (entry) {
    88         if (entry->equals(buffer, size)) {
    89             if (bm) {
    90                 *bm = entry->fBitmap;
    91             }
    92             // move to the head of our list, so we purge it last
    93             this->detach(entry);
    94             this->attachToHead(entry);
    95             return true;
    96         }
    97         entry = entry->fNext;
    98     }
    99     return false;
   100 }
   102 void SkBitmapCache::add(const void* buffer, size_t len, const SkBitmap& bm) {
   103     AutoValidate av(this);
   105     if (fEntryCount == fMaxEntries) {
   106         SkASSERT(fTail);
   107         delete this->detach(fTail);
   108         fEntryCount -= 1;
   109     }
   111     Entry* entry = SkNEW_ARGS(Entry, (buffer, len, bm));
   112     this->attachToHead(entry);
   113     fEntryCount += 1;
   114 }
   116 ///////////////////////////////////////////////////////////////////////////////
   118 #ifdef SK_DEBUG
   120 void SkBitmapCache::validate() const {
   121     SkASSERT(fEntryCount >= 0 && fEntryCount <= fMaxEntries);
   123     if (fEntryCount > 0) {
   124         SkASSERT(NULL == fHead->fPrev);
   125         SkASSERT(NULL == fTail->fNext);
   127         if (fEntryCount == 1) {
   128             SkASSERT(fHead == fTail);
   129         } else {
   130             SkASSERT(fHead != fTail);
   131         }
   133         Entry* entry = fHead;
   134         int count = 0;
   135         while (entry) {
   136             count += 1;
   137             entry = entry->fNext;
   138         }
   139         SkASSERT(count == fEntryCount);
   141         entry = fTail;
   142         while (entry) {
   143             count -= 1;
   144             entry = entry->fPrev;
   145         }
   146         SkASSERT(0 == count);
   147     } else {
   148         SkASSERT(NULL == fHead);
   149         SkASSERT(NULL == fTail);
   150     }
   151 }
   153 #endif

mercurial