コード例 #1
0
const ScaledImageFragment* ImageDecodingStore::insertAndLockCache(const ImageFrameGenerator* generator, PassOwnPtr<ScaledImageFragment> image)
{
    // Prune old cache entries to give space for the new one.
    prune();

    ScaledImageFragment* newImage = image.get();
    OwnPtr<ImageCacheEntry> newCacheEntry = ImageCacheEntry::createAndUse(generator, image);
    Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete;
    {
        MutexLocker lock(m_mutex);

        ImageCacheMap::iterator iter = m_imageCacheMap.find(newCacheEntry->cacheKey());

        // It is rare but possible that the key of a new cache entry is found.
        // This happens if the generation ID of the image object wraps around.
        // In this case we will try to return the existing cached object and
        // discard the new cache object.
        if (iter != m_imageCacheMap.end()) {
            const ScaledImageFragment* oldImage;
            if (lockCacheEntryInternal(iter->value.get(), &oldImage, &cacheEntriesToDelete)) {
                newCacheEntry->decrementUseCount();
                return oldImage;
            }
        }

        // The new image is not locked yet so do it here.
        newImage->bitmap().lockPixels();
        insertCacheInternal(newCacheEntry.release(), &m_imageCacheMap, &m_imageCacheKeyMap);
    }
    return newImage;
}
コード例 #2
0
bool ImageDecodingStore::lockCacheEntryInternal(ImageCacheEntry* cacheEntry, const ScaledImageFragment** cachedImage, Vector<OwnPtr<CacheEntry> >* deletionList)
{
    ScaledImageFragment* image = cacheEntry->cachedImage();

    image->bitmap().lockPixels();

    // Memory for this image entry might be discarded already.
    // In this case remove the entry.
    if (!image->bitmap().getPixels()) {
        image->bitmap().unlockPixels();
        removeFromCacheInternal(cacheEntry, &m_imageCacheMap, &m_imageCacheKeyMap, deletionList);
        removeFromCacheListInternal(*deletionList);
        return false;
    }
    cacheEntry->incrementUseCount();
    *cachedImage = image;
    return true;
}
コード例 #3
0
const ScaledImageFragment* ImageDecodingStore::insertAndLockCache(const ImageFrameGenerator* generator, PassOwnPtr<ScaledImageFragment> image, PassOwnPtr<ImageDecoder> decoder)
{
    // Prune old cache entries to give space for the new one.
    prune();

    ScaledImageFragment* cachedImage = image.get();
    OwnPtr<CacheEntry> newCacheEntry;

    // ImageDecoder is not used any more if cache is complete.
    if (image->isComplete())
        newCacheEntry = CacheEntry::createAndUse(generator, image);
    else
        newCacheEntry = CacheEntry::createAndUse(generator, image, decoder);

    MutexLocker lock(m_mutex);
    // Lock the underlying SkBitmap to prevent it from being purged.
    cachedImage->bitmap().lockPixels();
    ASSERT(!m_cacheMap.contains(newCacheEntry->cacheKey()));
    insertCacheInternal(newCacheEntry.release());
    return cachedImage;
}
コード例 #4
0
bool ImageDecodingStore::lockCache(const ImageFrameGenerator* generator, const SkISize& scaledSize, CacheCondition condition, const ScaledImageFragment** cachedImage, ImageDecoder** decoder)
{
    ASSERT(cachedImage);

    CacheEntry* cacheEntry = 0;
    Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete;
    {
        MutexLocker lock(m_mutex);
        CacheMap::iterator iter = m_cacheMap.find(std::make_pair(generator, scaledSize));
        if (iter == m_cacheMap.end())
            return false;
        cacheEntry = iter->value.get();
        ScaledImageFragment* image = cacheEntry->cachedImage();
        if (condition == CacheMustBeComplete && !image->isComplete())
            return false;

        // Incomplete cache entry cannot be used more than once.
        ASSERT(image->isComplete() || !cacheEntry->useCount());

        image->bitmap().lockPixels();
        if (image->bitmap().getPixels()) {
            // Increment use count such that it doesn't get evicted.
            cacheEntry->incrementUseCount();

            // Complete cache entry doesn't have a decoder.
            ASSERT(!image->isComplete() || !cacheEntry->cachedDecoder());

            if (decoder)
                *decoder = cacheEntry->cachedDecoder();
            *cachedImage = image;
        } else {
            image->bitmap().unlockPixels();
            removeFromCacheInternal(cacheEntry, &cacheEntriesToDelete);
            removeFromCacheListInternal(cacheEntriesToDelete);
            return false;
        }
    }

    return true;
}