windows-nt/Source/XPSP1/NT/shell/themes/uxtheme/cachelist.cpp
2020-09-26 16:20:57 +08:00

142 lines
4 KiB
C++

//---------------------------------------------------------------------------
// CacheList.cpp - manages list of CRenderCache objects
//---------------------------------------------------------------------------
#include "stdafx.h"
#include "CacheList.h"
//---------------------------------------------------------------------------
DWORD _tls_CacheListIndex = 0xffffffff; // index to tls pObjectPool
//---------------------------------------------------------------------------
CCacheList::CCacheList()
{
Log(LOG_CACHE, L"CCacheList: CREATED cache list for this thread");
}
//---------------------------------------------------------------------------
CCacheList::~CCacheList()
{
for (int i=0; i < _CacheEntries.m_nSize; i++)
{
if (_CacheEntries[i])
delete _CacheEntries[i];
}
Log(LOG_CACHE, L"~CCacheList: DELETED cache list for this thread");
}
//---------------------------------------------------------------------------
HRESULT CCacheList::GetCacheObject(CRenderObj *pRenderObj, int iSlot, CRenderCache **ppCache)
{
static int iPassCount = 0;
HRESULT hr = S_OK;
CRenderCache *pCache;
if (iSlot >= _CacheEntries.m_nSize)
{
hr = Resize(iSlot);
if (FAILED(hr))
goto exit;
}
pCache = _CacheEntries[iSlot];
//---- is this an old object (old objects are freed on discovery) ----
if (pCache)
{
BOOL fBad = (pRenderObj->_iUniqueId != pCache->_iUniqueId);
if (! fBad)
{
//---- verify integrity of cache/render design ----
if (pRenderObj != pCache->_pRenderObj)
{
// should never happen
Log(LOG_ERROR, L"cache object doesn't match CRenderObj");
fBad = TRUE;
}
}
if (fBad)
{
Log(LOG_CACHE, L"GetCacheObject: deleting OLD OBJECT (slot=%d)", iSlot);
delete pCache;
pCache = NULL;
_CacheEntries[iSlot] = NULL;
}
}
//---- create an object on demand ----
if (! pCache)
{
Log(LOG_CACHE, L"GetCacheObject: creating cache obj ON DEMAND (slot=%d)", iSlot);
pCache = new CRenderCache(pRenderObj, pRenderObj->_iUniqueId);
if (! pCache)
{
hr = MakeError32(E_OUTOFMEMORY);
goto exit;
}
_CacheEntries[iSlot] = pCache;
ASSERT(pRenderObj == pCache->_pRenderObj);
}
else
{
Log(LOG_CACHE, L"GetCacheObject: using EXISTING OBJ (slot=%d)", iSlot);
}
*ppCache = pCache;
exit:
return hr;
}
//---------------------------------------------------------------------------
HRESULT CCacheList::Resize(int iMaxSlotNum)
{
HRESULT hr = S_OK;
Log(LOG_CACHE, L"CCacheList::Resize: new MaxSlot=%d", iMaxSlotNum);
int iOldSize = _CacheEntries.m_nSize;
if (iMaxSlotNum >= iOldSize)
{
typedef CRenderCache *Entry;
Entry *pNew = (Entry *)realloc(_CacheEntries.m_aT,
(iMaxSlotNum+1) * sizeof(Entry));
if (! pNew)
hr = MakeError32(E_OUTOFMEMORY);
else
{
_CacheEntries.m_nAllocSize = iMaxSlotNum + 1;
_CacheEntries.m_aT = pNew;
_CacheEntries.m_nSize = iMaxSlotNum + 1;
for (int i=iOldSize; i < _CacheEntries.m_nSize; i++)
_CacheEntries[i] = NULL;
}
}
return hr;
}
//---------------------------------------------------------------------------
CCacheList *GetTlsCacheList(BOOL fOkToCreate)
{
CCacheList *pList = NULL;
if (_tls_CacheListIndex != 0xffffffff) // init-ed in ProcessAttach()
{
pList = (CCacheList *)TlsGetValue(_tls_CacheListIndex);
if ((! pList) && (fOkToCreate)) // not yet initialized
{
//---- create a thread-local cache list ----
pList = new CCacheList();
TlsSetValue(_tls_CacheListIndex, pList);
}
}
return pList;
}
//---------------------------------------------------------------------------