#include "Draw.h" NAMESPACE_UPP #define LLOG(x) // LOG(x) static StaticCriticalSection sMakeImage; static LRUCache& sImageCache() { static LRUCache m; return m; } struct scImageMaker : LRUCache::Maker { const ImageMaker *m; bool paintonly; virtual String Key() const { String q = m->Key(); return m->Key(); } virtual int Make(Image& object) const { object = m->Make(); if(paintonly) { SetPaintOnly___(object); return object.GetLength() + 20000; } return object.GetLength() + 100; } }; static int sMaxSize; static int sMaxSizeMax = 4000000; void SetMakeImageCacheMax(int m) { sMaxSizeMax = m; } void SetMakeImageCacheSize(int m) { sMaxSize = m; } void SweepMkImageCache() { INTERLOCKED_(sMakeImage) { LRUCache& cache = sImageCache(); cache.ClearCounters(); } } Image MakeImage__(const ImageMaker& m, bool paintonly) { Image result; INTERLOCKED_(sMakeImage) { LRUCache& cache = sImageCache(); scImageMaker cm; cm.m = &m; cm.paintonly = paintonly; result = cache.Get(cm); int q = min(cache.GetFoundSize() + cache.GetNewSize(), sMaxSizeMax); if(q > sMaxSize) { sMaxSize = q; LLOG("ImageCache: Increasing maxsize to " << sMaxSize); } cache.Shrink(sMaxSize); } return result; } Image MakeImage(const ImageMaker& m) { return MakeImage__(m, false); } Image MakeImagePaintOnly(const ImageMaker& m) { return MakeImage__(m, true); } class SimpleImageMaker : public ImageMaker { Image (*make)(const Image& image); Image image; public: virtual String Key() const; virtual Image Make() const; SimpleImageMaker(const Image& image, Image (*make)(const Image& image)) : make(make),image(image) {} }; String SimpleImageMaker::Key() const { String key; int64 k = image.GetSerialId(); key.Cat((const char *)&k, sizeof(int64)); key.Cat((const char *)&make, sizeof(make)); return key; } Image SimpleImageMaker::Make() const { return (*make)(image); } Image MakeImage(const Image& image, Image (*make)(const Image& image)) { return MakeImage(SimpleImageMaker(image, make)); } struct sCachedRescale : public ImageMaker { Rect src; Size sz; Image img; virtual String Key() const { StringBuffer h; RawCat(h, src.left); RawCat(h, src.top); RawCat(h, src.right); RawCat(h, src.bottom); RawCat(h, sz.cx); RawCat(h, sz.cy); RawCat(h, img.GetSerialId()); return h; } virtual Image Make() const { return Rescale(img, sz, src); } }; Image CachedRescale(const Image& m, Size sz, const Rect& src) { if(m.GetSize() == sz) return m; sCachedRescale cr; cr.sz = sz; cr.src = src; cr.img = m; return MakeImage(cr); } Image CachedRescale(const Image& m, Size sz) { return CachedRescale(m, sz, m.GetSize()); } Image CachedRescalePaintOnly(const Image& m, Size sz, const Rect& src) { if(m.GetSize() == sz) return m; sCachedRescale cr; cr.sz = sz; cr.src = src; cr.img = m; return MakeImagePaintOnly(cr); } Image CachedRescalePaintOnly(const Image& m, Size sz) { return CachedRescalePaintOnly(m, sz, m.GetSize()); } END_UPP_NAMESPACE