716 lines
19 KiB
C++
716 lines
19 KiB
C++
#include "precomp.h"
|
||
|
||
|
||
//
|
||
// RBC.CPP
|
||
// Received Bitmap Cache
|
||
//
|
||
// Copyright(c) Microsoft 1997-
|
||
//
|
||
|
||
#define MLZ_FILE_ZONE ZONE_CORE
|
||
|
||
|
||
|
||
//
|
||
// RBC_ViewStarting()
|
||
//
|
||
// For 3.0 nodes, we create the cache each time they start hosting.
|
||
// For 2.x nodes, we create the cache once and use it until they leave the
|
||
// share.
|
||
//
|
||
BOOL ASShare::RBC_ViewStarting(ASPerson * pasPerson)
|
||
{
|
||
BOOL rc = FALSE;
|
||
|
||
DebugEntry(ASShare::RBC_ViewStarting);
|
||
|
||
ValidatePerson(pasPerson);
|
||
|
||
//
|
||
// Allocate the INCOMING cache data for this host.
|
||
//
|
||
pasPerson->prbcHost = new RBC_HOST_INFO;
|
||
if (!pasPerson->prbcHost)
|
||
{
|
||
ERROR_OUT(( "Failed to get memory for prbcHost info"));
|
||
DC_QUIT;
|
||
}
|
||
ZeroMemory(pasPerson->prbcHost, sizeof(*(pasPerson->prbcHost)));
|
||
SET_STAMP(pasPerson->prbcHost, RBCHOST);
|
||
|
||
TRACE_OUT(( "Allocated RBC root for host [%d] at 0x%08x",
|
||
pasPerson->mcsID, pasPerson->prbcHost));
|
||
|
||
//
|
||
// Create the bitmap caches for the sender
|
||
//
|
||
|
||
// SMALL
|
||
if (!BMCAllocateCacheData(pasPerson->cpcCaps.bitmaps.sender.capsSmallCacheNumEntries,
|
||
pasPerson->cpcCaps.bitmaps.sender.capsSmallCacheCellSize,
|
||
ID_SMALL_BMP_CACHE,
|
||
&(pasPerson->prbcHost->bitmapCache[ID_SMALL_BMP_CACHE])))
|
||
{
|
||
DC_QUIT;
|
||
}
|
||
|
||
// MEDIUM
|
||
if (!BMCAllocateCacheData(pasPerson->cpcCaps.bitmaps.sender.capsMediumCacheNumEntries,
|
||
pasPerson->cpcCaps.bitmaps.sender.capsMediumCacheCellSize,
|
||
ID_MEDIUM_BMP_CACHE,
|
||
&(pasPerson->prbcHost->bitmapCache[ID_MEDIUM_BMP_CACHE])))
|
||
{
|
||
DC_QUIT;
|
||
}
|
||
|
||
// LARGE
|
||
if (!BMCAllocateCacheData(pasPerson->cpcCaps.bitmaps.sender.capsLargeCacheNumEntries,
|
||
pasPerson->cpcCaps.bitmaps.sender.capsLargeCacheCellSize,
|
||
ID_LARGE_BMP_CACHE,
|
||
&(pasPerson->prbcHost->bitmapCache[ID_LARGE_BMP_CACHE])))
|
||
{
|
||
DC_QUIT;
|
||
}
|
||
|
||
//
|
||
// The host can join the share.
|
||
//
|
||
rc = TRUE;
|
||
|
||
DC_EXIT_POINT:
|
||
DebugExitBOOL(ASShare::RBC_ViewStarting, rc);
|
||
return(rc);
|
||
}
|
||
|
||
|
||
//
|
||
// RBC_ViewEnded()
|
||
//
|
||
void ASShare::RBC_ViewEnded(ASPerson * pasPerson)
|
||
{
|
||
DebugEntry(ASShare::RBC_ViewEnded);
|
||
|
||
ValidatePerson(pasPerson);
|
||
|
||
RBCFreeIncoming(pasPerson);
|
||
|
||
DebugExitVOID(ASShare::RBC_ViewEnded);
|
||
}
|
||
|
||
|
||
//
|
||
// RBC_PartyLeftShare()
|
||
// For 2.x nodes, frees the incoming RBC data
|
||
//
|
||
void ASShare::RBC_PartyLeftShare(ASPerson * pasPerson)
|
||
{
|
||
DebugEntry(ASShare::RBC_PartyLeftShare);
|
||
|
||
ValidatePerson(pasPerson);
|
||
|
||
// This should be gone!
|
||
ASSERT(pasPerson->prbcHost == NULL);
|
||
|
||
DebugExitVOID(ASShare::RBC_PartyLeftShare);
|
||
}
|
||
|
||
|
||
//
|
||
// RBCFreeIncoming()
|
||
// Frees the party RBC incoming structures. This happens
|
||
// * For 3.0 nodes when they stop hosting
|
||
// * For 2.x nodes when leave the share
|
||
//
|
||
void ASShare::RBCFreeIncoming(ASPerson * pasPerson)
|
||
{
|
||
DebugEntry(ASShare::RBCFreeIncoming);
|
||
|
||
//
|
||
// Free this host's cache bitmaps.
|
||
//
|
||
if (pasPerson->prbcHost != NULL)
|
||
{
|
||
UINT i;
|
||
|
||
//
|
||
// Delete all of this host's cache bitmaps.
|
||
//
|
||
for (i = 0; i < NUM_BMP_CACHES; i++)
|
||
{
|
||
BMCFreeCacheData(&(pasPerson->prbcHost->bitmapCache[i]));
|
||
}
|
||
|
||
delete pasPerson->prbcHost;
|
||
pasPerson->prbcHost = NULL;
|
||
}
|
||
|
||
DebugExitVOID(ASShare::RBCFreeIncoming);
|
||
}
|
||
|
||
|
||
//
|
||
// RBC_ProcessCacheOrder(..)
|
||
//
|
||
void ASShare::RBC_ProcessCacheOrder
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPCOM_ORDER_UA pOrder
|
||
)
|
||
{
|
||
PBMC_ORDER_HDR pBmcOrderHdr;
|
||
PBMC_COLOR_TABLE_ORDER_UA pColorOrder;
|
||
PBMC_BITMAP_BITS_ORDER_R2_UA pBitsOrderR2;
|
||
BOOL fCompressed = FALSE;
|
||
UINT cxFixedBitmapWidth;
|
||
UINT iCacheEntry;
|
||
LPBYTE pBitmapBits;
|
||
UINT cbBitmapBits;
|
||
|
||
DebugEntry(ASShare::RBC_ProcessCacheOrder);
|
||
|
||
ValidatePerson(pasPerson);
|
||
|
||
//
|
||
// The rectangle is not included in the header for private order data
|
||
// (see SBC_CopyPrivateOrderData) so we must take this into account
|
||
// when working out the address of the order data.
|
||
//
|
||
pBmcOrderHdr = (PBMC_ORDER_HDR)
|
||
(pOrder->abOrderData - sizeof(pOrder->OrderHeader.rcsDst));
|
||
|
||
switch (pBmcOrderHdr->bmcPacketType)
|
||
{
|
||
case BMC_PT_COLOR_TABLE:
|
||
//
|
||
// This is a new color table. Simply cache the RGB values for
|
||
// use when we come to process a memblt order
|
||
// For backlevel calls the color table is always stored at
|
||
// index 0 because the index field in the order reuses a
|
||
// zero initialized "padding" field in the old structure.
|
||
//
|
||
TRACE_OUT(("Person [%d] Caching color table", pasPerson->mcsID));
|
||
pColorOrder = (PBMC_COLOR_TABLE_ORDER_UA)pBmcOrderHdr;
|
||
|
||
PM_CacheRxColorTable(pasPerson, pColorOrder->index,
|
||
EXTRACT_TSHR_UINT16_UA(&(pColorOrder->colorTableSize)),
|
||
(LPTSHR_RGBQUAD)&pColorOrder->data[0]);
|
||
break;
|
||
|
||
case BMC_PT_BITMAP_BITS_COMPRESSED:
|
||
fCompressed = TRUE;
|
||
TRACE_OUT(( "Compressed BMP"));
|
||
case BMC_PT_BITMAP_BITS_UNCOMPRESSED:
|
||
//
|
||
// This is some cached bitmap data. We have to store it in the
|
||
// specified slot in the specified cache.
|
||
//
|
||
|
||
//
|
||
// The width of the bitmaps we use are actually fixed as
|
||
// multiples of 16 pels wide. Work out the width that
|
||
// corresponds to the sub-bitmap width of data we are caching.
|
||
//
|
||
pBitsOrderR2 = (PBMC_BITMAP_BITS_ORDER_R2_UA)pBmcOrderHdr;
|
||
|
||
cbBitmapBits = EXTRACT_TSHR_UINT16_UA(
|
||
&(pBitsOrderR2->header.cbBitmapBits));
|
||
|
||
cxFixedBitmapWidth =
|
||
((pBitsOrderR2->header.cxSubBitmapWidth +15)/16)*16;
|
||
|
||
//
|
||
// The location of cache entry field depends on the R1/R2
|
||
// protocol
|
||
//
|
||
iCacheEntry = EXTRACT_TSHR_UINT16_UA(&(pBitsOrderR2->iCacheEntryR2));
|
||
pBitmapBits = pBitsOrderR2->data;
|
||
|
||
TRACE_OUT(("Person [%d] Rx bmp: id(%d) entry(%d) size(%dx%d) " \
|
||
"fixed(%d) bpp(%d) bytes(%d) compressed(%d)",
|
||
pasPerson->mcsID,
|
||
pBitsOrderR2->header.cacheID,
|
||
iCacheEntry,
|
||
pBitsOrderR2->header.cxSubBitmapWidth,
|
||
pBitsOrderR2->header.cySubBitmapHeight,
|
||
cxFixedBitmapWidth,
|
||
pBitsOrderR2->header.bpp,
|
||
cbBitmapBits,
|
||
fCompressed));
|
||
|
||
//
|
||
// Pass the BMC data to the caching code. When calculating the
|
||
// pointer to the bitmap bits remember that we did not send the
|
||
// pBitmapBits field of the BMC_BITMAP_BITS_ORDER_Rx structure
|
||
// (see SBC_CopyPrivateOrderData).
|
||
//
|
||
RBCStoreBitsInCacheBitmap(pasPerson,
|
||
pBitsOrderR2->header.cacheID,
|
||
iCacheEntry,
|
||
pBitsOrderR2->header.cxSubBitmapWidth,
|
||
cxFixedBitmapWidth,
|
||
pBitsOrderR2->header.cySubBitmapHeight,
|
||
pBitsOrderR2->header.bpp,
|
||
pBitmapBits,
|
||
cbBitmapBits,
|
||
fCompressed);
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(( "[%u]Invalid packet type(%d)",
|
||
pasPerson,
|
||
(UINT)pBmcOrderHdr->bmcPacketType));
|
||
break;
|
||
}
|
||
|
||
DebugExitVOID(ASShare::RBC_ProcessCacheOrder);
|
||
}
|
||
|
||
|
||
//
|
||
// RBC_MapCacheIDToBitmapHandle(..)
|
||
//
|
||
HBITMAP ASShare::RBC_MapCacheIDToBitmapHandle
|
||
(
|
||
ASPerson * pasPerson,
|
||
UINT cache,
|
||
UINT cacheEntry,
|
||
UINT colorIndex
|
||
)
|
||
{
|
||
PBMC_DIB_CACHE pDIBCache;
|
||
PBMC_DIB_ENTRY pDIBEntry;
|
||
BITMAPINFO_ours bitmapInfo;
|
||
UINT cColors;
|
||
HBITMAP hWorkBitmap = NULL;
|
||
HPALETTE hpalOldDIB = NULL;
|
||
LPBYTE pBits;
|
||
UINT cacheOffset;
|
||
|
||
DebugEntry(ASShare::RBC_MapCacheIDToBitmapHandle);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
//
|
||
// Check that the supplied cache ID is valid.
|
||
//
|
||
if (cache >= NUM_BMP_CACHES)
|
||
{
|
||
ERROR_OUT(( "[%u]Invalid cache ID (%d)", pasPerson, cache));
|
||
cache = 0;
|
||
}
|
||
|
||
//
|
||
// Get a pointer to the bitmap data
|
||
//
|
||
// Note that there are two indexes floating around. From the host's
|
||
// perspective this index is a Cache Handler token and it must be
|
||
// translated in order to address the associated data. However we
|
||
// use it as the direct index into our receive cache and so the
|
||
// slots used on host and remote will be diferent.
|
||
//
|
||
// There is no reason why the slots should be the same. This is just
|
||
// to warn you that if you try correlating cache offsets between
|
||
// host and remote you will get confused as soon as the cache fills
|
||
// up and entries are reallocated in different positions.
|
||
//
|
||
//
|
||
pDIBCache = &(pasPerson->prbcHost->bitmapCache[cache]);
|
||
TRACE_OUT(( "Local person [%d] cache id %d pointer %lx",
|
||
pasPerson->mcsID, cache, pDIBCache));
|
||
cacheOffset = cacheEntry * pDIBCache->cSize;
|
||
pDIBEntry = (PBMC_DIB_ENTRY)(pDIBCache->data + cacheOffset);
|
||
|
||
TRACE_OUT(( "Bits for index %u are at offset %ld, pointer 0x%08x",
|
||
cacheEntry, (cacheEntry * pDIBCache->cSize), pDIBEntry));
|
||
|
||
//
|
||
// Set up the BitmapInfo structure.
|
||
//
|
||
USR_InitDIBitmapHeader((BITMAPINFOHEADER *)&bitmapInfo, pDIBEntry->bpp);
|
||
bitmapInfo.bmiHeader.biWidth = pDIBEntry->cxFixed;
|
||
bitmapInfo.bmiHeader.biHeight = pDIBEntry->cy;
|
||
|
||
//
|
||
// Copy the Rx color table into the bitmap header.
|
||
//
|
||
if ( (pDIBEntry->bpp == 1) ||
|
||
(pDIBEntry->bpp == 4) ||
|
||
(pDIBEntry->bpp == 8) )
|
||
{
|
||
cColors = COLORS_FOR_BPP(pDIBEntry->bpp);
|
||
|
||
PM_GetColorTable( pasPerson,
|
||
colorIndex,
|
||
&cColors,
|
||
(LPTSHR_RGBQUAD)(&bitmapInfo.bmiColors) );
|
||
TRACE_OUT(( "Got %u colors from table",cColors));
|
||
bitmapInfo.bmiHeader.biClrUsed = cColors;
|
||
}
|
||
else if (pDIBEntry->bpp == 24)
|
||
{
|
||
ASSERT(colorIndex == COLORCACHEINDEX_NONE);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("RBC: Unexpected bpp %d from [%d]", pDIBEntry->bpp, pasPerson->mcsID));
|
||
DC_QUIT;
|
||
}
|
||
|
||
//
|
||
// Select which fixed width bitmap we are going to use to store the
|
||
// incoming DIB bits.
|
||
//
|
||
switch (pDIBEntry->cxFixed)
|
||
{
|
||
case 16:
|
||
hWorkBitmap = m_usrBmp16;
|
||
break;
|
||
|
||
case 32:
|
||
hWorkBitmap = m_usrBmp32;
|
||
break;
|
||
|
||
case 48:
|
||
hWorkBitmap = m_usrBmp48;
|
||
break;
|
||
|
||
case 64:
|
||
hWorkBitmap = m_usrBmp64;
|
||
break;
|
||
|
||
case 80:
|
||
hWorkBitmap = m_usrBmp80;
|
||
break;
|
||
|
||
case 96:
|
||
hWorkBitmap = m_usrBmp96;
|
||
break;
|
||
|
||
case 112:
|
||
hWorkBitmap = m_usrBmp112;
|
||
break;
|
||
|
||
case 128:
|
||
hWorkBitmap = m_usrBmp128;
|
||
break;
|
||
|
||
case 256:
|
||
hWorkBitmap = m_usrBmp256;
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(("RBC_MapCacheIDToBitmapHandle: invalid size from [%d]",
|
||
pDIBEntry->cxFixed, pasPerson->mcsID));
|
||
hWorkBitmap = m_usrBmp256;
|
||
break;
|
||
}
|
||
|
||
ASSERT(hWorkBitmap != NULL);
|
||
|
||
|
||
//
|
||
// If the cached bitmap bits are compressed, we first have to
|
||
// decompress them.
|
||
//
|
||
if (pDIBEntry->bCompressed)
|
||
{
|
||
ASSERT(pDIBEntry->bpp <= 8);
|
||
|
||
//
|
||
// Use the decompression buffer to decompress the bitmap data.
|
||
//
|
||
if (!BD_DecompressBitmap(pDIBEntry->bits, m_usrPBitmapBuffer,
|
||
pDIBEntry->cCompressed,
|
||
pDIBEntry->cxFixed,
|
||
pDIBEntry->cy,
|
||
pDIBEntry->bpp))
|
||
{
|
||
ERROR_OUT((
|
||
"Failed to decompress bitmap pBits(%lx)"
|
||
" pBuf(%lx) cb(%x) cx(%d) cy(%d) bpp(%d)",
|
||
pDIBEntry->bits,
|
||
m_usrPBitmapBuffer,
|
||
pDIBEntry->cCompressed,
|
||
pDIBEntry->cxFixed,
|
||
pDIBEntry->cy,
|
||
pDIBEntry->bpp));
|
||
DC_QUIT;
|
||
}
|
||
|
||
pBits = m_usrPBitmapBuffer;
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// For uncompressed data just use direct from the cache
|
||
//
|
||
TRACE_OUT(( "Bitmap bits are uncompressed"));
|
||
pBits = pDIBEntry->bits;
|
||
}
|
||
|
||
|
||
//
|
||
// Set the bits into the bitmap we are about to return to the caller
|
||
//
|
||
hpalOldDIB = SelectPalette(pasPerson->m_pView->m_usrWorkDC,
|
||
pasPerson->pmPalette, FALSE);
|
||
RealizePalette(pasPerson->m_pView->m_usrWorkDC);
|
||
|
||
if (!SetDIBits(pasPerson->m_pView->m_usrWorkDC,
|
||
hWorkBitmap,
|
||
0,
|
||
pDIBEntry->cy,
|
||
pBits,
|
||
(BITMAPINFO *)&bitmapInfo,
|
||
DIB_RGB_COLORS))
|
||
{
|
||
ERROR_OUT(("SetDIBits failed in RBC_MapCacheIDToBitmapHandle"));
|
||
}
|
||
|
||
SelectPalette(pasPerson->m_pView->m_usrWorkDC, hpalOldDIB, FALSE );
|
||
|
||
TRACE_OUT(( "Returning bitmap for person [%d] cache %u index %u color %u",
|
||
pasPerson->mcsID, cache, cacheEntry, colorIndex));
|
||
|
||
|
||
DC_EXIT_POINT:
|
||
DebugExitVOID(ASShare::RBC_MapCacheIDToBitmapHandle);
|
||
return(hWorkBitmap);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//
|
||
// FUNCTION: RBCStoreBitsInCacheBitmap(..)
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Stores received bitmap bits into one of the receiver's cache bitmaps.
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// pasPerson - pasPerson of host the bits came from.
|
||
//
|
||
// cache - the id of the cache bitmap to store the bits in.
|
||
//
|
||
// iCacheEntry - the cache entry number (index).
|
||
//
|
||
// cxSubBitmapWidth - the width in pels of the actual sub-bitmap (ie.
|
||
// excluding padding)
|
||
//
|
||
// cxFixedWidth - the fixed width in pels of the supplied bits (ie.
|
||
// including padding)
|
||
//
|
||
// cySubBitmapHeight - the height in pels of the sub-bitmap.
|
||
//
|
||
// pBitmapBits - a pointer to the actual bitmap bits. These may or may
|
||
// not be compressed (determined by the value of the fCompressed
|
||
// flag).
|
||
//
|
||
// cbBitmapBits - the size of the bitmap bits pointed to by pBitmapBits.
|
||
//
|
||
// fCompressed - a flag specifying whether the supplied bitmap
|
||
// bits are compressed.
|
||
//
|
||
// RETURNS:
|
||
//
|
||
// Nothing.
|
||
//
|
||
//
|
||
void ASShare::RBCStoreBitsInCacheBitmap
|
||
(
|
||
ASPerson * pasPerson,
|
||
UINT cache,
|
||
UINT iCacheEntry,
|
||
UINT cxSubBitmapWidth,
|
||
UINT cxFixedWidth,
|
||
UINT cySubBitmapHeight,
|
||
UINT bpp,
|
||
LPBYTE pBitmapBits,
|
||
UINT cbBitmapBits,
|
||
BOOL fCompressed
|
||
)
|
||
{
|
||
PBMC_DIB_ENTRY pDIBEntry;
|
||
|
||
DebugEntry(ASShare::RBCStoreBitsInCacheBitmap);
|
||
|
||
ValidatePerson(pasPerson);
|
||
|
||
//
|
||
// Do some error checking.
|
||
//
|
||
if (cache >= NUM_BMP_CACHES)
|
||
{
|
||
ERROR_OUT(("Invalid cache ID %d from [%d]", cache, pasPerson->mcsID));
|
||
DC_QUIT;
|
||
}
|
||
|
||
//
|
||
// Now store the bits in the cache
|
||
// The cache is a huge chunk of memory comprising cache slots of cSize
|
||
// bytes each. cSize is rounded to a power of 2 to ensure the array
|
||
// spans segment boundaries cleanly for segmented architecture OSs.
|
||
//
|
||
pDIBEntry = (PBMC_DIB_ENTRY)
|
||
(((LPBYTE)(pasPerson->prbcHost->bitmapCache[cache].data) +
|
||
(iCacheEntry * pasPerson->prbcHost->bitmapCache[cache].cSize)));
|
||
TRACE_OUT(( "Selected cache entry 0x%08x",pDIBEntry));
|
||
|
||
pDIBEntry->inUse = TRUE;
|
||
pDIBEntry->cx = (TSHR_UINT16)cxSubBitmapWidth;
|
||
pDIBEntry->cxFixed = (TSHR_UINT16)cxFixedWidth;
|
||
pDIBEntry->cy = (TSHR_UINT16)cySubBitmapHeight;
|
||
pDIBEntry->bpp = (TSHR_UINT16)bpp;
|
||
pDIBEntry->bCompressed = (fCompressed != FALSE);
|
||
pDIBEntry->cCompressed = cbBitmapBits;
|
||
|
||
//
|
||
// Now copy the bits into the cache entry
|
||
//
|
||
memcpy(pDIBEntry->bits, pBitmapBits, cbBitmapBits);
|
||
|
||
//
|
||
// THIS FIELD IS NEVER ACCESSED.
|
||
//
|
||
pDIBEntry->cBits = BYTES_IN_BITMAP(cxFixedWidth, cySubBitmapHeight,
|
||
pDIBEntry->bpp);
|
||
|
||
DC_EXIT_POINT:
|
||
DebugExitVOID(ASShare::RBCStoreBitsInCacheBitmap);
|
||
}
|
||
|
||
|
||
|
||
|
||
//
|
||
// BMCAllocateCacheData()
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Allocates memory for a bitmap cache
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// cellSize
|
||
//
|
||
// RETURNS:
|
||
//
|
||
// Area needed
|
||
//
|
||
//
|
||
BOOL BMCAllocateCacheData
|
||
(
|
||
UINT numEntries,
|
||
UINT cellSize,
|
||
UINT cacheID,
|
||
PBMC_DIB_CACHE pCache
|
||
)
|
||
{
|
||
BOOL rc = TRUE;
|
||
UINT memoryNeeded;
|
||
UINT workSize;
|
||
PBMC_DIB_ENTRY pCacheEntry;
|
||
UINT i;
|
||
|
||
DebugEntry(BMCAllocateCacheData);
|
||
|
||
//
|
||
// First we must free up any data, if it has been allocated
|
||
//
|
||
BMCFreeCacheData(pCache);
|
||
|
||
//
|
||
// For 2.x compat, we have SEND caps of 1 entry, 1 byte since 2.x
|
||
// remotes fail for zero entries. But we don't want a small cache
|
||
// at all, and for W95 nodes that don't have a cache at all, we don't
|
||
// want viewers to alloc memory which will never be used.
|
||
//
|
||
if ((cellSize > 1) && (numEntries > 1))
|
||
{
|
||
//
|
||
// Calculate the cell area
|
||
//
|
||
workSize = cellSize + sizeof(BMC_DIB_ENTRY) - 1;
|
||
memoryNeeded = numEntries * workSize;
|
||
|
||
TRACE_OUT(("Need 0x%08x bytes for cache %d, %d cells of size 0x%08x",
|
||
memoryNeeded, cacheID, numEntries, cellSize));
|
||
|
||
//
|
||
// Malloc the huge space
|
||
//
|
||
pCache->data = new BYTE[memoryNeeded];
|
||
if (pCache->data == NULL)
|
||
{
|
||
ERROR_OUT(( "Failed to alloc bitmap cache %d", cacheID));
|
||
rc = FALSE;
|
||
DC_QUIT;
|
||
}
|
||
|
||
pCache->cCellSize = cellSize;
|
||
pCache->cEntries = numEntries;
|
||
pCache->cSize = workSize;
|
||
pCache->freeEntry = NULL;
|
||
pCacheEntry = (PBMC_DIB_ENTRY)(pCache->data);
|
||
|
||
for (i = 0; i < numEntries; i++)
|
||
{
|
||
pCacheEntry->inUse = FALSE;
|
||
pCacheEntry = (PBMC_DIB_ENTRY)(((LPBYTE)pCacheEntry) + workSize);
|
||
}
|
||
|
||
TRACE_OUT(( "Allocated cache %d size %d, pointer 0x%08x stored at 0x%08x",
|
||
cacheID,
|
||
memoryNeeded,
|
||
pCache->data,
|
||
&pCache->data));
|
||
}
|
||
|
||
DC_EXIT_POINT:
|
||
DebugExitBOOL(BMCAllocateCacheData, rc);
|
||
return(rc);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// FUNCTION: BMCFreeCacheData()
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Deletes selected cache's memory
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
// cacheID - id of cache for free
|
||
// pCache - pointer to memory to be freed
|
||
//
|
||
//
|
||
// RETURNS:
|
||
//
|
||
// Nothing.
|
||
//
|
||
//
|
||
void BMCFreeCacheData(PBMC_DIB_CACHE pCache)
|
||
{
|
||
DebugEntry(BMCFreeCacheData);
|
||
|
||
if (pCache->data)
|
||
{
|
||
delete[] pCache->data;
|
||
pCache->data = NULL;
|
||
}
|
||
|
||
pCache->cCellSize = 0;
|
||
pCache->cEntries = 0;
|
||
|
||
DebugExitVOID(BMCFreeCacheData);
|
||
}
|
||
|
||
|