mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
171 lines
3 KiB
C++
171 lines
3 KiB
C++
#include "Draw.h"
|
|
|
|
NAMESPACE_UPP
|
|
|
|
#define LLOG(x) // LOG(x)
|
|
|
|
static StaticCriticalSection sMakeImage;
|
|
|
|
static LRUCache<Image>& sImageCache()
|
|
{
|
|
static LRUCache<Image> m;
|
|
return m;
|
|
}
|
|
|
|
struct scImageMaker : LRUCache<Image>::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<Image>& cache = sImageCache();
|
|
cache.ClearCounters();
|
|
}
|
|
}
|
|
|
|
Image MakeImage__(const ImageMaker& m, bool paintonly)
|
|
{
|
|
Image result;
|
|
INTERLOCKED_(sMakeImage) {
|
|
LRUCache<Image>& 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
|