
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkImageRefPool.h"
#include "SkImageRef.h"
#include "SkThread.h"

SkImageRefPool::SkImageRefPool() {
    fRAMBudget = 0; // means no explicit limit
    fRAMUsed = 0;
    fCount = 0;
    fHead = fTail = NULL;
}

SkImageRefPool::~SkImageRefPool() {
    //    SkASSERT(NULL == fHead);
}

void SkImageRefPool::setRAMBudget(size_t size) {
    if (fRAMBudget != size) {
        fRAMBudget = size;
        this->purgeIfNeeded();
    }
}

void SkImageRefPool::justAddedPixels(SkImageRef* ref) {
#ifdef DUMP_IMAGEREF_LIFECYCLE
    SkDebugf("=== ImagePool: add pixels %s [%d %d %d] bytes=%d heap=%d\n",
             ref->getURI(),
             ref->fBitmap.width(), ref->fBitmap.height(),
             ref->fBitmap.bytesPerPixel(),
             ref->fBitmap.getSize(), (int)fRAMUsed);
#endif
    fRAMUsed += ref->ramUsed();
    this->purgeIfNeeded();
}

void SkImageRefPool::canLosePixels(SkImageRef* ref) {
    // the refs near fHead have recently been released (used)
    // if we purge, we purge from the tail
    this->detach(ref);
    this->addToHead(ref);
    this->purgeIfNeeded();
}

void SkImageRefPool::purgeIfNeeded() {
    // do nothing if we have a zero-budget (i.e. unlimited)
    if (fRAMBudget != 0) {
        this->setRAMUsed(fRAMBudget);
    }
}

void SkImageRefPool::setRAMUsed(size_t limit) {
    SkImageRef* ref = fTail;
    
    while (NULL != ref && fRAMUsed > limit) {
        // only purge it if its pixels are unlocked
        if (0 == ref->getLockCount() && ref->fBitmap.getPixels()) {
            size_t size = ref->ramUsed();
            SkASSERT(size <= fRAMUsed);
            fRAMUsed -= size;

#ifdef DUMP_IMAGEREF_LIFECYCLE
            SkDebugf("=== ImagePool: purge %s [%d %d %d] bytes=%d heap=%d\n",
                     ref->getURI(),
                     ref->fBitmap.width(), ref->fBitmap.height(),
                     ref->fBitmap.bytesPerPixel(),
                     (int)size, (int)fRAMUsed);
#endif
            
            // remember the bitmap config (don't call reset),
            // just clear the pixel memory
            ref->fBitmap.setPixels(NULL);
            SkASSERT(NULL == ref->fBitmap.getPixels());
        }
        ref = ref->fPrev;
    }
}

///////////////////////////////////////////////////////////////////////////////

void SkImageRefPool::addToHead(SkImageRef* ref) {
    ref->fNext = fHead;
    ref->fPrev = NULL;
    
    if (fHead) {
        SkASSERT(NULL == fHead->fPrev);
        fHead->fPrev = ref;
    }
    fHead = ref;
    
    if (NULL == fTail) {
        fTail = ref;
    }
    fCount += 1;
    SkASSERT(computeCount() == fCount);
    
    fRAMUsed += ref->ramUsed();
}

void SkImageRefPool::addToTail(SkImageRef* ref) {
    ref->fNext = NULL;
    ref->fPrev = fTail;
    
    if (fTail) {
        SkASSERT(NULL == fTail->fNext);
        fTail->fNext = ref;
    }
    fTail = ref;
    
    if (NULL == fHead) {
        fHead = ref;
    }
    fCount += 1;
    SkASSERT(computeCount() == fCount);
    
    fRAMUsed += ref->ramUsed();
}

void SkImageRefPool::detach(SkImageRef* ref) {
    SkASSERT(fCount > 0);
    
    if (fHead == ref) {
        fHead = ref->fNext;
    }
    if (fTail == ref) {
        fTail = ref->fPrev;
    }
    if (ref->fPrev) {
        ref->fPrev->fNext = ref->fNext;
    }
    if (ref->fNext) {
        ref->fNext->fPrev = ref->fPrev;
    }
    
    ref->fNext = ref->fPrev = NULL;
    
    fCount -= 1;
    SkASSERT(computeCount() == fCount);
    
    SkASSERT(fRAMUsed >= ref->ramUsed());
    fRAMUsed -= ref->ramUsed();
}

int SkImageRefPool::computeCount() const {
    SkImageRef* ref = fHead;
    int count = 0;
    
    while (ref != NULL) {
        count += 1;
        ref = ref->fNext;
    }
    
#ifdef SK_DEBUG
    ref = fTail;
    int count2 = 0;
    
    while (ref != NULL) {
        count2 += 1;
        ref = ref->fPrev;
    }
    SkASSERT(count2 == count);
#endif
    
    return count;
}

///////////////////////////////////////////////////////////////////////////////

#include "SkStream.h"

void SkImageRefPool::dump() const {
#if defined(SK_DEBUG) || defined(DUMP_IMAGEREF_LIFECYCLE)
    SkDebugf("ImagePool dump: bugdet: %d used: %d count: %d\n",
             (int)fRAMBudget, (int)fRAMUsed, fCount);
    
    SkImageRef* ref = fHead;
    
    while (ref != NULL) {
        SkDebugf("  [%3d %3d %d] ram=%d data=%d locks=%d %s\n", ref->fBitmap.width(),
                 ref->fBitmap.height(), ref->fBitmap.config(),
                 ref->ramUsed(), (int)ref->fStream->getLength(),
                 ref->getLockCount(), ref->getURI());
        
        ref = ref->fNext;
    }
#endif
}

