changed region pool to use 2 linked lists of slots instead of an array, for constant time allocation and recycling. no longer allocates a fixed size pool, and regions are truly owned by the caller until recycled.

This commit is contained in:
beard%netscape.com 1999-05-30 00:48:01 +00:00
Родитель 8c8dc292af
Коммит 0ffc2cc2af
2 изменённых файлов: 80 добавлений и 58 удалений

Просмотреть файл

@ -26,20 +26,33 @@ nsNativeRegionPool sNativeRegionPool;
nsNativeRegionPool::nsNativeRegionPool() nsNativeRegionPool::nsNativeRegionPool()
{ {
for (short i = 0; i < kRegionPoolCount; i ++) mRegionSlots = nsnull;
{ mEmptySlots = nsnull;
mRegionArray[i].mRegion = ::NewRgn();
mRegionArray[i].mFree = PR_TRUE;
}
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
nsNativeRegionPool::~nsNativeRegionPool() nsNativeRegionPool::~nsNativeRegionPool()
{ {
for (short i = 0; i < kRegionPoolCount; i ++) // Release all of the regions.
{ if (mRegionSlots != nsnull) {
::DisposeRgn(mRegionArray[i].mRegion); nsRegionSlot* slot = mRegionSlots;
while (slot != nsnull) {
::DisposeRgn(slot->mRegion);
nsRegionSlot* next = slot->mNext;
delete slot;
slot = next;
}
}
// Release all empty slots.
if (mEmptySlots != nsnull) {
nsRegionSlot* slot = mEmptySlots;
while (slot != nsnull) {
nsRegionSlot* next = slot->mNext;
delete slot;
slot = next;
}
} }
} }
@ -47,31 +60,42 @@ nsNativeRegionPool::~nsNativeRegionPool()
RgnHandle nsNativeRegionPool::GetNewRegion() RgnHandle nsNativeRegionPool::GetNewRegion()
{ {
for (short i = 0; i < kRegionPoolCount; i ++) nsRegionSlot* slot = mRegionSlots;
{ if (slot != nsnull) {
if (mRegionArray[i].mFree) RgnHandle region = slot->mRegion;
{
mRegionArray[i].mFree = PR_FALSE; // remove this slot from the free list.
return mRegionArray[i].mRegion; mRegionSlots = slot->mNext;
}
// transfer this slot to the empty slot list for reuse.
slot->mRegion = nsnull;
slot->mNext = mEmptySlots;
mEmptySlots = slot;
// initialize the region.
::SetEmptyRgn(region);
return region;
} }
return (::NewRgn()); // we overflew the pool: return a new region
// return a fresh new region. a slot will be created to hold it
// if and when the region is released.
return (::NewRgn());
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
void nsNativeRegionPool::ReleaseRegion(RgnHandle aRgnHandle) void nsNativeRegionPool::ReleaseRegion(RgnHandle aRgnHandle)
{ {
for (short i = 0; i < kRegionPoolCount; i ++) nsRegionSlot* slot = mEmptySlots;
{ if (slot != nsnull)
if (mRegionArray[i].mRegion == aRgnHandle) mEmptySlots = slot->mNext;
{ else
::SetEmptyRgn(mRegionArray[i].mRegion); slot = new nsRegionSlot;
mRegionArray[i].mFree = PR_TRUE;
return; // put this region on the region list.
} slot->mRegion = aRgnHandle;
} slot->mNext = mRegionSlots;
::DisposeRgn(aRgnHandle); // we overflew the pool: delete the GraphicState mRegionSlots = slot;
} }
@ -82,7 +106,7 @@ static NS_DEFINE_IID(kRegionIID, NS_IREGION_IID);
//--------------------------------------------------------------------- //---------------------------------------------------------------------
nsRegionMac :: nsRegionMac() nsRegionMac::nsRegionMac()
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
mRegion = nsnull; mRegion = nsnull;
@ -91,7 +115,7 @@ nsRegionMac :: nsRegionMac()
//--------------------------------------------------------------------- //---------------------------------------------------------------------
nsRegionMac :: ~nsRegionMac() nsRegionMac::~nsRegionMac()
{ {
if (mRegion) if (mRegion)
sNativeRegionPool.ReleaseRegion(mRegion); //::DisposeRgn(mRegion); sNativeRegionPool.ReleaseRegion(mRegion); //::DisposeRgn(mRegion);
@ -104,7 +128,7 @@ NS_IMPL_RELEASE(nsRegionMac);
//--------------------------------------------------------------------- //---------------------------------------------------------------------
nsresult nsRegionMac :: Init(void) nsresult nsRegionMac::Init(void)
{ {
mRegion = sNativeRegionPool.GetNewRegion(); //::NewRgn(); mRegion = sNativeRegionPool.GetNewRegion(); //::NewRgn();
mRegionType = eRegionComplexity_empty; mRegionType = eRegionComplexity_empty;
@ -113,7 +137,7 @@ nsresult nsRegionMac :: Init(void)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: SetTo(const nsIRegion &aRegion) void nsRegionMac::SetTo(const nsIRegion &aRegion)
{ {
nsRegionMac* pRegion = (nsRegionMac*)&aRegion; nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
::CopyRgn(pRegion->mRegion, mRegion); ::CopyRgn(pRegion->mRegion, mRegion);
@ -122,7 +146,7 @@ void nsRegionMac :: SetTo(const nsIRegion &aRegion)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) void nsRegionMac::SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{ {
::SetRectRgn(mRegion, aX, aY, aX + aWidth, aY + aHeight); ::SetRectRgn(mRegion, aX, aY, aX + aWidth, aY + aHeight);
SetRegionType(); SetRegionType();
@ -130,7 +154,7 @@ void nsRegionMac :: SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeigh
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: Intersect(const nsIRegion &aRegion) void nsRegionMac::Intersect(const nsIRegion &aRegion)
{ {
nsRegionMac* pRegion = (nsRegionMac*)&aRegion; nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
::SectRgn(mRegion, pRegion->mRegion, mRegion); ::SectRgn(mRegion, pRegion->mRegion, mRegion);
@ -139,7 +163,7 @@ void nsRegionMac :: Intersect(const nsIRegion &aRegion)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) void nsRegionMac::Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{ {
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn(); RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn();
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight); ::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
@ -150,7 +174,7 @@ void nsRegionMac :: Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aH
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: Union(const nsIRegion &aRegion) void nsRegionMac::Union(const nsIRegion &aRegion)
{ {
nsRegionMac* pRegion = (nsRegionMac*)&aRegion; nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
::UnionRgn(mRegion, pRegion->mRegion, mRegion); ::UnionRgn(mRegion, pRegion->mRegion, mRegion);
@ -159,7 +183,7 @@ void nsRegionMac :: Union(const nsIRegion &aRegion)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) void nsRegionMac::Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{ {
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn(); RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn();
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight); ::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
@ -170,7 +194,7 @@ void nsRegionMac :: Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeigh
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: Subtract(const nsIRegion &aRegion) void nsRegionMac::Subtract(const nsIRegion &aRegion)
{ {
nsRegionMac* pRegion = (nsRegionMac*)&aRegion; nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
::DiffRgn(mRegion, pRegion->mRegion, mRegion); ::DiffRgn(mRegion, pRegion->mRegion, mRegion);
@ -179,7 +203,7 @@ void nsRegionMac :: Subtract(const nsIRegion &aRegion)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) void nsRegionMac::Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{ {
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn(); RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn();
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight); ::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
@ -190,7 +214,7 @@ void nsRegionMac :: Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHe
//--------------------------------------------------------------------- //---------------------------------------------------------------------
PRBool nsRegionMac :: IsEmpty(void) PRBool nsRegionMac::IsEmpty(void)
{ {
if (mRegionType == eRegionComplexity_empty) if (mRegionType == eRegionComplexity_empty)
return PR_TRUE; return PR_TRUE;
@ -200,7 +224,7 @@ PRBool nsRegionMac :: IsEmpty(void)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
PRBool nsRegionMac :: IsEqual(const nsIRegion &aRegion) PRBool nsRegionMac::IsEqual(const nsIRegion &aRegion)
{ {
nsRegionMac* pRegion = (nsRegionMac*)&aRegion; nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
return(::EqualRgn(mRegion, pRegion->mRegion)); return(::EqualRgn(mRegion, pRegion->mRegion));
@ -208,7 +232,7 @@ PRBool nsRegionMac :: IsEqual(const nsIRegion &aRegion)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight) void nsRegionMac::GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight)
{ {
#if TARGET_CARBON #if TARGET_CARBON
Rect macRect; Rect macRect;
@ -225,14 +249,14 @@ void nsRegionMac :: GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PR
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: Offset(PRInt32 aXOffset, PRInt32 aYOffset) void nsRegionMac::Offset(PRInt32 aXOffset, PRInt32 aYOffset)
{ {
::OffsetRgn(mRegion, aXOffset, aYOffset); ::OffsetRgn(mRegion, aXOffset, aYOffset);
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
PRBool nsRegionMac :: ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) PRBool nsRegionMac::ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{ {
Rect macRect; Rect macRect;
::SetRect(&macRect, aX, aY, aX + aWidth, aY + aHeight); ::SetRect(&macRect, aX, aY, aX + aWidth, aY + aHeight);
@ -241,7 +265,7 @@ PRBool nsRegionMac :: ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt
//--------------------------------------------------------------------- //---------------------------------------------------------------------
NS_IMETHODIMP nsRegionMac :: GetRects(nsRegionRectSet **aRects) NS_IMETHODIMP nsRegionMac::GetRects(nsRegionRectSet **aRects)
{ {
nsRegionRectSet *rects; nsRegionRectSet *rects;
@ -417,7 +441,7 @@ NS_IMETHODIMP nsRegionMac :: GetRects(nsRegionRectSet **aRects)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
NS_IMETHODIMP nsRegionMac :: FreeRects(nsRegionRectSet *aRects) NS_IMETHODIMP nsRegionMac::FreeRects(nsRegionRectSet *aRects)
{ {
if (nsnull != aRects) if (nsnull != aRects)
PR_Free((void *)aRects); PR_Free((void *)aRects);
@ -428,14 +452,14 @@ NS_IMETHODIMP nsRegionMac :: FreeRects(nsRegionRectSet *aRects)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
NS_IMETHODIMP nsRegionMac :: GetNativeRegion(void *&aRegion) const NS_IMETHODIMP nsRegionMac::GetNativeRegion(void *&aRegion) const
{ {
aRegion = (void *)mRegion; aRegion = (void *)mRegion;
return NS_OK; return NS_OK;
} }
nsresult nsRegionMac :: SetNativeRegion(void *aRegion) nsresult nsRegionMac::SetNativeRegion(void *aRegion)
{ {
if (aRegion) if (aRegion)
{ {
@ -451,7 +475,7 @@ nsresult nsRegionMac :: SetNativeRegion(void *aRegion)
//--------------------------------------------------------------------- //---------------------------------------------------------------------
NS_IMETHODIMP nsRegionMac :: GetRegionComplexity(nsRegionComplexity &aComplexity) const NS_IMETHODIMP nsRegionMac::GetRegionComplexity(nsRegionComplexity &aComplexity) const
{ {
aComplexity = mRegionType; aComplexity = mRegionType;
return NS_OK; return NS_OK;
@ -460,7 +484,7 @@ NS_IMETHODIMP nsRegionMac :: GetRegionComplexity(nsRegionComplexity &aComplexity
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: SetRegionType() void nsRegionMac::SetRegionType()
{ {
if (::EmptyRgn(mRegion) == PR_TRUE) if (::EmptyRgn(mRegion) == PR_TRUE)
mRegionType = eRegionComplexity_empty; mRegionType = eRegionComplexity_empty;
@ -479,7 +503,7 @@ void nsRegionMac :: SetRegionType()
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void nsRegionMac :: SetRegionEmpty() void nsRegionMac::SetRegionEmpty()
{ {
::SetEmptyRgn(mRegion); ::SetEmptyRgn(mRegion);
SetRegionType(); SetRegionType();
@ -488,7 +512,7 @@ void nsRegionMac :: SetRegionEmpty()
//--------------------------------------------------------------------- //---------------------------------------------------------------------
RgnHandle nsRegionMac :: CreateRectRegion(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) RgnHandle nsRegionMac::CreateRectRegion(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{ {
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn(); RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn();
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight); ::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);

Просмотреть файл

@ -34,15 +34,13 @@ public:
void ReleaseRegion(RgnHandle aRgnHandle); void ReleaseRegion(RgnHandle aRgnHandle);
private: private:
static const short kRegionPoolCount = 200; struct nsRegionSlot {
RgnHandle mRegion;
nsRegionSlot* mNext;
};
typedef struct nsRegionRec nsRegionSlot* mRegionSlots;
{ nsRegionSlot* mEmptySlots;
RgnHandle mRegion;
PRBool mFree;
} nsRegionRec;
nsRegionRec mRegionArray[kRegionPoolCount];
}; };
//------------------------------------------------------------------------ //------------------------------------------------------------------------