OptimizeDisplayList() changes.

This commit is contained in:
beard%netscape.com 2000-02-08 03:05:00 +00:00
Родитель 2c2bf523c0
Коммит cebe1b5b9a
2 изменённых файлов: 44 добавлений и 45 удалений

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

@ -42,10 +42,11 @@ static NS_DEFINE_IID(kRenderingContextCID, NS_RENDERING_CONTEXT_CID);
//#define NO_DOUBLE_BUFFER
// display list flags
#define RENDER_VIEW 0x0000
#define VIEW_INCLUDED 0x0001
#define PUSH_CLIP 0x0002
#define POP_CLIP 0x0004
#define VIEW_RENDERED 0x00000001
#define PUSH_CLIP 0x00000002
#define POP_CLIP 0x00000004
#define VIEW_TRANSPARENT 0x00000008
#define VIEW_TRANSLUSCENT 0x00000010
// display list elements
struct DisplayListElement {
@ -182,11 +183,6 @@ nsViewManager2::~nsViewManager2()
mDisplayList = nsnull;
}
if (nsnull != mFrontToBackList) {
delete mFrontToBackList;
mFrontToBackList = nsnull;
}
if (nsnull != mTransRgn) {
if (nsnull != mTransRects)
mTransRgn->FreeRects(mTransRects);
@ -641,16 +637,18 @@ void nsViewManager2::RenderViews(nsIView *aRootView, nsIRenderingContext& aRC, c
}
}
mDisplayListCount = 0;
mOpaqueViewCount = 0;
CreateDisplayList(mRootView, &mDisplayListCount, origin.x, origin.y, aRootView, &aRect);
// now, partition this display list into "front-to-back" bundles, and then draw each bundle
// with successively more and more restrictive clipping.
PartitionDisplayList();
if (mOpaqueViewCount > 0)
OptimizeDisplayList(aRect);
// draw all views in the display list, from back to front.
for (PRInt32 i = mDisplayListCount - 1; i>= 0; --i) {
DisplayListElement* element = NS_STATIC_CAST(DisplayListElement*, mDisplayList->ElementAt(i));
if (element->mFlags & VIEW_INCLUDED) {
if (element->mFlags & VIEW_RENDERED) {
// typical case, just rendering a view.
RenderView(element->mView, aRC, aRect, element->mClip, aResult);
} else {
@ -1928,26 +1926,30 @@ PRBool nsViewManager2::CreateDisplayList(nsIView *aView, PRInt32 *aIndex,
if (childCount > 0)
retval = AddToDisplayList(aIndex, aView, lrect, PUSH_CLIP);
} else if (!retval) {
nsViewVisibility vis;
nsViewVisibility visibility;
float opacity;
PRBool overlap;
PRBool trans;
PRBool transparent;
nsRect irect;
aView->GetVisibility(vis);
aView->GetVisibility(visibility);
aView->GetOpacity(opacity);
aView->HasTransparency(trans);
aView->HasTransparency(transparent);
if (aDamageRect)
overlap = irect.IntersectRect(lrect, *aDamageRect);
else
overlap = PR_TRUE;
if ((nsViewVisibility_kShow == vis) && (opacity > 0.0f) && overlap)
{
retval = AddToDisplayList(aIndex, aView, lrect, VIEW_INCLUDED);
if ((nsViewVisibility_kShow == visibility) && (opacity > 0.0f) && overlap) {
PRUint32 flags = VIEW_RENDERED;
if (transparent)
flags |= VIEW_TRANSPARENT;
if (opacity < 1.0f)
flags |= VIEW_TRANSLUSCENT;
retval = AddToDisplayList(aIndex, aView, lrect, flags);
if (retval || !trans && (opacity == 1.0f) && (irect == *aDamageRect))
if (retval || !transparent && (opacity == 1.0f) && (irect == *aDamageRect))
retval = PR_TRUE;
}
@ -1983,48 +1985,45 @@ PRBool nsViewManager2::AddToDisplayList(PRInt32 *aIndex, nsIView *aView, nsRect
element->mClip = aRect;
element->mFlags = aFlags;
if (aFlags == VIEW_RENDERED)
++mOpaqueViewCount;
return PR_FALSE;
}
nsresult nsViewManager2::PartitionDisplayList()
nsresult nsViewManager2::OptimizeDisplayList(const nsRect& aDamageRect)
{
#if 0
nsVoidArray* frontToBackList = mFrontToBackList;
if (frontToBackList == nsnull) {
frontToBackList = mFrontToBackList = new nsVoidArray(8);
if (frontToBackList == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
}
#endif
// walk the display list, looking for opaque views, and remove any views that are behind them and totally occluded.
PRInt32 count = mDisplayListCount;
PRInt32 opaqueCount = mOpaqueViewCount;
for (PRInt32 i = 0; i < count; ++i) {
DisplayListElement* element = NS_STATIC_CAST(DisplayListElement*, mDisplayList->ElementAt(i));
if (element->mFlags & VIEW_INCLUDED) {
nsIView* view = element->mView;
PRBool isTransparent;
view->HasTransparency(isTransparent);
if (!isTransparent) {
const nsRect& opaqueRect = element->mClip;
nscoord top = opaqueRect.y, left = opaqueRect.x,
bottom = top + opaqueRect.height, right = left + opaqueRect.width;
if (element->mFlags & VIEW_RENDERED) {
// a view is opaque if it is neither transparent nor transluscent
if (!(element->mFlags & (VIEW_TRANSPARENT | VIEW_TRANSLUSCENT))) {
nsRect opaqueRect;
opaqueRect.IntersectRect(element->mClip, aDamageRect);
nscoord top = opaqueRect.y, left = opaqueRect.x;
nscoord bottom = top + opaqueRect.height, right = left + opaqueRect.width;
// search for views behind this one, that are completely obscured by it.
for (PRInt32 j = i + 1; j < count; ++j) {
DisplayListElement* lowerElement = NS_STATIC_CAST(DisplayListElement*, mDisplayList->ElementAt(j));
if (lowerElement->mFlags & VIEW_INCLUDED) {
const nsRect& lowerRect = lowerElement->mClip;
if (lowerElement->mFlags & VIEW_RENDERED) {
nsRect lowerRect;
lowerRect.IntersectRect(lowerElement->mClip, aDamageRect);
if (left <= lowerRect.x && top <= lowerRect.y &&
right >= (lowerRect.x + lowerRect.width) &&
bottom >= (lowerRect.y + lowerRect.height))
{
// remove this element from the display list, by clearing its VIEW_INCLUDED flag.
lowerElement->mFlags &= ~VIEW_INCLUDED;
// remove this element from the display list, by clearing its VIEW_RENDERED flag.
lowerElement->mFlags &= ~VIEW_RENDERED;
}
}
}
}
}
if (--opaqueCount == 0)
break;
}
return NS_OK;
@ -2079,8 +2078,8 @@ void nsViewManager2::ShowDisplayList(PRInt32 flatlen)
newnestcnt++;
}
if (flags & VIEW_INCLUDED)
printf("VIEW_INCLUDED ");
if (flags & VIEW_RENDERED)
printf("VIEW_RENDERED ");
printf("\n");
}

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

@ -157,7 +157,7 @@ private:
nsIView *aRealView, const nsRect *aDamageRect = nsnull,
nsIView *aTopView = nsnull, nscoord aX = 0, nscoord aY = 0);
PRBool AddToDisplayList(PRInt32 *aIndex, nsIView *aView, nsRect &aRect, PRUint32 aFlags);
nsresult PartitionDisplayList(void);
nsresult OptimizeDisplayList(const nsRect& aDamageRect);
void ShowDisplayList(PRInt32 flatlen);
void ComputeViewOffset(nsIView *aView, nsPoint *aOrigin, PRInt32 aFlag);
@ -197,7 +197,7 @@ private:
PRInt32 mUpdateBatchCnt;
nsVoidArray *mDisplayList;
PRInt32 mDisplayListCount;
nsVoidArray *mFrontToBackList;
PRInt32 mOpaqueViewCount;
nsIScrollableView *mRootScrollable;
//from here to public should be static and locked... MMP