00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_CSPLUGINCOMMON_RENDERMANAGER_TEXTURECACHE_H__
00020 #define __CS_CSPLUGINCOMMON_RENDERMANAGER_TEXTURECACHE_H__
00021
00026 #include "igraphic/image.h"
00027 #include "ivideo/texture.h"
00028 #include "ivideo/txtmgr.h"
00029
00030 #include "csutil/genericresourcecache.h"
00031
00032 struct iTextureHandle;
00033
00034 namespace CS
00035 {
00036 namespace RenderManager
00037 {
00038 namespace Implementation
00039 {
00043 struct TextureSizeConstraint
00044 {
00045 struct KeyType
00046 {
00047 int w, h;
00048 };
00049
00050 static bool IsEqual (const csRef<iTextureHandle>& t1,
00051 const csRef<iTextureHandle>& t2)
00052 {
00053 int tw1, th1, tw2, th2;
00054 t1->GetRendererDimensions (tw1, th1);
00055 t2->GetRendererDimensions (tw2, th2);
00056
00057 if ((tw1 == tw2) && (th1 == th2)) return true;
00058 return false;
00059 }
00060
00061 static bool IsLargerEqual (const csRef<iTextureHandle>& t1,
00062 const csRef<iTextureHandle>& t2)
00063 {
00064 int tw1, th1, tw2, th2;
00065 t1->GetRendererDimensions (tw1, th1);
00066 t2->GetRendererDimensions (tw2, th2);
00067
00068 return ((tw1 >= tw2) && (th1 >= th2));
00069 }
00070
00071 static bool IsEqual (const csRef<iTextureHandle>& t1,
00072 const KeyType& t2)
00073 {
00074 int tw1, th1;
00075 t1->GetRendererDimensions (tw1, th1);
00076
00077 if ((tw1 == t2.w) && (th1 == t2.h)) return true;
00078 return false;
00079 }
00080
00081 static bool IsLargerEqual (const csRef<iTextureHandle>& t1,
00082 const KeyType& t2)
00083 {
00084 int tw1, th1;
00085 t1->GetRendererDimensions (tw1, th1);
00086
00087 if ((tw1 >= t2.w) && (th1 >= t2.h)) return true;
00088 return false;
00089 }
00090
00091 static bool IsLargerEqual (const KeyType& t1,
00092 const csRef<iTextureHandle>& t2)
00093 {
00094 int tw2, th2;
00095 t2->GetRendererDimensions (tw2, th2);
00096
00097 if ((t1.w >= tw2) && (t1.h >= th2)) return true;
00098 return false;
00099 }
00100
00101 };
00102 }
00103
00115 template<
00116 typename ReuseCondition = CS::Utility::ResourceCache::ReuseConditionAfterTime<csTicks>,
00117 typename PurgeCondition = CS::Utility::ResourceCache::PurgeConditionAfterTime<csTicks> >
00118 class TextureCacheT
00119 {
00120 public:
00122 enum
00123 {
00128 tcacheExactSizeMatch = 1,
00135 tcachePowerOfTwo = 2
00136 };
00137
00150 TextureCacheT (csImageType imgtype, const char* format, int textureFlags,
00151 const char* texClass, uint options,
00152 const ReuseCondition& reuse =
00153 CS::Utility::ResourceCache::ReuseConditionAfterTime<uint> (),
00154 const PurgeCondition& purge =
00155 CS::Utility::ResourceCache::PurgeConditionAfterTime<uint> (10000)) : g3d (0),
00156 backend (reuse, purge),
00157 imgtype (imgtype),
00158 format (format), textureFlags (textureFlags), texClass (texClass),
00159 options (options)
00160 {
00161 backend.agedPurgeInterval = 5000;
00162 }
00163
00165 void SetG3D (iGraphics3D* g3d)
00166 {
00167 this->g3d = g3d;
00168 }
00169
00173 void Clear ()
00174 {
00175 backend.Clear ();
00176 }
00177
00182 void AdvanceFrame (csTicks currentTime)
00183 {
00184 backend.AdvanceTime (currentTime);
00185 }
00186
00193 iTextureHandle* QueryUnusedTexture (int width, int height,
00194 int& real_w, int& real_h)
00195 {
00196 Implementation::TextureSizeConstraint::KeyType queryKey;
00197 queryKey.w = width; queryKey.h = height;
00198 csRef<iTextureHandle>* tex = backend.Query (queryKey,
00199 (options & tcacheExactSizeMatch));
00200
00201 if (tex != 0)
00202 {
00203 (*tex)->GetRendererDimensions (real_w, real_h);
00204 return *tex;
00205 }
00206
00207 if (options & tcachePowerOfTwo)
00208 {
00209 width = csFindNearestPowerOf2 (width);
00210 height = csFindNearestPowerOf2 (height);
00211 }
00212 real_w = width;
00213 real_h = height;
00214
00215 CS_ASSERT_MSG("SetG3D () not called", g3d);
00216 csRef<iTextureHandle> newTex (
00217 g3d->GetTextureManager()->CreateTexture (
00218 width, height, imgtype, format, textureFlags));
00219 newTex->SetTextureClass (texClass);
00220
00221 backend.AddActive (newTex);
00222
00223 return newTex;
00224 }
00225
00230 iTextureHandle* QueryUnusedTexture (int width, int height)
00231 {
00232 int dummyW, dummyH;
00233 return QueryUnusedTexture (width, height, dummyW, dummyH);
00234 }
00235
00237 const char* GetFormat() const { return format; }
00239 int GetFlags() const { return textureFlags; }
00241 const char* GetClass() const { return texClass; }
00242
00247 void SetFormat (const char* format)
00248 {
00249 this->format = format;
00250 Clear();
00251 }
00256 void SetFlags (int flags)
00257 {
00258 textureFlags = flags;
00259 Clear();
00260 }
00265 void SetClass (const char* texClass)
00266 {
00267 this->texClass = texClass;
00268 Clear();
00269 }
00270 protected:
00271 csRef<iGraphics3D> g3d;
00272
00273 CS::Utility::GenericResourceCache<csRef<iTextureHandle>,
00274 csTicks, Implementation::TextureSizeConstraint,
00275 ReuseCondition, PurgeCondition> backend;
00276
00277 csImageType imgtype;
00278 csString format;
00279 int textureFlags;
00280 csString texClass;
00281 uint options;
00282 };
00283
00285 typedef TextureCacheT<> TextureCache;
00286 }
00287 }
00288
00289 #endif // __CS_CSPLUGINCOMMON_RENDERMANAGER_TEXTURECACHE_H__