Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

OglImageCache.h

Go to the documentation of this file.
00001 #ifndef OglGui_OglImageCache_h
00002 #define OglGui_OglImageCache_h
00003 
00004 /*
00005  ******************************************************************************
00006     OglGui::OglImageCache: Maintain a LRU list of OGLIMAGE * objects.
00007 
00008     The OglImageCache increments the refCount of each
00009     added OGLIMAGE*, adding these to the cache until the
00010     cache is full.
00011 
00012     When an OGLIMAGE* is added and the cache is full, the
00013     refCount of the Least Recently Used OGLIMAGE is decremented
00014     (resulting in its destruction when no others are referencing it)
00015     and its slot in the cache is replaced by the new OGLIMAGE*.
00016 
00017     Use AddNoScalingTextured(OGLIMAGE* im, int id) to reuse cached
00018     existing textures based on the noTexScaling speed-up feature of OGL.
00019     In this case an unused OGLIMAGE with the correct texture size
00020     is searched for in the cache. Its texture is re-used and the unused
00021     image is destroyed. (See mainDirImViewer3D for an example of use)
00022 
00023     NOTE: When an OGLIMAGE* is obtained from the cache, its refCount
00024     is incremented. Therefore, the caller must release the obtained
00025     OGLIMAGE* when it is no longer needed.
00026 
00027  ******************************************************************************
00028  *  Example Caller:
00029  ******************************************************************************
00030     main()
00031     {
00032         Init(100);
00033     }
00034 
00035     void Init(int size)
00036     {
00037         mOglImageCache = new OglGui::OglImageCache(size);
00038         RandomRead(10000, 1000);
00039     }
00040 
00041     void RandomRead(int n, int maxId)
00042     {
00043         for (int i=0; i<n; i++)
00044         {
00045             OGLIMAGE* oglIm = LoadImageIdx("../images", ABSRND(maxId));
00046             if (oglIm)
00047                 ReleaseOglImage(oglIm);
00048         }
00049     }
00050 
00051     OGLIMAGE* LoadImageIdx(char* path, int id)
00052     {
00053         OGLIMAGE* im;
00054         if (! (im = mOglImageCache->GetImage(id)) )
00055         {
00056             char buf[1024];
00057             sprintf(buf, "%s/image%d.png", path, id);
00058             if (im = OGLReadPNG(buf))
00059                 mOglImageCache->Add(im, id);
00060         }
00061         else
00062             printf("Cache hit for image%d\n", id);
00063         return im;
00064     }
00065 *******************************************************************************
00066 */
00067 
00068 #ifndef OGLIMAGE_H
00069 #include "Link/OGL/OGLImage.h"
00070 #endif
00071 
00072 #include <vector>
00073 #include <list>
00074 
00075 extern "C" {
00076 unsigned char        IsPower2( int num, int *nearest );
00077 }
00078 
00079 namespace OglGui {
00080 
00081 class OglImageCache
00082 {
00083 public:
00084     typedef std::pair<OGLIMAGE*, unsigned long long>       ImIdPair;
00085 
00086     OglImageCache(int size)
00087     {
00088         Init(size);
00089     }
00090 
00091     ~OglImageCache()
00092     {
00093         int sz = mImages.size();
00094         for (int i=0; i<sz; i++)
00095         {
00096             ImIdPair* p = mImages[i];
00097             if (p->first)
00098                 ReleaseOglImage(p->first);
00099             delete p;
00100         }
00101         mImages.clear();
00102     }
00103 
00104     OGLIMAGE* GetImage(unsigned long long id)
00105     {
00106         ImIdPair* imIdPair = GetImIdPair(id);
00107         if (imIdPair)
00108         {
00109             OGLIMAGE* oglIm = imIdPair->first;
00110             if (oglIm)
00111                 oglIm->refCount++;
00112             return oglIm;
00113         }
00114         return 0;
00115     }
00116 
00117     void AddNoScalingTextured(OGLIMAGE* im, unsigned long long id)
00118     {
00119         if (!im)
00120             return;
00121 
00122         int texW, texH;
00123         IsPower2(im->w, &texW);
00124         IsPower2(im->h, &texH);
00125 
00126         ImIdPair* p;
00127         if (!im->texture && (p = GetUnusedImIdPairWithTexSize(texW, texH))!=0)
00128         {
00129             OGLIMAGE* texIm = p->first;
00130             int tex = texIm->texture;
00131             texIm->texture = 0;
00132             ReleaseOglImage(texIm);
00133 
00134             im->texture = tex;
00135             im->refCount++;
00136 
00137             p->second = id;
00138             p->first  = im;
00139         }
00140         else
00141             Add(im, id);
00142 
00143         im->noTexScaling = 1;
00144         im->texW = texW;
00145         im->texH = texH;
00146         im->changed = 1;
00147     }
00148 
00149     void Add(OGLIMAGE* im, unsigned long long id, bool allowReplace=false)
00150     {
00151         ImIdPair* p = 0;
00152 
00153         if (allowReplace)
00154             p = GetImIdPair(id);
00155         if (!p)
00156             p = GetLRU();
00157         if (im)
00158             im->refCount++;
00159         if (p->first)
00160             ReleaseOglImage(p->first);
00161         p->first   = im;
00162         p->second  = id;
00163     }
00164 
00165 private:
00166 
00167     ImIdPair* GetImIdPair(unsigned long long id)
00168     {
00169         for (int i=0; i<mImages.size(); i++)
00170         {
00171             if (id == mImages[i]->second)
00172             {
00173                 UpdateLRU(i);
00174                 return mImages[i];
00175             }
00176         }
00177         return 0;
00178     }
00179 
00180     ImIdPair* GetUnusedImIdPairWithTexSize(int texW, int texH)
00181     {
00182         OGLIMAGE* im;
00183         for (int i=0; i<mImages.size(); i++)
00184         {
00185             if ((im = mImages[i]->first) && im->refCount==1 &&
00186                 im->texture && im->texW == texW && im->texH == texH)
00187             {
00188                 UpdateLRU(i);
00189                 return mImages[i];
00190             }
00191         }
00192         return 0;
00193     }
00194 
00195     void UpdateLRU(int index)
00196     {
00197         mLRU.remove(index);
00198         mLRU.push_back(index);
00199     }
00200 
00201     ImIdPair* GetLRU()
00202     {
00203         int item = mLRU.front();
00204         UpdateLRU(item);
00205         return mImages[item];
00206     }
00207 
00208     void Init(int size)
00209     {
00210         mCacheSize = size;
00211 
00212         for (int i=0; i<mCacheSize; i++)
00213         {
00214             mImages.push_back(new ImIdPair(0,-1));
00215             mLRU.push_back(i);
00216         }
00217     }
00218 
00219     std::list<int>            mLRU;
00220     std::vector<ImIdPair*>    mImages;
00221 
00222     int                       mCacheSize;
00223 };
00224 
00225 } // namespace OglGui
00226 
00227 #endif // OglGui_OglImageCache_h

Generated on Fri Mar 19 09:31:37 2010 for ImpalaSrc by  doxygen 1.5.1