#include "GLDraw.h" #define LTIMING(x) // RTIMING(x) #define LLOG(x) // DLOG(x) namespace Upp { struct ImageGLData { Image img; GLuint texture_id; void Init(const Image& img, dword flags); ~ImageGLData(); }; void ImageGLData::Init(const Image& img_, dword flags) { LTIMING("CreateTexture"); Image img = img_; Size sz = img.GetSize(); glGenTextures(1, &texture_id); glBindTexture(GL_TEXTURE_2D, texture_id); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sz.cx, sz.cy, 0, GL_BGRA, GL_UNSIGNED_BYTE, ~img); if(flags & TEXTURE_MIPMAP) glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, flags & TEXTURE_LINEAR ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, flags & TEXTURE_LINEAR ? flags & TEXTURE_MIPMAP ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); LLOG("Texture id created: " << texture_id); SysImageRealized(img); } static LRUCache > sTextureCache; static bool sReset; ImageGLData::~ImageGLData() { SysImageReleased(img); if(!sReset) glDeleteTextures(1, &texture_id); LLOG("Texture id deleted: " << texture_id); } void GLDraw::ClearCache() { sReset = false; sTextureCache.Clear(); } void GLDraw::ResetCache() { sReset = true; sTextureCache.Clear(); sReset = false; } struct ImageGLDataMaker : LRUCache >::Maker { Image img; uint64 context; dword flags; virtual Tuple Key() const { return MakeTuple(img.GetSerialId(), context, flags); } virtual int Make(ImageGLData& object) const { object.Init(img, flags); return img.GetLength(); } }; int max_texture_memory = 4 * 1024 * 768; int max_texture_count = 1000; GLuint GetTextureForImage(dword flags, const Image& img, uint64 context) { sTextureCache.Shrink(max_texture_memory, max_texture_count); ImageGLDataMaker m; m.img = img; m.context = context; m.flags = flags; return sTextureCache.Get(m).texture_id; } };