blob: 91d233ac4a14acddf855bdc4fa907ef4f4c3235f [file] [log] [blame]
/*
* Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "FloatRect.h"
#include "Timer.h"
#include <CoreGraphics/CoreGraphics.h>
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>
#include <wtf/HashTraits.h>
#include <wtf/Lock.h>
#include <wtf/RetainPtr.h>
#include <wtf/RunLoop.h>
#define CACHE_SUBIMAGES 1
namespace WebCore {
#if CACHE_SUBIMAGES
class SubimageCacheWithTimer {
WTF_MAKE_NONCOPYABLE(SubimageCacheWithTimer); WTF_MAKE_FAST_ALLOCATED;
public:
struct SubimageCacheEntry {
RetainPtr<CGImageRef> image;
RetainPtr<CGImageRef> subimage;
FloatRect rect;
MonotonicTime lastAccessTime;
};
struct SubimageCacheEntryTraits : HashTraits<SubimageCacheEntry> {
typedef HashTraits<RetainPtr<CGImageRef>> ImageTraits;
static const bool emptyValueIsZero = true;
static const bool hasIsEmptyValueFunction = true;
static bool isEmptyValue(const SubimageCacheEntry& value) { return !value.image; }
static void constructDeletedValue(SubimageCacheEntry& slot) { ImageTraits::constructDeletedValue(slot.image); }
static bool isDeletedValue(const SubimageCacheEntry& value) { return ImageTraits::isDeletedValue(value.image); }
};
struct SubimageCacheHash {
static unsigned hash(CGImageRef image, const FloatRect& rect)
{
return pairIntHash(PtrHash<CGImageRef>::hash(image),
(static_cast<unsigned>(rect.x()) << 16) | static_cast<unsigned>(rect.y()));
}
static unsigned hash(const SubimageCacheEntry& key)
{
return hash(key.image.get(), key.rect);
}
static bool equal(const SubimageCacheEntry& a, const SubimageCacheEntry& b)
{
return a.image == b.image && a.rect == b.rect;
}
static const bool safeToCompareToEmptyOrDeleted = true;
};
static RetainPtr<CGImageRef> getSubimage(CGImageRef, const FloatRect&);
static void clearImage(CGImageRef);
static void clear();
private:
typedef HashSet<SubimageCacheEntry, SubimageCacheHash, SubimageCacheEntryTraits> SubimageCacheHashSet;
SubimageCacheWithTimer();
void pruneCacheTimerFired();
RetainPtr<CGImageRef> subimage(CGImageRef, const FloatRect&);
void clearImageAndSubimages(CGImageRef);
void prune() WTF_REQUIRES_LOCK(m_lock);
void clearAll();
Lock m_lock;
HashCountedSet<CGImageRef> m_imageCounts WTF_GUARDED_BY_LOCK(m_lock);
SubimageCacheHashSet m_cache WTF_GUARDED_BY_LOCK(m_lock);
RunLoop::Timer<SubimageCacheWithTimer> m_timer WTF_GUARDED_BY_LOCK(m_lock);
static SubimageCacheWithTimer& subimageCache();
static bool subimageCacheExists();
static SubimageCacheWithTimer* s_cache;
};
#endif // CACHE_SUBIMAGES
}