зеркало из https://github.com/mozilla/gecko-dev.git
added optimization so that as we render top->bottom, if the clip region ever
becomes empty, we stop rendering.
This commit is contained in:
Родитель
d5808c772f
Коммит
49c4d29e3f
|
@ -111,8 +111,9 @@ PRBool nsRenderingContextUnix :: IsVisibleRect(const nsRect& aRect)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
|
||||
PRBool nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect)
|
||||
|
@ -120,9 +121,10 @@ PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
|
||||
PRBool nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
|
||||
{
|
||||
//XXX wow, needs to do something.
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void nsRenderingContextUnix :: GetClipRegion(nsIRegion **aRegion)
|
||||
|
|
|
@ -68,9 +68,9 @@ public:
|
|||
|
||||
virtual PRBool IsVisibleRect(const nsRect& aRect);
|
||||
|
||||
virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
|
||||
virtual PRBool SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
|
||||
virtual PRBool GetClipRect(nsRect &aRect);
|
||||
virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
|
||||
virtual PRBool SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
|
||||
virtual void GetClipRegion(nsIRegion **aRegion);
|
||||
|
||||
virtual void SetColor(nscolor aColor);
|
||||
|
|
|
@ -119,15 +119,16 @@ public:
|
|||
* @param aRect The rectangle to set the clipping rectangle to
|
||||
* @param aCombine how to combine this rect with the current clip region.
|
||||
* see the bottom of nsIRenderingContext.h
|
||||
* @return PR_TRUE if the clip region is now empty, else PR_FALSE
|
||||
*/
|
||||
virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine) = 0;
|
||||
virtual PRBool SetClipRect(const nsRect& aRect, nsClipCombine aCombine) = 0;
|
||||
|
||||
/**
|
||||
* Gets the bounds of the clip region of the RenderingContext
|
||||
* @param aRect out parameter to contain the clip region bounds
|
||||
* for the RenderingContext
|
||||
* @return PR_TRUE if the rendering context has a cliprect set
|
||||
* (i.e. this is the exact clip rect, not a clip region bounds)
|
||||
* @return PR_TRUE if the rendering context has a local cliprect set
|
||||
* else aRect is undefined
|
||||
*/
|
||||
virtual PRBool GetClipRect(nsRect &aRect) = 0;
|
||||
|
||||
|
@ -136,8 +137,9 @@ public:
|
|||
* @param aRegion The region to set the clipping area to
|
||||
* @param aCombine how to combine this region with the current clip region.
|
||||
* see the bottom of nsIRenderingContext.h
|
||||
* @return PR_TRUE if the clip region is now empty, else PR_FALSE
|
||||
*/
|
||||
virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine) = 0;
|
||||
virtual PRBool SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine) = 0;
|
||||
|
||||
/**
|
||||
* Gets the current clipping region for the RenderingContext
|
||||
|
|
|
@ -402,9 +402,10 @@ PRBool nsRenderingContextWin :: IsVisibleRect(const nsRect& aRect)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
|
||||
PRBool nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
|
||||
{
|
||||
nsRect trect = aRect;
|
||||
int cliptype;
|
||||
|
||||
mStates->mLocalClip = aRect;
|
||||
|
||||
|
@ -419,10 +420,10 @@ void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCo
|
|||
{
|
||||
PushClipState();
|
||||
|
||||
::IntersectClipRect(mDC, trect.x,
|
||||
trect.y,
|
||||
trect.XMost(),
|
||||
trect.YMost());
|
||||
cliptype = ::IntersectClipRect(mDC, trect.x,
|
||||
trect.y,
|
||||
trect.XMost(),
|
||||
trect.YMost());
|
||||
}
|
||||
else if (aCombine == nsClipCombine_kUnion)
|
||||
{
|
||||
|
@ -433,17 +434,17 @@ void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCo
|
|||
trect.XMost(),
|
||||
trect.YMost());
|
||||
|
||||
::ExtSelectClipRgn(mDC, tregion, RGN_OR);
|
||||
cliptype = ::ExtSelectClipRgn(mDC, tregion, RGN_OR);
|
||||
::DeleteObject(tregion);
|
||||
}
|
||||
else if (aCombine == nsClipCombine_kSubtract)
|
||||
{
|
||||
PushClipState();
|
||||
|
||||
::ExcludeClipRect(mDC, trect.x,
|
||||
trect.y,
|
||||
trect.XMost(),
|
||||
trect.YMost());
|
||||
cliptype = ::ExcludeClipRect(mDC, trect.x,
|
||||
trect.y,
|
||||
trect.XMost(),
|
||||
trect.YMost());
|
||||
}
|
||||
else if (aCombine == nsClipCombine_kReplace)
|
||||
{
|
||||
|
@ -453,11 +454,16 @@ void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCo
|
|||
trect.y,
|
||||
trect.XMost(),
|
||||
trect.YMost());
|
||||
::SelectClipRgn(mDC, tregion);
|
||||
cliptype = ::SelectClipRgn(mDC, tregion);
|
||||
::DeleteObject(tregion);
|
||||
}
|
||||
else
|
||||
NS_ASSERTION(FALSE, "illegal clip combination");
|
||||
|
||||
if (cliptype == NULLREGION)
|
||||
return PR_TRUE;
|
||||
else
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsRenderingContextWin :: GetClipRect(nsRect &aRect)
|
||||
|
@ -471,11 +477,11 @@ PRBool nsRenderingContextWin :: GetClipRect(nsRect &aRect)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
|
||||
PRBool nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
|
||||
{
|
||||
nsRegionWin *pRegion = (nsRegionWin *)&aRegion;
|
||||
HRGN hrgn = pRegion->GetHRGN();
|
||||
int cmode;
|
||||
HRGN hrgn = pRegion->GetHRGN();
|
||||
int cmode, cliptype;
|
||||
|
||||
switch (aCombine)
|
||||
{
|
||||
|
@ -501,8 +507,15 @@ void nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, nsClipComb
|
|||
{
|
||||
mStates->mFlags &= ~FLAG_LOCAL_CLIP_VALID;
|
||||
PushClipState();
|
||||
::ExtSelectClipRgn(mDC, hrgn, cmode);
|
||||
cliptype = ::ExtSelectClipRgn(mDC, hrgn, cmode);
|
||||
}
|
||||
else
|
||||
return PR_FALSE;
|
||||
|
||||
if (cliptype == NULLREGION)
|
||||
return PR_TRUE;
|
||||
else
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void nsRenderingContextWin :: GetClipRegion(nsIRegion **aRegion)
|
||||
|
|
|
@ -65,9 +65,9 @@ public:
|
|||
|
||||
virtual PRBool IsVisibleRect(const nsRect& aRect);
|
||||
|
||||
virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
|
||||
virtual PRBool SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
|
||||
virtual PRBool GetClipRect(nsRect &aRect);
|
||||
virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
|
||||
virtual PRBool SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
|
||||
virtual void GetClipRegion(nsIRegion **aRegion);
|
||||
|
||||
virtual void SetColor(nscolor aColor);
|
||||
|
|
|
@ -126,9 +126,10 @@ public:
|
|||
* @param aBackstop if we will need to do back to front
|
||||
* painting, this is the view that, once rendered
|
||||
* ends the back to front pass.
|
||||
* @return PR_TRUE if the entire clip region has been eliminated, else PR_FALSE
|
||||
*/
|
||||
virtual void Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
PRUint32 aPaintFlags, nsIView *aBackstop = nsnull) = 0;
|
||||
virtual PRBool Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
PRUint32 aPaintFlags, nsIView *aBackstop = nsnull) = 0;
|
||||
|
||||
/**
|
||||
* Called to indicate that the specified region of the view
|
||||
|
@ -137,8 +138,9 @@ public:
|
|||
* @param rc rendering context to paint into
|
||||
* @param region damage area
|
||||
* @param aPaintFlags see nsIView.h for flag definitions
|
||||
* @return PR_TRUE if the entire clip region has been eliminated, else PR_FALSE
|
||||
*/
|
||||
virtual void Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags) = 0;
|
||||
virtual PRBool Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags) = 0;
|
||||
|
||||
/**
|
||||
* Called to indicate that the specified event should be handled
|
||||
|
|
|
@ -373,10 +373,11 @@ nsIWidget * nsView :: GetWidget()
|
|||
return mWindow;
|
||||
}
|
||||
|
||||
void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
PRUint32 aPaintFlags, nsIView *aBackstop)
|
||||
PRBool nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
PRUint32 aPaintFlags, nsIView *aBackstop)
|
||||
{
|
||||
nsIView *pRoot = mViewManager->GetRootView();
|
||||
PRBool clipres = PR_FALSE;
|
||||
|
||||
rc.PushState();
|
||||
|
||||
|
@ -389,52 +390,62 @@ void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
|||
crect.width = mClip.mRight - mClip.mLeft;
|
||||
crect.height = mClip.mBottom - mClip.mTop;
|
||||
|
||||
rc.SetClipRect(crect, nsClipCombine_kIntersect);
|
||||
clipres = rc.SetClipRect(crect, nsClipCombine_kIntersect);
|
||||
}
|
||||
else if (this != pRoot)
|
||||
rc.SetClipRect(mBounds, nsClipCombine_kIntersect);
|
||||
clipres = rc.SetClipRect(mBounds, nsClipCombine_kIntersect);
|
||||
|
||||
rc.Translate(mBounds.x, mBounds.y);
|
||||
|
||||
//XXX maybe we should set this before we set the clip? MMP
|
||||
|
||||
if (nsnull != mXForm)
|
||||
if (clipres == PR_FALSE)
|
||||
{
|
||||
nsTransform2D *pXForm = rc.GetCurrentTransform();
|
||||
pXForm->Concatenate(mXForm);
|
||||
}
|
||||
rc.Translate(mBounds.x, mBounds.y);
|
||||
|
||||
PRInt32 numkids = GetChildCount();
|
||||
//XXX maybe we should set this before we set the clip? MMP
|
||||
|
||||
for (PRInt32 cnt = 0; cnt < numkids; cnt++)
|
||||
{
|
||||
nsIView *kid = GetChild(cnt);
|
||||
|
||||
if (nsnull != kid)
|
||||
if (nsnull != mXForm)
|
||||
{
|
||||
nsRect kidRect;
|
||||
kid->GetBounds(kidRect);
|
||||
nsRect damageArea;
|
||||
PRBool overlap = damageArea.IntersectRect(rect, kidRect);
|
||||
nsTransform2D *pXForm = rc.GetCurrentTransform();
|
||||
pXForm->Concatenate(mXForm);
|
||||
}
|
||||
|
||||
if (overlap == PR_TRUE)
|
||||
PRInt32 numkids = GetChildCount();
|
||||
|
||||
for (PRInt32 cnt = 0; cnt < numkids; cnt++)
|
||||
{
|
||||
nsIView *kid = GetChild(cnt);
|
||||
|
||||
if (nsnull != kid)
|
||||
{
|
||||
// Translate damage area into kid's coordinate system
|
||||
nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y,
|
||||
damageArea.width, damageArea.height);
|
||||
kid->Paint(rc, kidDamageArea, aPaintFlags);
|
||||
nsRect kidRect;
|
||||
kid->GetBounds(kidRect);
|
||||
nsRect damageArea;
|
||||
PRBool overlap = damageArea.IntersectRect(rect, kidRect);
|
||||
|
||||
if (overlap == PR_TRUE)
|
||||
{
|
||||
// Translate damage area into kid's coordinate system
|
||||
nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y,
|
||||
damageArea.width, damageArea.height);
|
||||
clipres = kid->Paint(rc, kidDamageArea, aPaintFlags);
|
||||
|
||||
if (clipres == PR_TRUE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((clipres == PR_FALSE) && (mVis == nsViewVisibility_kShow) && (nsnull != mFrame))
|
||||
{
|
||||
nsIPresContext *cx = mViewManager->GetPresContext();
|
||||
rc.PushState();
|
||||
mFrame->Paint(*cx, rc, rect);
|
||||
rc.PopState();
|
||||
NS_RELEASE(cx);
|
||||
}
|
||||
}
|
||||
|
||||
if ((mVis == nsViewVisibility_kShow) && (nsnull != mFrame))
|
||||
{
|
||||
nsIPresContext *cx = mViewManager->GetPresContext();
|
||||
rc.PushState();
|
||||
mFrame->Paint(*cx, rc, rect);
|
||||
rc.PopState();
|
||||
NS_RELEASE(cx);
|
||||
}
|
||||
//XXX would be nice if we could have a version of pop that just removes the
|
||||
//state from the stack but doesn't change the state of the underlying graphics
|
||||
//context. MMP
|
||||
|
||||
rc.PopState();
|
||||
|
||||
|
@ -442,7 +453,7 @@ void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
|||
//paint process. only do this if this view is actually
|
||||
//visible and if there is no widget (like a scrollbar) here.
|
||||
|
||||
if ((mVis == nsViewVisibility_kShow) && (nsnull == mWindow))
|
||||
if ((clipres == PR_FALSE) && (mVis == nsViewVisibility_kShow) && (nsnull == mWindow))
|
||||
{
|
||||
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
|
||||
{
|
||||
|
@ -453,21 +464,24 @@ void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
|
|||
crect.width = mClip.mRight - mClip.mLeft;
|
||||
crect.height = mClip.mBottom - mClip.mTop;
|
||||
|
||||
rc.SetClipRect(crect, nsClipCombine_kSubtract);
|
||||
clipres = rc.SetClipRect(crect, nsClipCombine_kSubtract);
|
||||
}
|
||||
else if (this != pRoot)
|
||||
rc.SetClipRect(mBounds, nsClipCombine_kSubtract);
|
||||
clipres = rc.SetClipRect(mBounds, nsClipCombine_kSubtract);
|
||||
}
|
||||
|
||||
NS_RELEASE(pRoot);
|
||||
|
||||
return clipres;
|
||||
}
|
||||
|
||||
void nsView :: Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags)
|
||||
PRBool nsView :: Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags)
|
||||
{
|
||||
// XXX apply region to rc
|
||||
// XXX get bounding rect from region
|
||||
//if (nsnull != mFrame)
|
||||
// mFrame->Paint(rc, rect, aPaintFlags);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsEventStatus nsView :: HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags)
|
||||
|
|
|
@ -56,9 +56,9 @@ public:
|
|||
virtual void Destroy();
|
||||
virtual nsIViewManager * GetViewManager();
|
||||
virtual nsIWidget * GetWidget();
|
||||
virtual void Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
virtual PRBool Paint(nsIRenderingContext& rc, const nsRect& rect,
|
||||
PRUint32 aPaintFlags, nsIView *aBackstop = nsnull);
|
||||
virtual void Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags);
|
||||
virtual PRBool Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags);
|
||||
virtual nsEventStatus HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags);
|
||||
virtual void SetPosition(nscoord x, nscoord y);
|
||||
virtual void GetPosition(nscoord *x, nscoord *y);
|
||||
|
|
Загрузка…
Ссылка в новой задаче