Bug 109772. Cleanup views. Promote certain members of nsView and nsViewManager to stack variables. Provide non-COM versions of, and deprecate COM usage of, nsIView methods HasWidget, GetWidget, GetFloating, GetParent, GetFirstChild, GetNextSibling, GetOpacity, GetClientData, GetVisibility, GetViewManager, GetZIndex, GetPosition, and GetBounds. r+sr=dbaron

git-svn-id: svn://10.0.0.236/trunk@144076 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
roc+%cs.cmu.edu 2003-06-24 01:00:46 +00:00
parent 07ec09fbec
commit b023404ef9
6 changed files with 313 additions and 322 deletions

View File

@ -40,10 +40,14 @@
#include "nsISupports.h"
#include "nsCoord.h"
#include "nsRect.h"
#include "nsPoint.h"
#include <stdio.h>
#include "nsIWidget.h"
class nsIViewManager;
class nsViewManager;
class nsView;
struct nsRect;
// Enumerated type to indicate the visibility of a layer.
@ -60,6 +64,47 @@ enum nsViewVisibility {
{ 0xf0a21c40, 0xa7e1, 0x11d1, \
{ 0xa8, 0x24, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
//Flag to determine whether the view will check if events can be handled
//by its children or just handle the events itself
#define NS_VIEW_FLAG_DONT_CHECK_CHILDREN 0x0001
// indicates that the view is or contains a placeholder view
#define NS_VIEW_FLAG_CONTAINS_PLACEHOLDER 0x0002
//the view is transparent
#define NS_VIEW_FLAG_TRANSPARENT 0x0004
//indicates that the view should not be bitblt'd when moved
//or scrolled and instead must be repainted
#define NS_VIEW_FLAG_DONT_BITBLT 0x0010
// indicates that the view is using auto z-indexing
#define NS_VIEW_FLAG_AUTO_ZINDEX 0x0020
// indicates that the view is a floating view.
#define NS_VIEW_FLAG_FLOATING 0x0040
// set if our widget resized.
#define NS_VIEW_FLAG_WIDGET_RESIZED 0x0080
// set if our widget moved.
#define NS_VIEW_FLAG_WIDGET_MOVED 0x0100
#define NS_VIEW_FLAG_CLIPCHILDREN 0x0200
// if set it indicates that this view should be
// displayed above z-index:auto views if this view
// is z-index:auto also
#define NS_VIEW_FLAG_TOPMOST 0x0400
struct nsViewZIndex {
PRBool mIsAuto;
PRInt32 mZIndex;
PRBool mIsTopmost;
nsViewZIndex(PRBool aIsAuto, PRInt32 aZIndex, PRBool aIsTopmost)
: mIsAuto(aIsAuto), mZIndex(aZIndex), mIsTopmost(aIsTopmost) {}
};
//----------------------------------------------------------------------
/**
@ -113,7 +158,8 @@ public:
* view manager from somewhere else, do that instead.
* @result the view manager
*/
NS_IMETHOD GetViewManager(nsIViewManager *&aViewMgr) const = 0;
nsIViewManager* GetViewManager() const
{ return NS_REINTERPRET_CAST(nsIViewManager*, mViewManager); }
/**
* Called to get the position of a view.
@ -122,7 +168,12 @@ public:
* @param x out parameter for x position
* @param y out parameter for y position
*/
NS_IMETHOD GetPosition(nscoord *aX, nscoord *aY) const = 0;
nsPoint GetPosition() const {
// this assertion should go away once we're confident that it's not needed
NS_ASSERTION(!IsRoot() || (mPosX == 0 && mPosY == 0),
"root views should always have explicit position of (0,0)");
return nsPoint(mPosX, mPosY);
}
/**
* Called to get the dimensions and position of the view's bounds.
@ -131,25 +182,31 @@ public:
* if the view has content above or to the left of its origin.
* @param aBounds out parameter for bounds
*/
NS_IMETHOD GetBounds(nsRect &aBounds) const = 0;
nsRect GetBounds() const {
// this assertion should go away once we're confident that it's not needed
NS_ASSERTION(!IsRoot() || (mDimBounds.x == 0 && mDimBounds.y == 0),
"root views should always have explicit position of (0,0)");
return mDimBounds;
}
/**
* Called to query the visibility state of a view.
* @result current visibility state
*/
NS_IMETHOD GetVisibility(nsViewVisibility &aVisibility) const = 0;
nsViewVisibility GetVisibility() const { return mVis; }
/**
* Called to query the z-index of a view.
* The z-index is relative to all siblings of the view.
* @param aAuto PR_TRUE if the view is zindex:auto
* @param aZIndex explicit z-index value.
* @param aTopMost used when this view is zindex:auto
* PR_TRUE if the view is topmost when compared
* with another z-index:auto view
*
* @result mZIndex: explicit z-index value or 0 if none is set
* mIsAuto: PR_TRUE if the view is zindex:auto
* mIsTopMost: used when this view is zindex:auto
* PR_TRUE if the view is topmost when compared
* with another z-index:auto view
*/
NS_IMETHOD GetZIndex(PRBool &aAuto, PRInt32 &aZIndex, PRBool &aTopMost) const = 0;
nsViewZIndex GetZIndex() const { return nsViewZIndex((mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0,
mZIndex,
(mVFlags & NS_VIEW_FLAG_TOPMOST) != 0); }
/**
* Get whether the view "floats" above all other views,
@ -159,25 +216,25 @@ public:
* views that need to be drawn in front of all other views.
* @result PR_TRUE if the view floats, PR_FALSE otherwise.
*/
NS_IMETHOD GetFloating(PRBool &aFloatingView) const = 0;
PRBool GetFloating() const { return (mVFlags & NS_VIEW_FLAG_FLOATING) != 0; }
/**
* Called to query the parent of the view.
* @result view's parent
*/
NS_IMETHOD GetParent(nsIView *&aParent) const = 0;
nsIView* GetParent() const { return NS_REINTERPRET_CAST(nsIView*, mParent); }
/**
* The view's first child is the child which is earliest in document order.
* @result first child
*/
NS_IMETHOD GetFirstChild(nsIView* &aChild) const = 0;
nsIView* GetFirstChild() const { return NS_REINTERPRET_CAST(nsIView*, mFirstChild); }
/**
* Called to query the next sibling of the view.
* @result view's next sibling
*/
NS_IMETHOD GetNextSibling(nsIView *&aNextSibling) const = 0;
nsIView* GetNextSibling() const { return NS_REINTERPRET_CAST(nsIView*, mNextSibling); }
/**
* Note: This didn't exist in 4.0. Called to get the opacity of a view.
@ -185,15 +242,7 @@ public:
* completely opaque.
* @result view's opacity value
*/
NS_IMETHOD GetOpacity(float &aOpacity) const = 0;
/**
* Used to ask a view if it has any areas within its bounding box
* that are transparent. This is not the same as opacity - opacity can
* be set externally, transparency is a quality of the view itself.
* @result Returns PR_TRUE if there are transparent areas, PR_FALSE otherwise.
*/
NS_IMETHOD HasTransparency(PRBool &aTransparent) const = 0;
float GetOpacity() const { return mOpacity; }
/**
* Set the view's link to client owned data.
@ -205,7 +254,7 @@ public:
* Query the view for it's link to client owned data.
* @result data associated with view or nsnull if there is none.
*/
NS_IMETHOD GetClientData(void *&aData) const = 0;
void* GetClientData() const { return mClientData; }
/**
* Get the nearest widget in this view or a parent of this view and
@ -246,13 +295,12 @@ public:
* @param aWidget out parameter for widget that this view contains,
* or nsnull if there is none.
*/
NS_IMETHOD GetWidget(nsIWidget *&aWidget) const = 0;
nsIWidget* GetWidget() const { return mWindow; }
/**
* Returns PR_TRUE if the view has a widget associated with it.
* @param aHasWidget out parameter that indicates whether a view has a widget.
*/
NS_IMETHOD HasWidget(PRBool *aHasWidget) const = 0;
PRBool HasWidget() const { return mWindow != nsnull; }
// XXX Temporary for Bug #19416
NS_IMETHOD IgnoreSetPosition(PRBool aShouldIgnore) = 0;
@ -264,9 +312,43 @@ public:
*/
NS_IMETHOD List(FILE* out, PRInt32 aIndent = 0) const = 0;
/**
* @result true iff this is the root view for its view manager
*/
virtual PRBool IsRoot() const = 0;
// DEPRECATED METHODS to be removed by roc
NS_IMETHOD HasWidget(PRBool *aHasWidget) const = 0;
NS_IMETHOD GetWidget(nsIWidget *&aWidget) const = 0;
NS_IMETHOD GetFloating(PRBool &aFloatingView) const = 0;
NS_IMETHOD GetParent(nsIView *&aParent) const = 0;
NS_IMETHOD GetFirstChild(nsIView* &aChild) const = 0;
NS_IMETHOD GetNextSibling(nsIView *&aNextSibling) const = 0;
NS_IMETHOD GetOpacity(float &aOpacity) const = 0;
NS_IMETHOD GetClientData(void *&aData) const = 0;
NS_IMETHOD GetVisibility(nsViewVisibility &aVisibility) const = 0;
NS_IMETHOD GetViewManager(nsIViewManager *&aViewMgr) const = 0;
NS_IMETHOD GetZIndex(PRBool &aAuto, PRInt32 &aZIndex, PRBool &aTopMost) const = 0;
NS_IMETHOD GetPosition(nscoord *aX, nscoord *aY) const = 0;
NS_IMETHOD GetBounds(nsRect &aBounds) const = 0;
private:
NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
NS_IMETHOD_(nsrefcnt) Release(void) = 0;
protected:
nsViewManager *mViewManager;
nsView *mParent;
nsIWidget *mWindow;
nsView *mNextSibling;
nsView *mFirstChild;
void *mClientData;
PRInt32 mZIndex;
nsViewVisibility mVis;
nscoord mPosX, mPosY;
nsRect mDimBounds; // relative to parent
float mOpacity;
PRUint32 mVFlags;
};
#endif

View File

@ -442,19 +442,16 @@ void nsScrollPortView::AdjustChildWidgets(nsScrollPortView *aScrolling, nsView *
NS_IMETHODIMP nsScrollPortView::SetScrolledView(nsIView *aScrolledView)
{
PRInt32 count = GetChildCount();
NS_ASSERTION(count <= 1,"Error scroll port has too many children");
NS_ASSERTION(GetFirstChild() == nsnull || GetFirstChild()->GetNextSibling() == nsnull,
"Error scroll port has too many children");
// if there is already a child so remove it
if (count == 1)
if (GetFirstChild() != nsnull)
{
nsView* child = GetFirstChild();
mViewManager->RemoveChild(child);
mViewManager->RemoveChild(GetFirstChild());
}
return mViewManager->InsertChild(this, aScrolledView, 0);
}
NS_IMETHODIMP nsScrollPortView::GetScrolledView(nsIView *&aScrolledView) const

View File

@ -640,7 +640,6 @@ void nsView::InsertChild(nsView *aChild, nsView *aSibling)
mFirstChild = aChild;
}
aChild->SetParent(this);
mNumKids++;
}
}
@ -662,7 +661,6 @@ void nsView::RemoveChild(nsView *child)
mFirstChild = kid->GetNextSibling();
}
child->SetParent(nsnull);
mNumKids--;
found = PR_TRUE;
break;
}
@ -943,7 +941,7 @@ nsresult nsView::GetDirtyRegion(nsIRegion*& aRegion)
return NS_OK;
}
PRBool nsView::IsRoot()
PRBool nsView::IsRoot() const
{
NS_ASSERTION(mViewManager != nsnull," View manager is null in nsView::IsRoot()");
return mViewManager->GetRootView() == this;

View File

@ -66,37 +66,6 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICLIPVIEW_IID)
};
//Flag to determine whether the view will check if events can be handled
//by its children or just handle the events itself
#define NS_VIEW_FLAG_DONT_CHECK_CHILDREN 0x0001
// indicates that the view is or contains a placeholder view
#define NS_VIEW_FLAG_CONTAINS_PLACEHOLDER 0x0002
//the view is transparent
#define NS_VIEW_FLAG_TRANSPARENT 0x0004
//indicates that the view should not be bitblt'd when moved
//or scrolled and instead must be repainted
#define NS_VIEW_FLAG_DONT_BITBLT 0x0010
// indicates that the view is using auto z-indexing
#define NS_VIEW_FLAG_AUTO_ZINDEX 0x0020
// indicates that the view is a floating view.
#define NS_VIEW_FLAG_FLOATING 0x0040
// set if our widget resized.
#define NS_VIEW_FLAG_WIDGET_RESIZED 0x0080
// set if our widget moved.
#define NS_VIEW_FLAG_WIDGET_MOVED 0x0100
#define NS_VIEW_FLAG_CLIPCHILDREN 0x0200
// if set it indicates that this view should be
// displayed above z-index:auto views if this view
// is z-index:auto also
#define NS_VIEW_FLAG_TOPMOST 0x0400
class nsView : public nsIView
{
@ -118,13 +87,17 @@ public:
NS_IMETHOD GetBounds(nsRect &aBounds) const;
NS_IMETHOD GetVisibility(nsViewVisibility &aVisibility) const;
NS_IMETHOD GetZIndex(PRBool &aAuto, PRInt32 &aZIndex, PRBool &aTopMost) const;
PRInt32 GetZIndex() const { return mZIndex; }
PRBool GetZIndexIsAuto() const { return (mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0; }
NS_IMETHOD GetFloating(PRBool &aFloatingView) const;
NS_IMETHOD GetParent(nsIView *&aParent) const;
NS_IMETHOD GetFirstChild(nsIView* &aChild) const;
NS_IMETHOD GetNextSibling(nsIView *&aNextSibling) const;
NS_IMETHOD GetOpacity(float &aOpacity) const;
/**
* Used to ask a view if it has any areas within its bounding box
* that are transparent. This is not the same as opacity - opacity can
* be set externally, transparency is a quality of the view itself.
* @result Returns PR_TRUE if there are transparent areas, PR_FALSE otherwise.
*/
NS_IMETHOD HasTransparency(PRBool &aTransparent) const;
NS_IMETHOD SetClientData(void *aData);
NS_IMETHOD GetClientData(void *&aData) const;
@ -292,7 +265,7 @@ public:
static nsView* GetViewFor(nsIWidget* aWidget);
// Helper function to determine if the view instance is the root view
PRBool IsRoot();
virtual PRBool IsRoot() const;
// Helper function to determine if the view point is inside of a view
PRBool PointIsInside(nsView& aView, nscoord x, nscoord y) const;
@ -301,17 +274,27 @@ public:
// parent, if we can)
void DropMouseGrabbing();
public: // NOT in nsIView, so only available in view module
public:
// NOT in nsIView, so only available in view module
nsZPlaceholderView* GetZParent() const { return mZParent; }
// These are also present in nsIView, but these versions return nsView and nsViewManager
// instead of nsIView and nsIViewManager.
nsView* GetFirstChild() const { return mFirstChild; }
nsView* GetNextSibling() const { return mNextSibling; }
nsView* GetParent() const { return mParent; }
nsZPlaceholderView* GetZParent() const { return mZParent; }
nsViewManager* GetViewManager() const { return mViewManager; }
nsViewVisibility GetVisibility() const { return mVis; }
void* GetClientData() const { return mClientData; }
// These are superceded by a better interface in nsIView
PRInt32 GetZIndex() const { return mZIndex; }
PRBool GetZIndexIsAuto() const { return (mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0; }
// This is a better interface than GetDimensions(nsRect&) above
nsRect GetDimensions() const { nsRect r = mDimBounds; r.MoveBy(-mPosX, -mPosY); return r; }
// These are defined exactly the same in nsIView, but for now they have to be redeclared
// here because of stupid C++ method hiding rules
PRBool GetFloating() const { return (mVFlags & NS_VIEW_FLAG_FLOATING) != 0; }
float GetOpacity() const { return mOpacity; }
void* GetClientData() const { return mClientData; }
nsViewVisibility GetVisibility() const { return mVis; }
PRInt32 GetChildCount() const { return mNumKids; }
nsView* GetChild(PRInt32 aIndex) const;
void InsertChild(nsView *aChild, nsView *aSibling);
@ -335,24 +318,10 @@ protected:
virtual nsresult LoadWidget(const nsCID &aClassIID);
protected:
nsViewManager *mViewManager;
nsView *mParent;
nsIWidget *mWindow;
nsZPlaceholderView*mZParent;
//XXX should there be pointers to last child so backward walking is fast?
nsView *mNextSibling;
nsView *mFirstChild;
void *mClientData;
PRInt32 mZIndex;
nsViewVisibility mVis;
PRInt32 mNumKids;
nscoord mPosX, mPosY;
nsRect mDimBounds; // relative to parent
nsRect mChildClip;
float mOpacity;
PRUint32 mVFlags;
nsIRegion* mDirtyRegion;
// Bug #19416
PRPackedBool mShouldIgnoreSetPosition;

View File

@ -67,7 +67,6 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
XXX TODO XXX
DeCOMify newly private methods
Fix opacity model to conform to SVG (requires backbuffer stack)
Optimize view storage
*/
@ -94,7 +93,9 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
#define VIEW_TRANSLUCENT 0x00000010
#define VIEW_CLIPPED 0x00000020
// used only by CanScrollWithBitBlt
#define VIEW_ISSCROLLED 0x00000080
#define VIEW_ISSCROLLED 0x00000040
#define PUSH_FILTER 0x00000080
#define POP_FILTER 0x00000100
#define SUPPORT_TRANSLUCENT_VIEWS
@ -477,8 +478,6 @@ NS_IMETHODIMP nsViewManager::Init(nsIDeviceContext* aContext)
mContext->GetAppUnitsToDevUnits(mTwipsToPixels);
mContext->GetDevUnitsToAppUnits(mPixelsToTwips);
mTransCnt = 0;
mRefreshEnabled = PR_TRUE;
mMouseGrabber = nsnull;
@ -502,7 +501,6 @@ NS_IMETHODIMP nsViewManager::SetRootView(nsIView *aView, nsIWidget* aWidget)
{
nsView* view = NS_STATIC_CAST(nsView*, aView);
UpdateTransCnt(mRootView, view);
// Do NOT destroy the current root view. It's the caller's responsibility
// to destroy it
mRootView = view;
@ -701,11 +699,8 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
}
mPainting = PR_TRUE;
//printf("refreshing region...\n");
//force double buffering because of non-opaque views?
if (mTransCnt > 0)
aUpdateFlags |= NS_VMREFRESH_DOUBLE_BUFFER;
// force double buffering in general
aUpdateFlags |= NS_VMREFRESH_DOUBLE_BUFFER;
if (!DoDoubleBuffering())
aUpdateFlags &= ~NS_VMREFRESH_DOUBLE_BUFFER;
@ -775,7 +770,8 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
}
}
if ((aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) && ds) {
PRBool usingDoubleBuffer = (aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) && ds;
if (usingDoubleBuffer) {
// Adjust translations because the backbuffer holds just the damaged area,
// not the whole widget
@ -794,18 +790,18 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
localcx->Translate(-viewRect.x, -viewRect.y);
}
PRBool result;
// Note that nsIRenderingContext::SetClipRegion always works in pixel coordinates,
// and nsIRenderingContext::SetClipRect always works in app coordinates. Stupid huh?
// Also, SetClipRegion doesn't subject its argument to the current transform, but
// SetClipRect does.
localcx->SetClipRegion(*aRegion, nsClipCombine_kReplace, result);
localcx->SetClipRect(damageRect, nsClipCombine_kIntersect, result);
PRBool isClipped;
localcx->SetClipRegion(*aRegion, nsClipCombine_kReplace, isClipped);
localcx->SetClipRect(damageRect, nsClipCombine_kIntersect, isClipped);
// painting will be done in aView's coordinates
RenderViews(aView, *localcx, damageRegion, result);
RenderViews(aView, *localcx, damageRegion, usingDoubleBuffer);
if ((aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) && ds) {
if (usingDoubleBuffer) {
// Flush bits back to the screen
// Restore aRegion to pixels-relative-to-widget-origin
@ -815,8 +811,8 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
// Make damageRect twips-relative-to-widget-origin
damageRect.MoveBy(-viewRect.x, -viewRect.y);
// Reset clip region to widget-relative
localcx->SetClipRegion(*aRegion, nsClipCombine_kReplace, result);
localcx->SetClipRect(damageRect, nsClipCombine_kIntersect, result);
localcx->SetClipRegion(*aRegion, nsClipCombine_kReplace, isClipped);
localcx->SetClipRect(damageRect, nsClipCombine_kIntersect, isClipped);
// neither source nor destination are transformed
localcx->CopyOffScreenBits(ds, 0, 0, widgetDamageRectInPixels, NS_COPYBITS_USE_SOURCE_CLIP_REGION);
} else {
@ -961,7 +957,8 @@ static void SortByZOrder(DisplayZTreeNode *aNode, nsVoidArray &aBuffer, nsVoidAr
nsInt64 explicitZIndex = 0;
if (nsnull != aNode->mView) {
autoZIndex = aNode->mView->GetZIndexIsAuto();
// Hixie says only non-translucent elements can have z-index:auto
autoZIndex = aNode->mView->GetZIndexIsAuto() && aNode->mView->GetOpacity() == 1.0f;
explicitZIndex = BuildExtendedZIndex(aNode->mView);
}
@ -1135,19 +1132,20 @@ void nsViewManager::AddCoveringWidgetsToOpaqueRegion(nsRegion &aRgn, nsIDeviceCo
}
void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
const nsRegion& aRegion, PRBool &aResult)
const nsRegion& aRegion, PRBool aRCIsOffscreen)
{
BuildDisplayList(aRootView, aRegion.GetBounds(), PR_FALSE, PR_FALSE);
nsAutoVoidArray displayList;
PRBool anyRendered;
nsRect finalTransparentRect;
BuildDisplayList(aRootView, aRegion.GetBounds(), PR_FALSE, PR_FALSE, &displayList);
nsRegion opaqueRgn;
AddCoveringWidgetsToOpaqueRegion(opaqueRgn, mContext, aRootView);
OptimizeDisplayList(aRegion, finalTransparentRect, opaqueRgn);
nsRect finalTransparentRect;
OptimizeDisplayList(&displayList, aRegion, finalTransparentRect, opaqueRgn);
#ifdef DEBUG_roc
// ShowDisplayList(mDisplayListCount);
// ShowDisplayList(&displayList);
#endif
if (!finalTransparentRect.IsEmpty()) {
@ -1161,13 +1159,27 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
#endif
}
// initialize various counters. These are updated in OptimizeDisplayListClipping.
mTranslucentViewCount = 0;
mTranslucentArea.SetRect(0, 0, 0, 0);
PRInt32 index = 0;
nsRect fakeClipRect;
OptimizeDisplayListClipping(PR_FALSE, fakeClipRect, index, anyRendered);
PRBool anyRendered;
OptimizeDisplayListClipping(&displayList, PR_FALSE, fakeClipRect, index, anyRendered);
PRInt32 translucentViewCount;
nsRect translucentArea(0, 0, 0, 0);
PRInt32 i;
// count number of translucent views, and
// accumulate a rectangle of all translucent
// views. this will be used to determine which
// views need to be rendered into the blending
// buffers.
for (i = displayList.Count() - 1; i >= 0; --i) {
DisplayListElement2* element =
NS_STATIC_CAST(DisplayListElement2*, displayList.ElementAt(i));
if ((element->mFlags & VIEW_TRANSLUCENT) && (element->mFlags & VIEW_RENDERED)) {
translucentViewCount++;
translucentArea.UnionRect(translucentArea, element->mBounds);
}
}
// We keep a list of all the rendering contexts whose clip rects
// need to be updated.
@ -1184,21 +1196,23 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
NS_WARNING("Transparent window enabled");
// for a translucent window, we'll pretend the whole area is
// translucent.
mTranslucentArea = aRegion.GetBounds();
translucentArea = aRegion.GetBounds();
}
}
BlendingBuffers* buffers = nsnull;
// create blending buffers, if necessary.
if (mTranslucentViewCount > 0 || translucentWindow) {
buffers = CreateBlendingBuffers(&aRC, translucentWindow);
if (translucentViewCount > 0 || translucentWindow) {
buffers = CreateBlendingBuffers(&aRC, translucentWindow,
translucentViewCount > 0, translucentArea);
NS_ASSERTION(buffers, "not enough memory to blend");
if (!buffers) {
// fall back by just rendering with transparency.
mTranslucentViewCount = 0;
for (PRInt32 i = mDisplayListCount - 1; i>= 0; --i) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(i));
translucentViewCount = 0;
for (i = displayList.Count() - 1; i >= 0; --i) {
DisplayListElement2* element =
NS_STATIC_CAST(DisplayListElement2*, displayList.ElementAt(i));
element->mFlags &= ~VIEW_TRANSLUCENT;
}
} else {
@ -1206,7 +1220,7 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
if (translucentWindow) {
RCList[RCCount++] = buffers->mOffScreenWhiteCX;
}
if (mTranslucentViewCount > 0) {
if (translucentViewCount > 0) {
RCList[RCCount++] = buffers->mBlackCX;
RCList[RCCount++] = buffers->mWhiteCX;
}
@ -1215,7 +1229,7 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
// There are some bits that aren't going to be completely painted, so
// make sure we don't leave garbage in the offscreen context
buffers->mOffScreenCX->SetColor(NS_RGB(128, 128, 128));
buffers->mOffScreenCX->FillRect(nsRect(0, 0, mTranslucentArea.width, mTranslucentArea.height));
buffers->mOffScreenCX->FillRect(nsRect(0, 0, translucentArea.width, translucentArea.height));
}
}
@ -1225,30 +1239,34 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
}
// draw all views in the display list, from back to front.
for (PRInt32 i = 0; i < mDisplayListCount; i++) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(i));
for (i = 0; i < displayList.Count(); i++) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, displayList.ElementAt(i));
if (element->mFlags & PUSH_CLIP) {
PushStateAndClip(RCList, RCCount, element->mBounds, translucentArea.x, translucentArea.y);
}
if (element->mFlags & PUSH_FILTER) {
// nothing here yet
}
if (element->mFlags & VIEW_RENDERED) {
// typical case, just rendering a view.
// RenderView(element->mView, aRC, aRect, element->mBounds, aResult);
if (element->mFlags & VIEW_CLIPPED) {
//Render the view using the clip rect set by it's ancestors
PushStateAndClip(RCList, RCCount, element->mBounds, mTranslucentArea.x, mTranslucentArea.y);
RenderDisplayListElement(element, aRC, buffers);
PushStateAndClip(RCList, RCCount, element->mBounds, translucentArea.x, translucentArea.y);
RenderDisplayListElement(element, aRC, buffers, translucentArea);
PopState(RCList, RCCount);
} else {
RenderDisplayListElement(element, aRC, buffers);
}
} else {
// special case, pushing or popping clipping.
if (element->mFlags & PUSH_CLIP) {
PushStateAndClip(RCList, RCCount, element->mBounds, mTranslucentArea.x, mTranslucentArea.y);
} else {
if (element->mFlags & POP_CLIP) {
PopState(RCList, RCCount);
}
RenderDisplayListElement(element, aRC, buffers, translucentArea);
}
}
if (element->mFlags & POP_FILTER) {
// nothing here yet
}
if (element->mFlags & POP_CLIP) {
PopState(RCList, RCCount);
}
delete element;
}
@ -1258,7 +1276,7 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
if (buffers) {
if (translucentWindow) {
// Set window alphas
nsRect r = mTranslucentArea;
nsRect r = translucentArea;
r *= mTwipsToPixels;
nsRect bufferRect(0, 0, r.width, r.height);
PRUint8* alphas = nsnull;
@ -1273,23 +1291,22 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
// DEBUG: is this getting through?
// mOffScreenCX->SetColor(NS_RGB(177, 177, 0));
// mOffScreenCX->FillRect(nsRect(1, 1, mTranslucentArea.width-2, mTranslucentArea.height-2));
aRC.CopyOffScreenBits(buffers->mOffScreen, 0, 0, mTranslucentArea,
// mOffScreenCX->FillRect(nsRect(1, 1, translucentArea.width-2, translucentArea.height-2));
aRC.CopyOffScreenBits(buffers->mOffScreen, 0, 0, translucentArea,
NS_COPYBITS_XFORM_DEST_VALUES |
NS_COPYBITS_TO_BACK_BUFFER);
// DEBUG: what rectangle are we blitting?
// aRC.SetColor(NS_RGB(0, 177, 177));
// aRC.DrawRect(mTranslucentArea);
// aRC.DrawRect(translucentArea);
delete buffers;
}
mDisplayList.Clear();
}
void nsViewManager::RenderDisplayListElement(DisplayListElement2* element,
nsIRenderingContext &aRC,
BlendingBuffers* aBuffers)
BlendingBuffers* aBuffers,
const nsRect& aTranslucentArea)
{
PRBool clipEmpty;
nsRect r;
@ -1300,7 +1317,7 @@ void nsViewManager::RenderDisplayListElement(DisplayListElement2* element,
// if this element is contained by the translucent area, then
// there's no point in drawing it here because it will be
// overwritten by the final copy of the composited offscreen area
if (!aBuffers || !mTranslucentArea.Contains(element->mBounds)) {
if (!aBuffers || !aTranslucentArea.Contains(element->mBounds)) {
aRC.PushState();
nscoord x = element->mAbsX - r.x, y = element->mAbsY - r.y;
@ -1315,14 +1332,14 @@ void nsViewManager::RenderDisplayListElement(DisplayListElement2* element,
}
#if defined(SUPPORT_TRANSLUCENT_VIEWS)
if (aBuffers && mTranslucentArea.Intersects(element->mBounds)) {
if (aBuffers && aTranslucentArea.Intersects(element->mBounds)) {
// compute the origin of the view, relative to the offscreen buffer, which has the
// same dimensions as mTranslucentArea.
// same dimensions as aTranslucentArea.
nscoord x = element->mAbsX - r.x, y = element->mAbsY - r.y;
nscoord viewX = x - mTranslucentArea.x, viewY = y - mTranslucentArea.y;
nscoord viewX = x - aTranslucentArea.x, viewY = y - aTranslucentArea.y;
nsRect damageRect(element->mBounds);
damageRect.IntersectRect(damageRect, mTranslucentArea);
damageRect.IntersectRect(damageRect, aTranslucentArea);
// -> coordinates relative to element->mView origin
damageRect.x -= x, damageRect.y -= y;
@ -1349,7 +1366,7 @@ void nsViewManager::RenderDisplayListElement(DisplayListElement2* element,
float opacity;
view->GetOpacity(opacity);
// -> coordinates relative to mTranslucentArea origin
// -> coordinates relative to aTranslucentArea origin
damageRect.x += viewX, damageRect.y += viewY;
// perform the blend itself.
@ -1448,7 +1465,9 @@ BlendingBuffers::~BlendingBuffers() {
}
BlendingBuffers* nsViewManager::CreateBlendingBuffers(nsIRenderingContext *aRC,
PRBool aTranslucentWindow)
PRBool aTranslucentWindow,
PRBool aTranslucentViews,
const nsRect& aTranslucentArea)
{
nsresult rv;
@ -1466,9 +1485,9 @@ BlendingBuffers* nsViewManager::CreateBlendingBuffers(nsIRenderingContext *aRC,
if (!buffers)
return nsnull;
nsRect offscreenBounds(0, 0, mTranslucentArea.width, mTranslucentArea.height);
nsRect offscreenBounds(0, 0, aTranslucentArea.width, aTranslucentArea.height);
offscreenBounds.ScaleRoundOut(mTwipsToPixels);
nsSize offscreenSize(mTranslucentArea.width, mTranslucentArea.height);
nsSize offscreenSize(aTranslucentArea.width, aTranslucentArea.height);
rv = aRC->CreateDrawingSurface(offscreenBounds, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, buffers->mOffScreen);
if (NS_FAILED(rv)) {
@ -1482,7 +1501,7 @@ BlendingBuffers* nsViewManager::CreateBlendingBuffers(nsIRenderingContext *aRC,
return nsnull;
}
if (mTranslucentViewCount > 0) {
if (aTranslucentViews) {
rv = aRC->CreateDrawingSurface(offscreenBounds, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, buffers->mBlack);
if (NS_FAILED(rv)) {
delete buffers;
@ -1507,7 +1526,7 @@ BlendingBuffers* nsViewManager::CreateBlendingBuffers(nsIRenderingContext *aRC,
return nsnull;
}
nsRect fillArea(0, 0, mTranslucentArea.width, mTranslucentArea.height);
nsRect fillArea(0, 0, aTranslucentArea.width, aTranslucentArea.height);
buffers->mBlackCX->SetColor(NS_RGB(0, 0, 0));
buffers->mBlackCX->FillRect(fillArea);
@ -1528,7 +1547,7 @@ BlendingBuffers* nsViewManager::CreateBlendingBuffers(nsIRenderingContext *aRC,
return nsnull;
}
nsRect fillArea(0, 0, mTranslucentArea.width, mTranslucentArea.height);
nsRect fillArea(0, 0, aTranslucentArea.width, aTranslucentArea.height);
buffers->mOffScreenCX->SetColor(NS_RGB(0, 0, 0));
buffers->mOffScreenCX->FillRect(fillArea);
@ -2144,7 +2163,7 @@ static PRBool ComputePlaceholderContainment(nsView* aView) {
}
/*
Fills mDisplayList with DisplayListElement2* pointers. The caller is responsible
Fills aDisplayList with DisplayListElement2* pointers. The caller is responsible
for freeing these structs. The display list elements are ordered by z-order so
that the first element of the array is at the bottom in z-order and the last element
in the array is at the top in z-order.
@ -2157,7 +2176,7 @@ static PRBool ComputePlaceholderContainment(nsView* aView) {
Set aCaptured if the event is being captured by the given view.
*/
void nsViewManager::BuildDisplayList(nsView* aView, const nsRect& aRect, PRBool aEventProcessing,
PRBool aCaptured) {
PRBool aCaptured, nsAutoVoidArray* aDisplayList) {
// compute this view's origin
nsPoint origin(0, 0);
ComputeViewOffset(aView, &origin);
@ -2198,7 +2217,8 @@ void nsViewManager::BuildDisplayList(nsView* aView, const nsRect& aRect, PRBool
displayRoot->GetFloating(paintFloaters);
}
CreateDisplayList(displayRoot, PR_FALSE, zTree, PR_FALSE, origin.x, origin.y,
aView, &aRect, nsnull, displayRootOrigin.x, displayRootOrigin.y, paintFloaters, aEventProcessing);
aView, &aRect, nsnull, displayRootOrigin.x, displayRootOrigin.y,
paintFloaters, aEventProcessing);
// Reparent any views that need reparenting in the Z-order tree
ReparentViews(zTree);
@ -2208,11 +2228,9 @@ void nsViewManager::BuildDisplayList(nsView* aView, const nsRect& aRect, PRBool
// Apply proper Z-order handling
nsAutoVoidArray mergeTmp;
SortByZOrder(zTree, mDisplayList, mergeTmp, PR_TRUE);
SortByZOrder(zTree, *aDisplayList, mergeTmp, PR_TRUE);
}
mDisplayListCount = mDisplayList.Count();
DestroyZTreeNode(zTree);
}
@ -2224,25 +2242,23 @@ void nsViewManager::BuildEventTargetList(nsAutoVoidArray &aTargets, nsView* aVie
}
nsRect eventRect(aEvent->point.x, aEvent->point.y, 1, 1);
BuildDisplayList(aView, eventRect, PR_TRUE, aCaptured);
nsAutoVoidArray displayList;
BuildDisplayList(aView, eventRect, PR_TRUE, aCaptured, &displayList);
#ifdef DEBUG_roc
// ShowDisplayList(mDisplayListCount);
// ShowDisplayList(aDisplayList);
#endif
// The display list is in order from back to front. We return the target list in order from
// front to back.
for (PRInt32 i = mDisplayListCount - 1; i >= 0; --i) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(i));
for (PRInt32 i = displayList.Count() - 1; i >= 0; --i) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, displayList.ElementAt(i));
if (element->mFlags & VIEW_RENDERED) {
aTargets.AppendElement(element);
} else {
delete element;
}
}
mDisplayList.Clear();
}
nsEventStatus nsViewManager::HandleEvent(nsView* aView, nsGUIEvent* aEvent, PRBool aCaptured) {
@ -2521,8 +2537,6 @@ NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, nsIV
ReparentWidgets(child, parent);
#endif
UpdateTransCnt(nsnull, child);
// if the parent view is marked as "floating", make the newly added view float as well.
PRBool isFloating = PR_FALSE;
parent->GetFloating(isFloating);
@ -2578,7 +2592,6 @@ NS_IMETHODIMP nsViewManager::RemoveChild(nsIView *aChild)
if ((nsnull != parent) && (nsnull != child))
{
UpdateTransCnt(child, nsnull);
UpdateView(child, NS_VMREFRESH_NO_SYNC);
parent->RemoveChild(child);
}
@ -2859,11 +2872,12 @@ PRBool nsViewManager::CanScrollWithBitBlt(nsView* aView)
}
aView->ConvertFromParentCoords(&r.x, &r.y);
BuildDisplayList(aView, r, PR_FALSE, PR_FALSE);
nsAutoVoidArray displayList;
BuildDisplayList(aView, r, PR_FALSE, PR_FALSE, &displayList);
PRInt32 i;
for (i = 0; i < mDisplayListCount; i++) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(i));
for (i = 0; i < displayList.Count(); i++) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, displayList.ElementAt(i));
if ((element->mFlags & VIEW_RENDERED) != 0) {
if (IsAncestorOf(aView, element->mView)) {
element->mFlags |= (VIEW_ISSCROLLED | VIEW_TRANSPARENT);
@ -2917,13 +2931,13 @@ PRBool nsViewManager::CanScrollWithBitBlt(nsView* aView)
// (Of course it's possible that aView's parent is actually in front of aView (if aView has a negative
// z-index) but if so, this code still does the right thing. Yay for the display list based approach!)
OptimizeDisplayList(nsRegion(r), finalTransparentRect, opaqueRegion);
OptimizeDisplayList(&displayList, nsRegion(r), finalTransparentRect, opaqueRegion);
PRBool anyUnscrolledViews = PR_FALSE;
PRBool anyUnblittableViews = PR_FALSE;
for (i = 0; i < mDisplayListCount; i++) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(i));
for (i = 0; i < displayList.Count(); i++) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, displayList.ElementAt(i));
if ((element->mFlags & VIEW_RENDERED) != 0) {
if ((element->mFlags & VIEW_ISSCROLLED) == 0 && element->mView != aView) {
anyUnscrolledViews = PR_TRUE;
@ -2935,8 +2949,6 @@ PRBool nsViewManager::CanScrollWithBitBlt(nsView* aView)
delete element;
}
mDisplayList.Clear();
return !anyUnscrolledViews && !anyUnblittableViews;
}
@ -3086,9 +3098,7 @@ NS_IMETHODIMP nsViewManager::SetViewContentTransparency(nsIView *aView, PRBool a
view->HasTransparency(trans);
if (trans != aTransparent) {
UpdateTransCnt(view, nsnull);
view->SetContentTransparency(aTransparent);
UpdateTransCnt(nsnull, view);
if (IsViewInserted(view)) {
UpdateView(view, NS_VMREFRESH_NO_SYNC);
@ -3107,9 +3117,7 @@ NS_IMETHODIMP nsViewManager::SetViewOpacity(nsIView *aView, float aOpacity)
if (opacity != aOpacity)
{
UpdateTransCnt(view, nsnull);
view->SetOpacity(aOpacity);
UpdateTransCnt(nsnull, view);
if (IsViewInserted(view)) {
UpdateView(view, NS_VMREFRESH_NO_SYNC);
@ -3258,33 +3266,6 @@ void nsViewManager::AddRectToDirtyRegion(nsView* aView, const nsRect &aRect) con
}
}
void nsViewManager::UpdateTransCnt(nsView *oldview, nsView *newview)
{
if (nsnull != oldview)
{
PRBool hasTransparency;
float opacity;
oldview->HasTransparency(hasTransparency);
oldview->GetOpacity(opacity);
if (hasTransparency || (1.0f != opacity))
mTransCnt--;
}
if (nsnull != newview)
{
PRBool hasTransparency;
float opacity;
newview->HasTransparency(hasTransparency);
newview->GetOpacity(opacity);
if (hasTransparency || (1.0f != opacity))
mTransCnt++;
}
}
NS_IMETHODIMP nsViewManager::DisableRefresh(void)
{
if (mUpdateBatchCnt > 0)
@ -3387,13 +3368,12 @@ NS_IMETHODIMP nsViewManager::Display(nsIView* aView, nscoord aX, nscoord aY, con
localcx->Translate(aX, aY);
PRBool result;
localcx->SetClipRect(aClipRect, nsClipCombine_kReplace, result);
PRBool isClipped;
localcx->SetClipRect(aClipRect, nsClipCombine_kReplace, isClipped);
// Paint the view. The clipping rect was set above set don't clip again.
//aView->Paint(*localcx, trect, NS_VIEW_FLAG_CLIP_SET, result);
RenderViews(view, *localcx, nsRegion(trect), result);
RenderViews(view, *localcx, nsRegion(trect), PR_FALSE);
NS_RELEASE(localcx);
@ -3577,21 +3557,22 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView, PRBool aReparentedViewsPr
}
}
PRInt32 childCount = aView->GetChildCount();
PRBool anyChildren = aView->GetFirstChild() != nsnull;
if (aEventProcessing
&& (aView->GetViewFlags() & NS_VIEW_FLAG_DONT_CHECK_CHILDREN) != 0) {
childCount = 0;
anyChildren = PR_FALSE;
}
if (childCount > 0) {
if (anyChildren) {
if (isClipView) {
// -> to refresh-frame coordinates (relative to aRealView)
bounds.x -= aOriginX;
bounds.y -= aOriginY;
// Add POP first because the z-tree is in reverse order
retval = AddToDisplayList(aView, aResult, bounds, bounds, POP_CLIP, aX - aOriginX, aY - aOriginY, PR_FALSE);
retval = AddToDisplayList(aView, aResult, bounds, bounds,
POP_CLIP, aX - aOriginX, aY - aOriginY, PR_FALSE);
if (retval)
return retval;
@ -3642,7 +3623,8 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView, PRBool aReparentedViewsPr
if (opacity < 1.0f)
flags |= VIEW_TRANSLUCENT;
#endif
retval = AddToDisplayList(aView, aResult, bounds, irect, flags, aX - aOriginX, aY - aOriginY,
retval = AddToDisplayList(aView, aResult, bounds, irect, flags,
aX - aOriginX, aY - aOriginY,
aEventProcessing && aRealView == aView);
}
@ -3657,12 +3639,13 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView, PRBool aReparentedViewsPr
}
}
if (childCount > 0 && isClipView) {
if (anyChildren && isClipView) {
// -> to refresh-frame coordinates (relative to aRealView)
bounds.x -= aOriginX;
bounds.y -= aOriginY;
if (AddToDisplayList(aView, aResult, bounds, bounds, PUSH_CLIP, aX - aOriginX, aY - aOriginY, PR_FALSE)) {
if (AddToDisplayList(aView, aResult, bounds, bounds, PUSH_CLIP,
aX - aOriginX, aY - aOriginY, PR_FALSE)) {
retval = PR_TRUE;
}
}
@ -3670,9 +3653,11 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView, PRBool aReparentedViewsPr
return retval;
}
PRBool nsViewManager::AddToDisplayList(nsView *aView, DisplayZTreeNode* &aParent,
nsRect &aClipRect, nsRect& aDirtyRect, PRUint32 aFlags,nscoord aAbsX, nscoord aAbsY,
PRBool aAssumeIntersection)
PRBool nsViewManager::AddToDisplayList(nsView *aView,
DisplayZTreeNode* &aParent, nsRect &aClipRect,
nsRect& aDirtyRect, PRUint32 aFlags,
nscoord aAbsX, nscoord aAbsY,
PRBool aAssumeIntersection)
{
PRBool empty;
PRBool clipped;
@ -3724,40 +3709,6 @@ PRBool nsViewManager::AddToDisplayList(nsView *aView, DisplayZTreeNode* &aParent
return PR_FALSE;
}
// Make sure that all PUSH_CLIP/POP_CLIP pairs are honored.
// They might not be because of the Z-reparenting mess: a fixed-position view might have
// created a display element with bounds that do not reflect the clipping instructions that now
// surround the element. This would cause problems in the optimizer.
// XXX No longer used. REMOVE IN THE GREAT VIEW MANAGER PURGE
void nsViewManager::ReapplyClipInstructions(PRBool aHaveClip, nsRect& aClipRect, PRInt32& aIndex)
{
while (aIndex < mDisplayListCount) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(aIndex));
aIndex++;
if (element->mFlags & VIEW_RENDERED) {
if (aHaveClip && !element->mBounds.IntersectRect(aClipRect, element->mBounds)) {
element->mFlags &= ~VIEW_RENDERED;
}
}
if (element->mFlags & PUSH_CLIP) {
nsRect newClip;
if (aHaveClip) {
newClip.IntersectRect(aClipRect, element->mBounds);
} else {
newClip = element->mBounds;
}
ReapplyClipInstructions(PR_TRUE, newClip, aIndex);
}
if (element->mFlags & POP_CLIP) {
return;
}
}
}
/**
Walk the display list, looking for opaque views, and remove any views that are behind them
and totally occluded.
@ -3768,13 +3719,12 @@ void nsViewManager::ReapplyClipInstructions(PRBool aHaveClip, nsRect& aClipRect,
Usually this will be empty, but nothing really prevents someone
from creating a set of views that are (for example) all transparent.
*/
nsresult nsViewManager::OptimizeDisplayList(const nsRegion& aDamageRegion,
nsRect& aFinalTransparentRect,
nsRegion &aOpaqueRegion)
void nsViewManager::OptimizeDisplayList(nsAutoVoidArray* aDisplayList, const nsRegion& aDamageRegion,
nsRect& aFinalTransparentRect,
nsRegion &aOpaqueRegion)
{
PRInt32 count = mDisplayListCount;
for (PRInt32 i = count - 1; i >= 0; i--) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(i));
for (PRInt32 i = aDisplayList->Count() - 1; i >= 0; i--) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, aDisplayList->ElementAt(i));
if (element->mFlags & VIEW_RENDERED) {
nsRegion tmpRgn;
tmpRgn.Sub(element->mBounds, aOpaqueRegion);
@ -3796,36 +3746,21 @@ nsresult nsViewManager::OptimizeDisplayList(const nsRegion& aDamageRegion,
nsRegion tmpRgn;
tmpRgn.Sub(aDamageRegion, aOpaqueRegion);
aFinalTransparentRect = tmpRgn.GetBounds();
return NS_OK;
}
// Remove redundant PUSH/POP_CLIP pairs. These could be expensive.
// We also count the translucent views and compute the translucency area in
// this pass.
void nsViewManager::OptimizeDisplayListClipping(PRBool aHaveClip, nsRect& aClipRect, PRInt32& aIndex,
void nsViewManager::OptimizeDisplayListClipping(nsAutoVoidArray* aDisplayList,
PRBool aHaveClip, nsRect& aClipRect, PRInt32& aIndex,
PRBool& aAnyRendered)
{
aAnyRendered = PR_FALSE;
while (aIndex < mDisplayListCount) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(aIndex));
while (aIndex < aDisplayList->Count()) {
DisplayListElement2* element =
NS_STATIC_CAST(DisplayListElement2*, aDisplayList->ElementAt(aIndex));
aIndex++;
if (element->mFlags & VIEW_RENDERED) {
// count number of translucent views, and
// accumulate a rectangle of all translucent
// views. this will be used to determine which
// views need to be rendered into the blending
// buffers.
if (element->mFlags & VIEW_TRANSLUCENT) {
if (mTranslucentViewCount++ == 0) {
mTranslucentArea = element->mBounds;
} else {
mTranslucentArea.UnionRect(mTranslucentArea, element->mBounds);
}
}
aAnyRendered = PR_TRUE;
if (aHaveClip && (element->mFlags & VIEW_CLIPPED)) {
@ -3847,8 +3782,9 @@ void nsViewManager::OptimizeDisplayListClipping(PRBool aHaveClip, nsRect& aClipR
}
PRBool anyRenderedViews = PR_FALSE;
OptimizeDisplayListClipping(PR_TRUE, newClip, aIndex, anyRenderedViews);
DisplayListElement2* popElement = NS_STATIC_CAST(DisplayListElement2*, mDisplayList.ElementAt(aIndex - 1));
OptimizeDisplayListClipping(aDisplayList, PR_TRUE, newClip, aIndex, anyRenderedViews);
DisplayListElement2* popElement =
NS_STATIC_CAST(DisplayListElement2*, aDisplayList->ElementAt(aIndex - 1));
NS_ASSERTION(popElement->mFlags & POP_CLIP, "Must end with POP!");
if (anyRenderedViews) {
@ -3868,19 +3804,19 @@ void nsViewManager::OptimizeDisplayListClipping(PRBool aHaveClip, nsRect& aClipR
}
}
#ifdef NS_DEBUG
void nsViewManager::ShowDisplayList(PRInt32 flatlen)
void nsViewManager::ShowDisplayList(nsAutoVoidArray* aDisplayList)
{
#ifdef NS_DEBUG
char nest[400];
PRInt32 newnestcnt, nestcnt = 0, cnt;
for (cnt = 0; cnt < 400; cnt++)
nest[cnt] = ' ';
printf("### display list length=%d ###\n", flatlen);
printf("### display list length=%d ###\n", aDisplayList->Count());
for (cnt = 0; cnt < flatlen; cnt++) {
DisplayListElement2* element = (DisplayListElement2*) mDisplayList.ElementAt(cnt);
for (cnt = 0; cnt < aDisplayList->Count(); cnt++) {
DisplayListElement2* element = (DisplayListElement2*)aDisplayList->ElementAt(cnt);
nsView* view = element->mView;
nsRect rect = element->mBounds;
PRUint32 flags = element->mFlags;
@ -3920,6 +3856,16 @@ void nsViewManager::ShowDisplayList(PRInt32 flatlen)
newnestcnt++;
}
if (flags & POP_FILTER) {
printf("POP_FILTER ");
newnestcnt--;
}
if (flags & PUSH_FILTER) {
printf("PUSH_FILTER ");
newnestcnt++;
}
if (flags & VIEW_RENDERED)
printf("VIEW_RENDERED ");
@ -3945,8 +3891,8 @@ void nsViewManager::ShowDisplayList(PRInt32 flatlen)
nestcnt = newnestcnt;
}
}
#endif
}
void nsViewManager::ComputeViewOffset(nsView *aView, nsPoint *aOrigin)
{

View File

@ -244,7 +244,6 @@ private:
void ReparentWidgets(nsIView* aView, nsIView *aParent);
nsIRenderingContext *CreateRenderingContext(nsView &aView);
void AddRectToDirtyRegion(nsView* aView, const nsRect &aRect) const;
void UpdateTransCnt(nsView *oldview, nsView *newview);
PRBool UpdateWidgetArea(nsView *aWidgetView, const nsRect &aDamagedRect, nsView* aIgnoreWidgetView);
@ -254,11 +253,11 @@ private:
nsIRegion *region, PRUint32 aUpdateFlags);
void DefaultRefresh(nsView* aView, const nsRect* aRect);
void RenderViews(nsView *aRootView, nsIRenderingContext& aRC, const nsRegion& aRegion,
PRBool &aResult);
PRBool aRCIsOffscreen);
void RenderDisplayListElement(DisplayListElement2* element,
nsIRenderingContext &aRC,
BlendingBuffers* aBuffers);
BlendingBuffers* aBuffers, const nsRect& aTranslucentArea);
void PaintView(nsView *aView, nsIRenderingContext &aRC, nscoord x, nscoord y,
const nsRect &aDamageRect);
@ -268,20 +267,26 @@ private:
PRUint32 aUpdateFlags, nscoord aY1, nscoord aY2, PRBool aInCutOut);
BlendingBuffers* CreateBlendingBuffers(nsIRenderingContext *aRC,
PRBool aTranslucentWindow);
PRBool aTranslucentWindow, PRBool aTranslucentViews,
const nsRect& aTranslucentArea);
void ReparentViews(DisplayZTreeNode* aNode);
void BuildDisplayList(nsView* aView, const nsRect& aRect, PRBool aEventProcessing, PRBool aCaptured);
void BuildDisplayList(nsView* aView, const nsRect& aRect, PRBool aEventProcessing,
PRBool aCaptured, nsAutoVoidArray* aDisplayList);
void BuildEventTargetList(nsAutoVoidArray &aTargets, nsView* aView, nsGUIEvent* aEvent, PRBool aCaptured);
PRBool CreateDisplayList(nsView *aView, PRBool aReparentedViewsPresent, DisplayZTreeNode* &aResult, nscoord aOriginX, nscoord aOriginY,
PRBool CreateDisplayList(nsView *aView,
PRBool aReparentedViewsPresent, DisplayZTreeNode* &aResult,
nscoord aOriginX, nscoord aOriginY,
PRBool aInsideRealView, nsView *aRealView, const nsRect *aDamageRect,
nsView *aTopView, nscoord aX, nscoord aY, PRBool aPaintFloaters, PRBool aEventProcessing);
PRBool AddToDisplayList(nsView *aView, DisplayZTreeNode* &aParent, nsRect &aClipRect,
nsRect& aDirtyRect, PRUint32 aFlags, nscoord aAbsX, nscoord aAbsY, PRBool aAssumeIntersection);
void ReapplyClipInstructions(PRBool aHaveClip, nsRect& aClipRect, PRInt32& aIndex);
nsresult OptimizeDisplayList(const nsRegion& aDirtyRegion,
nsRect& aFinalTransparentRect, nsRegion& aOpaqueRgn);
nsView *aTopView, nscoord aX, nscoord aY,
PRBool aPaintFloaters, PRBool aEventProcessing);
PRBool AddToDisplayList(nsView *aView,
DisplayZTreeNode* &aParent, nsRect &aClipRect,
nsRect& aDirtyRect, PRUint32 aFlags, nscoord aAbsX, nscoord aAbsY,
PRBool aAssumeIntersection);
void OptimizeDisplayList(nsAutoVoidArray* aDisplayList, const nsRegion& aDirtyRegion,
nsRect& aFinalTransparentRect, nsRegion& aOpaqueRgn);
// Remove redundant PUSH/POP_CLIP pairs.
void ComputeViewOffset(nsView *aView, nsPoint *aOrigin);
@ -294,11 +299,10 @@ private:
void PauseTimer(void);
void RestartTimer(void);
void OptimizeDisplayListClipping(PRBool aHaveClip, nsRect& aClipRect, PRInt32& aIndex,
void OptimizeDisplayListClipping(nsAutoVoidArray* aDisplayList, PRBool aHaveClip,
nsRect& aClipRect, PRInt32& aIndex,
PRBool& aAnyRendered);
#ifdef NS_DEBUG
void ShowDisplayList(PRInt32 flatlen);
#endif
void ShowDisplayList(nsAutoVoidArray* aDisplayList);
// Utilities
@ -375,7 +379,6 @@ private:
float mPixelsToTwips;
nsIViewObserver *mObserver;
nsIWidget *mRootWindow;
PRInt32 mTransCnt;
PRBool mRefreshEnabled;
PRBool mPainting;
PRBool mRecursiveRefreshPending;
@ -383,10 +386,6 @@ private:
nsView *mKeyGrabber;
PRInt32 mUpdateCnt;
PRInt32 mUpdateBatchCnt;
PRInt32 mDisplayListCount;
nsAutoVoidArray mDisplayList;
PRInt32 mTranslucentViewCount;
nsRect mTranslucentArea; // bounding box of all translucent views.
nsIScrollableView *mRootScrollable;
PRInt32 mCachingWidgetChanges;
nscolor mDefaultBackgroundColor;