bitmapcache.cpp

Go to the documentation of this file.
00001 // $Id: bitmapcache.cpp 1282 2006-06-09 09:46:49Z alex $
00002 // BitmapCache.cpp: implementation of the CBitmapCache class.
00003 //
00005 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00006 ================================XARAHEADERSTART===========================
00007  
00008                Xara LX, a vector drawing and manipulation program.
00009                     Copyright (C) 1993-2006 Xara Group Ltd.
00010        Copyright on certain contributions may be held in joint with their
00011               respective authors. See AUTHORS file for details.
00012 
00013 LICENSE TO USE AND MODIFY SOFTWARE
00014 ----------------------------------
00015 
00016 This file is part of Xara LX.
00017 
00018 Xara LX is free software; you can redistribute it and/or modify it
00019 under the terms of the GNU General Public License version 2 as published
00020 by the Free Software Foundation.
00021 
00022 Xara LX and its component source files are distributed in the hope
00023 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00024 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00025 See the GNU General Public License for more details.
00026 
00027 You should have received a copy of the GNU General Public License along
00028 with Xara LX (see the file GPL in the root directory of the
00029 distribution); if not, write to the Free Software Foundation, Inc., 51
00030 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00031 
00032 
00033 ADDITIONAL RIGHTS
00034 -----------------
00035 
00036 Conditional upon your continuing compliance with the GNU General Public
00037 License described above, Xara Group Ltd grants to you certain additional
00038 rights. 
00039 
00040 The additional rights are to use, modify, and distribute the software
00041 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00042 library and any other such library that any version of Xara LX relased
00043 by Xara Group Ltd requires in order to compile and execute, including
00044 the static linking of that library to XaraLX. In the case of the
00045 "CDraw" library, you may satisfy obligation under the GNU General Public
00046 License to provide source code by providing a binary copy of the library
00047 concerned and a copy of the license accompanying it.
00048 
00049 Nothing in this section restricts any of the rights you have under
00050 the GNU General Public License.
00051 
00052 
00053 SCOPE OF LICENSE
00054 ----------------
00055 
00056 This license applies to this program (XaraLX) and its constituent source
00057 files only, and does not necessarily apply to other Xara products which may
00058 in part share the same code base, and are subject to their own licensing
00059 terms.
00060 
00061 This license does not apply to files in the wxXtra directory, which
00062 are built into a separate library, and are subject to the wxWindows
00063 license contained within that directory in the file "WXXTRA-LICENSE".
00064 
00065 This license does not apply to the binary libraries (if any) within
00066 the "libs" directory, which are subject to a separate license contained
00067 within that directory in the file "LIBS-LICENSE".
00068 
00069 
00070 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00071 ----------------------------------------------
00072 
00073 Subject to the terms of the GNU Public License (see above), you are
00074 free to do whatever you like with your modifications. However, you may
00075 (at your option) wish contribute them to Xara's source tree. You can
00076 find details of how to do this at:
00077   http://www.xaraxtreme.org/developers/
00078 
00079 Prior to contributing your modifications, you will need to complete our
00080 contributor agreement. This can be found at:
00081   http://www.xaraxtreme.org/developers/contribute/
00082 
00083 Please note that Xara will not accept modifications which modify any of
00084 the text between the start and end of this header (marked
00085 XARAHEADERSTART and XARAHEADEREND).
00086 
00087 
00088 MARKS
00089 -----
00090 
00091 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00092 designs are registered or unregistered trademarks, design-marks, and/or
00093 service marks of Xara Group Ltd. All rights in these marks are reserved.
00094 
00095 
00096       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00097                         http://www.xara.com/
00098 
00099 =================================XARAHEADEREND============================
00100  */
00101 
00102 #include "camtypes.h"
00103 
00104 //#include "bitmapcache.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00105 
00106 /*********************************************************************************************
00107 
00108     Preference: Percentage of RAM devoted to cache
00109     Section:    Cacheing
00110     Range:      0 - 100 (although greater values are acceptable)
00111     Purpose:    How much RAM to devote to cacheing bitmaps
00112     SeeAlso:    -
00113 
00114 **********************************************************************************************/ 
00115 INT32 CBitmapCache::CacheRAMPercent = 25;       // 25% of free RAM or 25% of half total RAM
00116 
00117 
00118 UINT32 AFXAPI HashKey(const CBitmapCacheKey& key)
00119 {
00120     return key.Hash();
00121 }
00122 
00123 
00124 
00125 
00127 // Construction/Destruction
00129 
00130 CBitmapCache::CBitmapCache()
00131 {
00132     m_lMaxDataSize = 0;
00133     m_lCurrentDataSize = 0;
00134     m_lMaxHashTableLoad = 0;
00135 }
00136 
00137 
00138 
00139 
00140 /********************************************************************************************
00141 
00142 >   UINT32 CBitmapCache::Initialise()
00143 
00144     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00145     Created:    11/06/2004
00146     Inputs:     -
00147     Outputs:    -
00148     Returns:    -
00149     Purpose:    -
00150     Errors:     -
00151     SeeAlso:    -
00152 
00153 ********************************************************************************************/
00154 void CBitmapCache::Initialise()
00155 {
00156     // Declare the section that the magnetic options will live in
00157     BOOL Worked = Camelot.DeclareSection(TEXT("Cache"), 2);
00158 
00159     // declare the 2 prefs that there are
00160     if (Worked) Camelot.DeclarePref(TEXT("Cache"), TEXT("CacheRAMPercent"), &CacheRAMPercent, 0, 200);
00161 
00162     // Set up the default maximum cache size
00163     m_lMaxDataSize = CalcRecommendedMaximumDataSize();
00164 TRACEUSER( "Phil", _T("Recommended Cache Size = %I64d\n"), m_lMaxDataSize);
00165 
00166     // Make the hash table big enough for however many average 80*80*32BPP pixel bitmaps
00167     // will fit into the configured maximum cache size. Make the hash table twice that size
00168     // to keep it sparse and thus running more efficiently and ensure that it's prime.
00169     m_lMaxHashTableLoad = (UINT32) m_lMaxDataSize/(80*80*4);
00170 //  InitHashTable(PrimeAbove(m_lMaxHashTableLoad*2), TRUE);
00171 }
00172 
00173 
00174 
00175 
00176 /********************************************************************************************
00177 
00178 >   void CBitmapCache::DeInitialise()
00179 
00180     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00181     Created:    18/06/2004
00182     Inputs:     -
00183     Outputs:    -
00184     Returns:    -
00185     Purpose:    -
00186     Errors:     -
00187     SeeAlso:    -
00188 
00189 ********************************************************************************************/
00190 void CBitmapCache::DeInitialise()
00191 {
00192     // Get rid of all cached bitmaps...
00193 /*  POSITION pos = GetStartPosition();
00194     while (pos)
00195     {
00196         CBitmapCacheKey key;
00197         CCachedBitmap bitmap;
00198         GetNextAssoc(pos, key, bitmap);
00199 
00200         RemoveKey(key);
00201         m_lCurrentDataSize -= bitmap.GetBitmapSize();
00202         FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits);
00203     }
00204 */  CCacheKeyMap::iterator pos;
00205     for ( pos=m_map.begin() ; pos!=m_map.end() ; pos++ )
00206     {
00207         CBitmapCacheKey key = pos->first;
00208         CCachedBitmap bitmap = pos->second;
00209 //      m_map.erase(key);
00210         m_lCurrentDataSize -= bitmap.GetBitmapSize();
00211         FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits);
00212     }
00213     m_map.clear();
00214 }
00215 
00216 
00217 
00218 
00219 /********************************************************************************************
00220 
00221 >   void CBitmapCache::RemoveLowPriorityBitmaps(const INT32 maxpriority = CACHEPRIORITY_TEMPBITMAP_HIGH)
00222 
00223     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00224     Created:    15/09/2004
00225     Inputs:     -
00226     Outputs:    -
00227     Returns:    -
00228     Purpose:    -
00229     Errors:     -
00230     SeeAlso:    -
00231 
00232 ********************************************************************************************/
00233 void CBitmapCache::RemoveLowPriorityBitmaps(const INT32 maxpriority)
00234 {
00235     // Get rid of all cached bitmaps...
00236 /*  POSITION pos = GetStartPosition();
00237     while (pos)
00238     {
00239         CBitmapCacheKey key;
00240         CCachedBitmap bitmap;
00241         GetNextAssoc(pos, key, bitmap);
00242 
00243         if (bitmap.nPriority <= maxpriority)
00244         {
00245             RemoveKey(key);
00246             m_lCurrentDataSize -= bitmap.GetBitmapSize();
00247             FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits);
00248         }
00249     }
00250 */  CCacheKeyMap::iterator pos;
00251     for ( pos=m_map.begin() ; pos!=m_map.end() ; )
00252     {
00253         CBitmapCacheKey key = pos->first;
00254         CCachedBitmap bitmap = pos->second;
00255         pos++;
00256         if (bitmap.nPriority <= maxpriority)
00257         {
00258             m_map.erase(key);
00259             m_lCurrentDataSize -= bitmap.GetBitmapSize();
00260             FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits);
00261         }
00262     }
00263 }
00264 
00265 
00266 
00267 
00268 /********************************************************************************************
00269 
00270 >   UINT32 CBitmapCache::StoreBitmap()
00271 
00272     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00273     Created:    11/06/2004
00274     Inputs:     key
00275                 Bitmap
00276     Outputs:    -
00277     Returns:    -
00278     Purpose:    Places a bitmap in the cache (making room if necessary by removing others)
00279     Errors:     -
00280     SeeAlso:    -
00281 
00282 ********************************************************************************************/
00283 void CBitmapCache::StoreBitmap(const CBitmapCacheKey& key, const CCachedBitmap& bitmap)
00284 {
00285 /*
00286 #if _DEBUG
00287     if ((UINT32)m_nCount >= m_lMaxHashTableLoad)
00288     {
00289         TRACE( _T("BitmapCache hash table moving into inefficient zone!\n"));
00290 //      ERROR3("BitmapCache hash table moving into inefficient zone\n");
00291     }
00292 #endif
00293 */
00294 //  ENSURE(bitmap.rectCachedRect.IsValid(), "Invalid rect in CBitmapCache::StoreBitmap");
00295     ENSURE(bitmap.pbmpInfo->bmiHeader.biCompression==BI_RGB || bitmap.pbmpInfo->bmiHeader.biCompression==0x80000001,
00296             "Invalid compression type in StoreBitmap");
00297 
00298     // Remove the previous entry for this key, if there was one...
00299     CCachedBitmap cbmp = RemoveBitmap(key);                                 // Watch out - doesn't release bitmap memory!
00300     if (bitmap.pbmpBits!=cbmp.pbmpBits && bitmap.pbmpInfo!=cbmp.pbmpInfo)   // Only release the bitmap if we're not still using it
00301         cbmp.Release();                                                     // But this does!
00302 
00303     UINT32 newitemsize = bitmap.GetBitmapSize();
00304     UINT32 priority = bitmap.nPriority;
00305     while ((UINT64)(m_lCurrentDataSize+newitemsize) > m_lMaxDataSize)
00306     {
00307         CCachedBitmap cbmp = RemoveRandomBitmap(priority);                  // Remove random bitmap from cache
00308         if (cbmp.IsValid())
00309         {
00310             ERROR3IF(bitmap.pbmpInfo==cbmp.pbmpInfo || bitmap.pbmpBits==cbmp.pbmpBits,
00311                      "RemoveRandomBitmap found the same bitmap we're trying to Store! Something's gone horribly wrong!\n");
00312             TRACE( _T("Removing bitmap to make room in cache!\n") );
00313             cbmp.Release();
00314         }
00315         else
00316         {
00317             // We have run out of room in the cache for this priority level
00318             TRACEUSER( "Phil", _T("Changing priority to make room in cache\n"));
00319             if (priority < CACHEPRIORITY_TEMPBITMAP_HIGH)
00320             {
00321                 // We can try to remove higher-priority temp bitmaps...
00322                 // (But not the very highest, permanent bitmaps...)
00323                 priority = CACHEPRIORITY_TEMPBITMAP_HIGH;
00324             }
00325             else
00326             {
00327                 // We have no more room to remove any temporary bitmaps
00328                 // ARGH!!!! Now what?
00329                 ERROR3("Bitmap Cache is full!");
00330                 break;                  // Just gobble up the user's memory!
00331             }
00332         }
00333     }
00334 
00335     m_lCurrentDataSize += newitemsize;
00336 //  SetAt(key, (CCachedBitmap)bitmap);
00337     m_map.insert(pair<CBitmapCacheKey, CCachedBitmap>(key,(CCachedBitmap)bitmap));
00338 }
00339 
00340 
00341 
00342 
00343 /********************************************************************************************
00344 
00345 >   CCachedBitmap CBitmapCache::RemoveBitmap(const CBitmapCacheKey& key)
00346 
00347     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00348     Created:    11/06/2004
00349     Inputs:     key
00350     Outputs:    -
00351     Returns:    Pointer to bitmap or NULL if not found
00352     Purpose:    Removes either the specified bitmap from the cache or a selected bitmap
00353                 according to the removal policy
00354                 NOTE! It's up to the caller to delete the bitmap returned!!!
00355     Errors:     -
00356     SeeAlso:    -
00357 
00358 ********************************************************************************************/
00359 CCachedBitmap CBitmapCache::RemoveBitmap(const CBitmapCacheKey& key)
00360 {
00361     CCachedBitmap bitmap;
00362 
00363     if (m_map.size()==0)
00364             return bitmap;
00365 
00366     if (key.IsValid())
00367     {
00368         // Then we must remove the specified bitmap from the cache
00369         if (Lookup(key, bitmap))
00370         {
00371             m_lCurrentDataSize -= bitmap.GetBitmapSize();
00372             m_map.erase(key);
00373 //          RemoveKey(key);
00374         }
00375     }
00376 
00377     return bitmap;
00378 }
00379 
00380 
00381 
00382 
00383 /********************************************************************************************
00384 
00385 >   CCachedBitmap CBitmapCache::RemoveRandomBitmap(const INT32 maxpriority = CACHEPRIORITY_TEMPBITMAP_HIGH)
00386 
00387     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00388     Created:    11/06/2004
00389     Inputs:     key
00390     Outputs:    -
00391     Returns:    Pointer to bitmap or NULL if not found
00392     Purpose:    Removes either the specified bitmap from the cache or a selected bitmap
00393                 according to the removal policy
00394                 NOTE! It's up to the caller to delete the bitmap returned!!!
00395                 NOTE! This routine only uses the primary association array of the hash table
00396                         The chains of values stored in the same slot are ignored at first
00397                         (but obviously will be considered later on if their head item
00398                         has been removed)
00399     Errors:     -
00400     SeeAlso:    -
00401 
00402 ********************************************************************************************/
00403 CCachedBitmap CBitmapCache::RemoveRandomBitmap(const INT32 maxpriority)
00404 {
00405 //  ENSURE(m_nHashTableSize!=0, "Zero-sized hash table found in RemoveRandomBitmap\n");
00406 /*
00407     // Implement cache removal policy - remove a random bitmap
00408     //
00409     // Select a bitmap of our choosing for removal
00410     // The removal policy is random (ish)
00411     // Must be Order(0) complexity
00412     //
00413     CCachedBitmap bitmap;
00414 
00415 
00416     UINT32 startitem = rand() % m_nHashTableSize;
00417     UINT32 item = startitem;
00418     CAssoc* pAssoc = NULL;
00419     do
00420     {
00421         pAssoc = m_pHashTable[item];
00422         item++;
00423         if (item==m_nHashTableSize)
00424             item = 0;
00425 
00426         // If we have found a value, check whether it's of equal or lesser "value"
00427         // than the one we're trying to store before throwing it out...
00428         if (pAssoc)
00429         {
00430 //          bitmap = (CCachedBitmap)pAssoc->value;      // Get value in a form we can use
00431             if (((CCachedBitmap)pAssoc->value).nPriority <= maxpriority)        // Check whether value's priority is <= priority limit
00432                 break;                                  // If so, we'll get rid of this one
00433             else
00434                 pAssoc = NULL;
00435         }
00436     }
00437     while (item != startitem);
00438 
00439     if (pAssoc)
00440     {
00441         // Remove the bitmap that we found from the cache...
00442         bitmap = (CCachedBitmap)pAssoc->value;
00443         m_lCurrentDataSize -= bitmap.GetBitmapSize();
00444         RemoveKey(pAssoc->key);
00445     }
00446 
00447     return bitmap;
00448 */
00449     // Implement cache removal policy - remove a random bitmap
00450     //
00451     // Select a bitmap of our choosing for removal
00452     // The removal policy is random (ish)
00453     // Must be Order(0) complexity
00454     //
00455     // Pick a random start point iterate
00456     // through the map from there...
00457     //
00458     srand((unsigned)time(NULL));
00459     UINT32 item = rand()%(UINT32)m_map.size();
00460     CCacheKeyMap::iterator pos;
00461     for ( pos=m_map.begin() ; item-- ; pos++ )
00462         ;
00463     CCacheKeyMap::iterator spos = pos;
00464     do
00465     {
00466         if ( pos==m_map.end() )
00467             pos = m_map.begin() ;
00468         CBitmapCacheKey key = pos->first;
00469         CCachedBitmap bitmap = pos->second;
00470         if ( bitmap.nPriority<=maxpriority )        // Check whether value's priority is <= priority limit
00471         {
00472             m_lCurrentDataSize -= bitmap.GetBitmapSize();
00473             m_map.erase(key);
00474             return bitmap;
00475         }
00476         pos++;
00477     } while ( pos!=spos );
00478     return m_map.begin()->second;
00479 }
00480 
00481     
00482     
00483 
00484 /********************************************************************************************
00485 
00486 >   BOOL CBitmapCache::RemoveAllOwnedBitmaps(const CBitmapCacheKey& key,
00487                                             const BOOL bOpaqueOnly,
00488                                             const INT32 maxpriority = CACHEPRIORITY_TEMPBITMAP_HIGH)
00489 
00490     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00491     Created:    11/06/2004
00492     Inputs:     key
00493     Outputs:    -
00494     Returns:    TRUE if removed one or more bitmap associated with the owner of this key
00495                 FALSE otherwise
00496     Purpose:    Removes all bitmaps from the cache that have the owner specified in the
00497                 key...
00498     Errors:     -
00499     SeeAlso:    -
00500 
00501 ********************************************************************************************/
00502 BOOL CBitmapCache::RemoveAllOwnedBitmaps(const CBitmapCacheKey& key,
00503                                          const BOOL bOpaqueOnly,
00504                                          const INT32 maxpriority)
00505 {
00506     BOOL bRemovedSome = FALSE;
00507     CCachedBitmap abitmap;
00508 
00509     if (!key.IsValid())
00510         return FALSE;
00511 
00512     if (m_map.size()==0)
00513         return FALSE;
00514 
00515     // Use the owner information stored in the keys to find all bitmap entries
00516     // in the hash table with the same owner...
00517 /*  POSITION pos = GetStartPosition();
00518     while (pos)
00519     {
00520         CBitmapCacheKey akey;
00521         GetNextAssoc(pos, akey, abitmap);
00522 
00523         if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority)
00524         {
00525             if (bOpaqueOnly==FALSE || !abitmap.IsTransparent())
00526             {
00527                 RemoveKey(akey);
00528                 m_lCurrentDataSize -= abitmap.GetBitmapSize();
00529                 FreeDIB(abitmap.pbmpInfo, abitmap.pbmpBits);
00530                 bRemovedSome = TRUE;
00531             }
00532         }
00533     }
00534 */  CCacheKeyMap::iterator pos;
00535     for ( pos=m_map.begin() ; pos!=m_map.end() ; )
00536     {
00537         CBitmapCacheKey akey = pos->first;
00538         CCachedBitmap abitmap = pos->second;
00539         pos++;
00540         if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority)
00541         {
00542             if (bOpaqueOnly==FALSE || !abitmap.IsTransparent())
00543             {
00544                 m_map.erase(akey);
00545                 m_lCurrentDataSize -= abitmap.GetBitmapSize();
00546                 FreeDIB(abitmap.pbmpInfo, abitmap.pbmpBits);
00547                 bRemovedSome = TRUE;
00548             }
00549         }
00550     }
00551 
00552     return bRemovedSome;
00553 }
00554 
00555 
00556 
00557 
00558 /********************************************************************************************
00559 
00560 >   CCachedBitmap CBitmapCache::FindNextOwnedBitmap(POSITION& pos,
00561                                             CBitmapCacheKey& key,
00562                                             const BOOL bOpaqueOnly,
00563                                             const INT32 maxpriority = CACHEPRIORITY_TEMPBITMAP_HIGH)
00564 
00565     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00566     Created:    11/06/2004
00567     Inputs:     key
00568     Outputs:    -
00569     Returns:    TRUE is removed one or more bitmap associated with the owner of this key
00570                 FALSE otherwise
00571     Purpose:    Removes all bitmaps from the cache that have the owner specified in the
00572                 key...
00573     Errors:     -
00574     SeeAlso:    -
00575 
00576 ********************************************************************************************/
00577 CCachedBitmap CBitmapCache::FindNextOwnedBitmap(CCacheKeyMap::iterator &pos,
00578                                         CBitmapCacheKey& key,
00579                                         const BOOL bOpaqueOnly,
00580                                         const INT32 maxpriority)
00581 {
00582 //  BOOL bRemovedSome = FALSE;
00583     CCachedBitmap abitmap;
00584 
00585     if (!key.IsValid())
00586         return abitmap;
00587 
00588     if (m_map.size()==0)
00589         return abitmap;
00590 
00591     // Use the owner information stored in the keys to find all bitmap entries
00592     // in the hash table with the same owner...
00593 /*  while (pos)
00594     {
00595         CBitmapCacheKey akey;
00596         GetNextAssoc(pos, akey, abitmap);
00597 
00598         if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority)
00599         {
00600             if (bOpaqueOnly==FALSE || !abitmap.IsTransparent())
00601             {
00602                 key = akey;         // Return the key we found
00603                 return abitmap;     // along with the bitmap we found
00604             }
00605         }
00606     }
00607 */
00608     while (pos!=m_map.end())
00609     {
00610         CBitmapCacheKey akey = pos->first;
00611         CCachedBitmap abitmap = pos->second;
00612         pos++;
00613         if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority)
00614         {
00615             if (bOpaqueOnly==FALSE || !abitmap.IsTransparent())
00616             {
00617                 key = akey;         // Return the key we found
00618                 return abitmap;     // along with the bitmap we found
00619             }
00620         }
00621     }
00622 
00623     return CCachedBitmap();
00624 }
00625 
00626 
00627 
00628 
00629 /********************************************************************************************
00630 
00631 >   void CBitmapCache::SetMaximumDataSize(UINT64 maxsize)
00632 
00633     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00634     Created:    11/06/2004
00635     Inputs:     -
00636     Outputs:    -
00637     Returns:    -
00638     Purpose:    -
00639     Errors:     -
00640     SeeAlso:    -
00641 
00642 ********************************************************************************************/
00643 void CBitmapCache::SetMaximumDataSize(UINT64 maxsize)
00644 {
00645     m_lMaxDataSize = maxsize;
00646 }
00647 
00648 
00649 
00650 
00651 /********************************************************************************************
00652 
00653 >   UINT64 CBitmapCache::GetMaximumDataSize()
00654 
00655     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00656     Created:    11/06/2004
00657     Inputs:     -
00658     Outputs:    -
00659     Returns:    -
00660     Purpose:    -
00661     Errors:     -
00662     SeeAlso:    -
00663 
00664 ********************************************************************************************/
00665 UINT64 CBitmapCache::GetMaximumDataSize()
00666 {
00667     return m_lMaxDataSize;
00668 }
00669 
00670 
00671 
00672 
00673 /********************************************************************************************
00674 
00675 >   UINT32 CBitmapCache::GetCurrentDataSize()
00676 
00677     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00678     Created:    11/06/2004
00679     Inputs:     -
00680     Outputs:    -
00681     Returns:    -
00682     Purpose:    -
00683     Errors:     -
00684     SeeAlso:    -
00685 
00686 ********************************************************************************************/
00687 UINT32 CBitmapCache::GetCurrentDataSize()
00688 {
00689     return m_lCurrentDataSize;
00690 }
00691 
00692 
00693 
00694 
00695 /********************************************************************************************
00696 
00697 >   UINT64 CBitmapCache::CalcRecommendedMaximumDataSize()
00698 
00699     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00700     Created:    11/06/2004
00701     Inputs:     -
00702     Outputs:    -
00703     Returns:    Recommended max cache size in current memory environment
00704     Purpose:    Work out how much RAM this machine can afford to devote
00705                 to the bitmap cache.
00706                 Never use more than 50% of physical RAM
00707                 Never use more RAM than is free
00708                 Use CachRAMPercent preference to decide percentage of free ram to grab
00709     Errors:     -
00710     SeeAlso:    -
00711 
00712 ********************************************************************************************/
00713 UINT64 CBitmapCache::CalcRecommendedMaximumDataSize()
00714 {
00715     UINT64      ullPhysRAM = 0;
00716     UINT32      LoadPercentage = 0;
00717 
00718     GetMemoryStatus(&ullPhysRAM, &LoadPercentage);
00719 
00720     // Don't use more than 50% of physical ram in the Bitmap Cache
00721     if (LoadPercentage<50) LoadPercentage = 50;     // If <50% in use pretend that 50% is used (never use more than 50%)
00722     return ullPhysRAM * (100-LoadPercentage) * CacheRAMPercent / 10000;
00723 }
00724 
00725 
00726 
00727 
00728 /********************************************************************************************
00729 
00730 >   UINT32 CBitmapCache::PrimeAbove(UINT32 number)
00731 
00732     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> (from the Internet)
00733     Created:    11/06/2004
00734     Inputs:     number to start from
00735     Outputs:    -
00736     Returns:    prime number above the starting value
00737     Purpose:    Computes the first prime number equal to or greater than a specified number.
00738     Errors:     -
00739     SeeAlso:    -
00740 
00741 ********************************************************************************************/
00742 /*
00743 UINT32 CBitmapCache::PrimeAbove(UINT32 number)
00744 {
00745     if (number < 4)  return (number) ;      // 0, 1, 2, and 3 are prime.
00746     if ((number % 2) == 0)  number++ ;      // Prime must be odd.
00747 
00748     for ( ; ; )
00749     {
00750 //    Check for possible divisors.  The "divisor > dividend" test is similar
00751 //    to checking 2 .. sqrt(N) as possible divisors, but avoids the need for
00752 //    linking to the math library.
00753 
00754         for ( UINT32 divisor = 3 ; ; divisor+=2 )
00755         {
00756             if ((number % divisor) == 0)
00757                 break ;             // Not prime - divisor found.
00758             if (divisor > (number / divisor))
00759                 return number ;     // Prime - no divisors found.
00760         }
00761 
00762         number += 2 ;               // Check next odd number.
00763     }
00764 }
00765 */
00766 
00767 
00768 
00769 #ifdef _DEBUG
00770 /********************************************************************************************
00771 
00772 >   void CBitmapCache::DebugDump()
00773 
00774     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00775     Created:    02/11/2004
00776     Inputs:     -
00777     Outputs:    -
00778     Returns:    -
00779     Purpose:    -
00780     Errors:     -
00781     SeeAlso:    -
00782 
00783 ********************************************************************************************/
00784 void CBitmapCache::DebugDump()
00785 {
00786     TRACE( _T("Contents of Bitmap Cache:\n"));
00787 /*  POSITION pos = GetStartPosition();
00788     while (pos)
00789     {
00790         CBitmapCacheKey key;
00791         CCachedBitmap bitmap;
00792         GetNextAssoc(pos, key, bitmap);
00793 
00794         TRACE( _T("Bitmap: %x (%d*%d, %d) Priority: %d Owner: %x %d %s\n"),
00795                                                         bitmap.pbmpInfo,
00796                                                         bitmap.pbmpInfo->bmiHeader.biWidth,
00797                                                         bitmap.pbmpInfo->bmiHeader.biHeight,
00798                                                         bitmap.GetBitmapSize(),
00799                                                         bitmap.nPriority,
00800                                                         key.pOwner,
00801                                                         key.nOption,
00802                                                         ((CCObject*)key.pOwner)->GetRuntimeClass()->m_lpszClassName
00803                                                         );
00804     }
00805 */  CCacheKeyMap::iterator pos;
00806     for ( pos=m_map.begin() ; pos!=m_map.end() ; pos++ )
00807     {
00808         CBitmapCacheKey key = pos->first;
00809         CCachedBitmap bitmap = pos->second;
00810         TRACE( _T("Bitmap: %x (%d*%d, %d) Priority: %d Owner: %x %d %s\n"),
00811                                                         bitmap.pbmpInfo,
00812                                                         bitmap.pbmpInfo->bmiHeader.biWidth,
00813                                                         bitmap.pbmpInfo->bmiHeader.biHeight,
00814                                                         bitmap.GetBitmapSize(),
00815                                                         bitmap.nPriority,
00816                                                         key.pOwner,
00817                                                         key.nOption,
00818                                                         ((CCObject*)key.pOwner)->GetRuntimeClass()->m_lpszClassName
00819                                                         );
00820     }
00821 }
00822 #endif
00823 
00824 
00825 
00826 
00828 // Construction/Destruction
00830 
00831 CCachedBitmap::CCachedBitmap()
00832 {
00833     pbmpInfo = NULL;
00834     pbmpBits = NULL;
00835 //  rectCachedRect = DocRect(0,0,0,0);
00836     coord0 = DocCoord(0,0);
00837     coord1 = DocCoord(0,0);
00838     coord2 = DocCoord(0,0);
00839     nPriority = 0;
00840 }
00841 
00842 CCachedBitmap::CCachedBitmap(LPBITMAPINFO pNewInfo, LPBYTE pNewBits, INT32 nNewPriority)
00843 {
00844     pbmpInfo = pNewInfo;
00845     pbmpBits = pNewBits;
00846 //  rectCachedRect = DocRect(0,0,0,0);
00847     coord0 = DocCoord(0,0);
00848     coord1 = DocCoord(0,0);
00849     coord2 = DocCoord(0,0);
00850     nPriority = nNewPriority;
00851 }
00852 
00853 CCachedBitmap::CCachedBitmap(const CCachedBitmap& cbmp)
00854 {
00855     pbmpInfo = cbmp.pbmpInfo;
00856     pbmpBits = cbmp.pbmpBits;
00857 //  rectCachedRect = cbmp.rectCachedRect;
00858     coord0 = cbmp.coord0;
00859     coord1 = cbmp.coord1;
00860     coord2 = cbmp.coord2;
00861     nPriority = cbmp.nPriority;
00862 }
00863 
00864 
00865 CCachedBitmap::CCachedBitmap(UINT32 Width, UINT32 Height, UINT32 Depth, DocRect rect, INT32 nNewPriority)
00866 {
00867     ENSURE(rect.IsValid(), "Attempt to create a cached bitmap with an invalid rectangle!");
00868     pbmpInfo = AllocDIB(Width, Height, Depth, &pbmpBits);
00869 //  rectCachedRect = rect;
00870     coord0 = DocCoord(rect.lo.x, rect.lo.y);
00871     coord1 = DocCoord(rect.hi.x, rect.lo.y);
00872     coord2 = DocCoord(rect.lo.x, rect.hi.y);
00873     nPriority = nNewPriority;
00874 }
00875 
00876 
00877 CCachedBitmap::~CCachedBitmap()
00878 {
00879 //  if (pbmpInfo && pbmpBits)                   DON'T DO THIS!!!
00880 //      DIBUtil::FreeDIB(pbmpInfo, pbmpBits);
00881     pbmpInfo = NULL;
00882     pbmpBits = NULL;
00883 }
00884 
00885 
00886 
00887 
00888 /********************************************************************************************
00889 
00890 >   void CCachedBitmap::Release()
00891     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00892     Created:    21/06/2004
00893     Inputs:     -
00894     Outputs:    -
00895     Returns:    TRUE if this key is valid
00896                 FALSE otherwise
00897     Purpose:    Test whether this object has been constructed correctly
00898     Errors:     -
00899     SeeAlso:    -
00900 
00901 ********************************************************************************************/
00902 void CCachedBitmap::Release()
00903 {
00904     FreeDIB(pbmpInfo, pbmpBits);
00905 }
00906 
00907 
00908 
00909 
00910 /********************************************************************************************
00911 
00912 >   CCachedBitmap CCachedBitmap::Copy()
00913     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00914     Created:    21/10/2004
00915     Inputs:     -
00916     Outputs:    -
00917     Returns:    -
00918     Purpose:    Copy this cached bitmap (actually copy the bitmap, not just the bitmap pointers)
00919     Errors:     -
00920     SeeAlso:    -
00921 
00922 ********************************************************************************************/
00923 CCachedBitmap CCachedBitmap::Copy()
00924 {
00925     CCachedBitmap copybmp(*this);
00926     INT32 lHRes = pbmpInfo->bmiHeader.biXPelsPerMeter;
00927     INT32 lVRes = pbmpInfo->bmiHeader.biYPelsPerMeter;
00928     DIBUtil::CopyBitmap(pbmpInfo, pbmpBits, &copybmp.pbmpInfo, &copybmp.pbmpBits);
00929     if (copybmp.pbmpInfo)
00930     {
00931         copybmp.pbmpInfo->bmiHeader.biXPelsPerMeter = lHRes;
00932         copybmp.pbmpInfo->bmiHeader.biYPelsPerMeter = lVRes;
00933     }
00934     return copybmp;
00935 }
00936 
00937 
00938 
00939 
00940 /********************************************************************************************
00941 
00942 >   CCachedBitmap::operator==()
00943     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00944     Created:    10/06/2004
00945     Inputs:     -
00946     Outputs:    -
00947     Returns:    TRUE if this key is exactly the same the the specified key
00948     Purpose:    Test whether this object has been constructed correctly
00949                 Required by CTypedPtrMap
00950     Errors:     -
00951     SeeAlso:    -
00952 
00953 ********************************************************************************************/
00954 bool CCachedBitmap::operator==(const CCachedBitmap& cbmp) const
00955 {
00956     return (pbmpInfo == cbmp.pbmpInfo &&
00957             pbmpBits == cbmp.pbmpBits &&
00958 //          rectCachedRect == cbmp.rectCachedRect &&
00959             coord0 == cbmp.coord0 &&
00960             coord1 == cbmp.coord1 &&
00961             coord2 == cbmp.coord2 &&
00962             nPriority == cbmp.nPriority
00963             );
00964 }
00965 
00966 
00967 
00968 
00969 /********************************************************************************************
00970 
00971 >   CCachedBitmap::operator=()
00972     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00973     Created:    10/06/2004
00974     Inputs:     -
00975     Outputs:    -
00976     Returns:    TRUE if this key is exactly the same the the specified key
00977     Purpose:    Test whether this object has been constructed correctly
00978                 Required by CTypedPtrMap
00979     Errors:     -
00980     SeeAlso:    -
00981 
00982 ********************************************************************************************/
00983 const CCachedBitmap&  CCachedBitmap::operator=(const CCachedBitmap& cbmp)
00984 {
00985     pbmpInfo = cbmp.pbmpInfo;
00986     pbmpBits = cbmp.pbmpBits;
00987 //  rectCachedRect = cbmp.rectCachedRect;
00988     coord0 = cbmp.coord0;
00989     coord1 = cbmp.coord1;
00990     coord2 = cbmp.coord2;
00991     nPriority = cbmp.nPriority;
00992     return cbmp;
00993 }
00994 
00995 /********************************************************************************************
00996 
00997 >   BOOL CCachedBitmap::IsValid() const
00998     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00999     Created:    10/06/2004
01000     Inputs:     -
01001     Outputs:    -
01002     Returns:    TRUE if this key is valid
01003                 FALSE otherwise
01004     Purpose:    Test whether this object has been constructed correctly
01005     Errors:     -
01006     SeeAlso:    -
01007 
01008 ********************************************************************************************/
01009 BOOL CCachedBitmap::IsValid() const
01010 {
01011     return (pbmpInfo!=NULL && pbmpBits!=NULL);
01012 }
01013 
01014 
01015 
01016 
01017 /********************************************************************************************
01018 
01019 >   UINT32 CCachedBitmap::GetBitmapSize() const
01020     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01021     Created:    18/06/2004
01022     Inputs:     -
01023     Outputs:    -
01024     Returns:    Size of bitmap in bytes
01025     Purpose:    Find the size of this bitmap
01026     Errors:     -
01027     SeeAlso:    -
01028 
01029 ********************************************************************************************/
01030 UINT32 CCachedBitmap::GetBitmapSize() const
01031 {
01032     return (pbmpInfo->bmiHeader.biSizeImage);
01033 }
01034 
01035 
01036 
01037 
01038 /********************************************************************************************
01039 
01040 >   BOOL CCachedBitmap::IsTransparent() const
01041     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01042     Created:    29/06/2004
01043     Inputs:     -
01044     Outputs:    -
01045     Returns:    TRUE if cached bitmap is 32BPP (transparent)
01046     Purpose:    Find out whether this bitmap has a transparency channel or not
01047     Errors:     -
01048     SeeAlso:    -
01049 
01050 ********************************************************************************************/
01051 BOOL CCachedBitmap::IsTransparent() const
01052 {
01053     return (pbmpInfo->bmiHeader.biCompression!=BI_RGB);
01054 }
01055 
01056 
01057 
01058 
01059 /********************************************************************************************
01060 
01061 >   UINT32 CCachedBitmap::GetBPP() const
01062     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01063     Created:    30/06/2004
01064     Inputs:     -
01065     Outputs:    -
01066     Returns:    Bits Per Pixel
01067     Purpose:    Get bit depth of cached bitmap
01068     Errors:     -
01069     SeeAlso:    -
01070 
01071 ********************************************************************************************/
01072 UINT32 CCachedBitmap::GetBPP() const
01073 {
01074     return (pbmpInfo->bmiHeader.biBitCount);
01075 }
01076 
01077 
01078 
01079 
01080 /********************************************************************************************
01081 
01082 >   void CCachedBitmap::Transform(TransformBase& Trans)
01083     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01084     Created:    21/20/2004
01085     Inputs:     Transform to apply to the stored coords of this bitmap
01086     Outputs:    -
01087     Returns:    -
01088     Purpose:    Transform the cached bitmap so that it can be distorted/repositioned
01089     Errors:     -
01090     SeeAlso:    -
01091 
01092 ********************************************************************************************/
01093 void CCachedBitmap::Transform(TransformBase& Trans)
01094 {
01095 //  Trans.Transform((DocCoord*)&rectCachedRect, 2);
01096     Trans.Transform(&coord0, 3);
01097 }
01098 
01099 
01100 
01101 
01102 /********************************************************************************************
01103 
01104 >   DocRect CCachedBitmap::GetCachedRect()
01105     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01106     Created:    21/20/2004
01107     Inputs:     -
01108     Outputs:    -
01109     Returns:    DocRect - upright rectangle containing all points in stored parallelogram
01110     Purpose:    Transform the cached bitmap so that it can be distorted/repositioned
01111     Errors:     -
01112     SeeAlso:    -
01113 
01114 ********************************************************************************************/
01115 DocRect CCachedBitmap::GetCachedRect()
01116 {
01117     DocRect r(coord0, coord0);
01118     r.IncludePoint(coord1);
01119     r.IncludePoint(coord2);
01120     r.IncludePoint(DocCoord(coord2.x+coord1.x-coord0.x, coord2.y+coord1.y-coord0.y));
01121 
01122     return r;
01123 }
01124 
01125 
01126 
01127 
01128 /********************************************************************************************
01129 
01130 >   void CCachedBitmap::SetCachedRect(DocRect r)
01131     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01132     Created:    21/20/2004
01133     Inputs:     -
01134     Outputs:    -
01135     Returns:    DocRect - upright rectangle containing all points in stored parallelogram
01136     Purpose:    Transform the cached bitmap so that it can be distorted/repositioned
01137     Errors:     -
01138     SeeAlso:    -
01139 
01140 ********************************************************************************************/
01141 void CCachedBitmap::SetCachedRect(DocRect r)
01142 {
01143     coord0 = r.lo;
01144     coord1 = DocCoord(r.hi.x, r.lo.y);
01145     coord2 = DocCoord(r.lo.x, r.hi.y);
01146 }
01147 
01148 
01149 
01150 
01151 /********************************************************************************************
01152 
01153 >   void CCachedBitmap::SetCachedParallelogram(DocCoord* pCoords, UINT32 numCoords)
01154     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01155     Created:    28/07/2005
01156     Inputs:     -
01157     Outputs:    -
01158     Returns:    -
01159     Purpose:    Store parallelogram details
01160     Errors:     -
01161     SeeAlso:    -
01162 
01163 ********************************************************************************************/
01164 void CCachedBitmap::SetCachedParallelogram(DocCoord* pCoords, UINT32 numCoords)
01165 {
01166     coord0 = pCoords[0];
01167     coord1 = pCoords[1];
01168     coord2 = pCoords[2];
01169 }
01170 
01171 
01172 
01173 

Generated on Sat Nov 10 03:44:24 2007 for Camelot by  doxygen 1.4.4