зеркало из https://github.com/mozilla/gecko-dev.git
Bug 165149. Make children of a scrolled element inherit style directly from the element instead of via the scrolled frames. Add a new view property to indicate that the view is painted on a uniform background and use it to optimize scrolling, so that a scrolled element with a uniform background color can still be scrolled using bitblits. r+sr=dbaron
This commit is contained in:
Родитель
886718db18
Коммит
7eecd9a0ef
|
@ -6617,6 +6617,15 @@ nsCSSFrameConstructor::ResolveStyleContext(nsIPresContext* aPresContext,
|
|||
// Resolve the style context based on the content object and the parent
|
||||
// style context
|
||||
nsStyleContext* parentStyleContext = aParentFrame->GetStyleContext();
|
||||
|
||||
// skip past any parents that are scrolled-content. We want to inherit directly
|
||||
// from the outer scroll frame.
|
||||
nsCOMPtr<nsIAtom> pseudo;
|
||||
while (parentStyleContext && (pseudo = parentStyleContext->GetPseudoType()) ==
|
||||
nsCSSAnonBoxes::scrolledContent) {
|
||||
parentStyleContext = parentStyleContext->GetParent();
|
||||
}
|
||||
|
||||
if (aContent->IsContentOfType(nsIContent::eELEMENT)) {
|
||||
return aPresContext->ResolveStyleContextFor(aContent, parentStyleContext);
|
||||
} else {
|
||||
|
|
|
@ -548,11 +548,41 @@ SyncFrameViewGeometryDependentProperties(nsIPresContext* aPresContext,
|
|||
// view's contents should be repainted and not bitblt'd
|
||||
vm->SetViewBitBltEnabled(aView, !fixedBackground);
|
||||
|
||||
nsCOMPtr<nsIAtom> pseudo = aFrame->GetStyleContext()->GetPseudoType();
|
||||
|
||||
// If the frame has a solid background color, 'background-clip:border',
|
||||
// and it's a kind of frame that paints its background, and rounded borders aren't
|
||||
// clipping the background, then it's opaque.
|
||||
PRBool viewHasTransparentContent =
|
||||
!hasBG ||
|
||||
(bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) ||
|
||||
!aFrame->CanPaintBackground() ||
|
||||
HasNonZeroBorderRadius(aStyleContext);
|
||||
!(hasBG && !(bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) &&
|
||||
bg->mBackgroundClip == NS_STYLE_BG_CLIP_BORDER &&
|
||||
aFrame->CanPaintBackground() &&
|
||||
!HasNonZeroBorderRadius(aStyleContext));
|
||||
|
||||
PRBool drawnOnUniformField = PR_FALSE;
|
||||
if (pseudo == nsCSSAnonBoxes::scrolledContent) {
|
||||
// If the nsGfxScrollFrame draws a solid unclipped background
|
||||
// color, and nothing else, then tell the view system that we're
|
||||
// drawn on a uniform field. Note that it's OK if the background
|
||||
// is clipped to the padding area, since the scrollport is within
|
||||
// the borders.
|
||||
nsIFrame* scrollFrame = aFrame->GetParent();
|
||||
nsCOMPtr<nsIAtom> parentPseudo;
|
||||
while ((parentPseudo = scrollFrame->GetStyleContext()->GetPseudoType())
|
||||
== nsCSSAnonBoxes::scrolledContent) {
|
||||
scrollFrame = scrollFrame->GetParent();
|
||||
}
|
||||
PRBool scrollFrameIsCanvas;
|
||||
const nsStyleBackground* scrollFrameBG;
|
||||
PRBool scrollFrameHasBG =
|
||||
nsCSSRendering::FindBackground(aPresContext, scrollFrame, &scrollFrameBG,
|
||||
&scrollFrameIsCanvas);
|
||||
drawnOnUniformField = scrollFrameHasBG &&
|
||||
!(scrollFrameBG->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) &&
|
||||
(scrollFrameBG->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) &&
|
||||
!HasNonZeroBorderRadius(scrollFrame->GetStyleContext());
|
||||
}
|
||||
aView->SetHasUniformBackground(drawnOnUniformField);
|
||||
|
||||
if (isCanvas) {
|
||||
nsIView* rootView;
|
||||
|
|
|
@ -4437,6 +4437,9 @@ GetNextSiblingAcrossLines(nsIPresContext *aPresContext, nsIFrame *aFrame)
|
|||
*
|
||||
* Also correct for the frame tree mangling that happens when we create
|
||||
* wrappers for :before/:after.
|
||||
*
|
||||
* Also skip anonymous scrolled-content parents; inherit directly from the
|
||||
* outer scroll frame.
|
||||
*/
|
||||
static nsresult
|
||||
GetCorrectedParent(nsIPresContext* aPresContext, nsIFrame* aFrame,
|
||||
|
@ -4462,6 +4465,19 @@ GetCorrectedParent(nsIPresContext* aPresContext, nsIFrame* aFrame,
|
|||
} else {
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
parentPseudo = parent->GetStyleContext()->GetPseudoType();
|
||||
}
|
||||
|
||||
// if this frame itself is not scrolled-content, then skip any scrolled-content
|
||||
// parents since they're basically anonymous as far as the style system goes
|
||||
if (parentPseudo == nsCSSAnonBoxes::scrolledContent) {
|
||||
nsCOMPtr<nsIAtom> pseudo = aFrame->GetStyleContext()->GetPseudoType();
|
||||
if (pseudo != nsCSSAnonBoxes::scrolledContent) {
|
||||
do {
|
||||
parent = parent->GetParent();
|
||||
parentPseudo = parent->GetStyleContext()->GetPseudoType();
|
||||
} while (parentPseudo == nsCSSAnonBoxes::scrolledContent);
|
||||
}
|
||||
}
|
||||
|
||||
if (parent->GetStateBits() & NS_FRAME_IS_SPECIAL) {
|
||||
|
|
|
@ -548,11 +548,41 @@ SyncFrameViewGeometryDependentProperties(nsIPresContext* aPresContext,
|
|||
// view's contents should be repainted and not bitblt'd
|
||||
vm->SetViewBitBltEnabled(aView, !fixedBackground);
|
||||
|
||||
nsCOMPtr<nsIAtom> pseudo = aFrame->GetStyleContext()->GetPseudoType();
|
||||
|
||||
// If the frame has a solid background color, 'background-clip:border',
|
||||
// and it's a kind of frame that paints its background, and rounded borders aren't
|
||||
// clipping the background, then it's opaque.
|
||||
PRBool viewHasTransparentContent =
|
||||
!hasBG ||
|
||||
(bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) ||
|
||||
!aFrame->CanPaintBackground() ||
|
||||
HasNonZeroBorderRadius(aStyleContext);
|
||||
!(hasBG && !(bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) &&
|
||||
bg->mBackgroundClip == NS_STYLE_BG_CLIP_BORDER &&
|
||||
aFrame->CanPaintBackground() &&
|
||||
!HasNonZeroBorderRadius(aStyleContext));
|
||||
|
||||
PRBool drawnOnUniformField = PR_FALSE;
|
||||
if (pseudo == nsCSSAnonBoxes::scrolledContent) {
|
||||
// If the nsGfxScrollFrame draws a solid unclipped background
|
||||
// color, and nothing else, then tell the view system that we're
|
||||
// drawn on a uniform field. Note that it's OK if the background
|
||||
// is clipped to the padding area, since the scrollport is within
|
||||
// the borders.
|
||||
nsIFrame* scrollFrame = aFrame->GetParent();
|
||||
nsCOMPtr<nsIAtom> parentPseudo;
|
||||
while ((parentPseudo = scrollFrame->GetStyleContext()->GetPseudoType())
|
||||
== nsCSSAnonBoxes::scrolledContent) {
|
||||
scrollFrame = scrollFrame->GetParent();
|
||||
}
|
||||
PRBool scrollFrameIsCanvas;
|
||||
const nsStyleBackground* scrollFrameBG;
|
||||
PRBool scrollFrameHasBG =
|
||||
nsCSSRendering::FindBackground(aPresContext, scrollFrame, &scrollFrameBG,
|
||||
&scrollFrameIsCanvas);
|
||||
drawnOnUniformField = scrollFrameHasBG &&
|
||||
!(scrollFrameBG->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) &&
|
||||
(scrollFrameBG->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) &&
|
||||
!HasNonZeroBorderRadius(scrollFrame->GetStyleContext());
|
||||
}
|
||||
aView->SetHasUniformBackground(drawnOnUniformField);
|
||||
|
||||
if (isCanvas) {
|
||||
nsIView* rootView;
|
||||
|
|
|
@ -4437,6 +4437,9 @@ GetNextSiblingAcrossLines(nsIPresContext *aPresContext, nsIFrame *aFrame)
|
|||
*
|
||||
* Also correct for the frame tree mangling that happens when we create
|
||||
* wrappers for :before/:after.
|
||||
*
|
||||
* Also skip anonymous scrolled-content parents; inherit directly from the
|
||||
* outer scroll frame.
|
||||
*/
|
||||
static nsresult
|
||||
GetCorrectedParent(nsIPresContext* aPresContext, nsIFrame* aFrame,
|
||||
|
@ -4462,6 +4465,19 @@ GetCorrectedParent(nsIPresContext* aPresContext, nsIFrame* aFrame,
|
|||
} else {
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
parentPseudo = parent->GetStyleContext()->GetPseudoType();
|
||||
}
|
||||
|
||||
// if this frame itself is not scrolled-content, then skip any scrolled-content
|
||||
// parents since they're basically anonymous as far as the style system goes
|
||||
if (parentPseudo == nsCSSAnonBoxes::scrolledContent) {
|
||||
nsCOMPtr<nsIAtom> pseudo = aFrame->GetStyleContext()->GetPseudoType();
|
||||
if (pseudo != nsCSSAnonBoxes::scrolledContent) {
|
||||
do {
|
||||
parent = parent->GetParent();
|
||||
parentPseudo = parent->GetStyleContext()->GetPseudoType();
|
||||
} while (parentPseudo == nsCSSAnonBoxes::scrolledContent);
|
||||
}
|
||||
}
|
||||
|
||||
if (parent->GetStateBits() & NS_FRAME_IS_SPECIAL) {
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
|
||||
*|*::-moz-scrolled-content {
|
||||
/* e.g., text inputs, select boxes */
|
||||
background: inherit;
|
||||
padding: inherit;
|
||||
display: inherit;
|
||||
-moz-box-orient: inherit;
|
||||
|
|
|
@ -6617,6 +6617,15 @@ nsCSSFrameConstructor::ResolveStyleContext(nsIPresContext* aPresContext,
|
|||
// Resolve the style context based on the content object and the parent
|
||||
// style context
|
||||
nsStyleContext* parentStyleContext = aParentFrame->GetStyleContext();
|
||||
|
||||
// skip past any parents that are scrolled-content. We want to inherit directly
|
||||
// from the outer scroll frame.
|
||||
nsCOMPtr<nsIAtom> pseudo;
|
||||
while (parentStyleContext && (pseudo = parentStyleContext->GetPseudoType()) ==
|
||||
nsCSSAnonBoxes::scrolledContent) {
|
||||
parentStyleContext = parentStyleContext->GetParent();
|
||||
}
|
||||
|
||||
if (aContent->IsContentOfType(nsIContent::eELEMENT)) {
|
||||
return aPresContext->ResolveStyleContextFor(aContent, parentStyleContext);
|
||||
} else {
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
|
||||
*|*::-moz-scrolled-content {
|
||||
/* e.g., text inputs, select boxes */
|
||||
background: inherit;
|
||||
padding: inherit;
|
||||
display: inherit;
|
||||
-moz-box-orient: inherit;
|
||||
|
|
|
@ -74,6 +74,10 @@ enum nsViewVisibility {
|
|||
//the view is transparent
|
||||
#define NS_VIEW_FLAG_TRANSPARENT 0x0004
|
||||
|
||||
// The view is always painted onto a background consisting
|
||||
// of a uniform field of opaque pixels.
|
||||
#define NS_VIEW_FLAG_UNIFORM_BACKGROUND 0x0008
|
||||
|
||||
//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
|
||||
|
@ -244,6 +248,23 @@ public:
|
|||
*/
|
||||
float GetOpacity() const { return mOpacity; }
|
||||
|
||||
/**
|
||||
* Indicate that this view is always painted onto a uniform field of pixels. Thus,
|
||||
* even if the view is transparent, it may still be bitblit scrollable because
|
||||
* the background that shines through does not vary with position.
|
||||
*/
|
||||
void SetHasUniformBackground(PRBool aUniform) {
|
||||
if (aUniform) {
|
||||
mVFlags |= NS_VIEW_FLAG_UNIFORM_BACKGROUND;
|
||||
} else {
|
||||
mVFlags &= ~NS_VIEW_FLAG_UNIFORM_BACKGROUND;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool HasUniformBackground() {
|
||||
return mVFlags & NS_VIEW_FLAG_UNIFORM_BACKGROUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the view's link to client owned data.
|
||||
* @param aData - data to associate with view. nsnull to disassociate
|
||||
|
|
|
@ -1135,7 +1135,7 @@ void nsViewManager::RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
|
|||
AddCoveringWidgetsToOpaqueRegion(opaqueRgn, mContext, aRootView);
|
||||
|
||||
nsRect finalTransparentRect;
|
||||
OptimizeDisplayList(&displayList, aRegion, finalTransparentRect, opaqueRgn);
|
||||
OptimizeDisplayList(&displayList, aRegion, finalTransparentRect, opaqueRgn, PR_FALSE);
|
||||
|
||||
#ifdef DEBUG_roc
|
||||
// ShowDisplayList(&displayList);
|
||||
|
@ -2867,13 +2867,22 @@ PRBool nsViewManager::CanScrollWithBitBlt(nsView* aView)
|
|||
}
|
||||
}
|
||||
|
||||
// We DO need to use OptimizeDisplayList here to eliminate views that are covered by views we know
|
||||
// are opaque. Typically aView itself is opaque and we want to eliminate views behind aView, such as
|
||||
// aView's parent, that aren't being scrolled and would otherwise cause us to decide not to blit.
|
||||
// We DO need to use OptimizeDisplayList here to eliminate views
|
||||
// that are covered by views we know are opaque. Typically aView's
|
||||
// scrolled view is opaque and we want to eliminate views behind it,
|
||||
// such as aView itself, that aren't being moved and would otherwise
|
||||
// cause us to decide not to blit. Note that if for some view,
|
||||
// view->HasUniformBackground(), that's also sufficient to ignore
|
||||
// views behind 'view'; we've been promised that they produce only a
|
||||
// uniform background, which is still blittable. So we can treat
|
||||
// 'view' as opaque.
|
||||
|
||||
// (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(&displayList, nsRegion(r), finalTransparentRect, opaqueRegion);
|
||||
// (Note that it's possible for aView's parent to actually be 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(&displayList, nsRegion(r), finalTransparentRect, opaqueRegion, PR_TRUE);
|
||||
|
||||
PRBool anyUnscrolledViews = PR_FALSE;
|
||||
PRBool anyUnblittableViews = PR_FALSE;
|
||||
|
@ -3613,7 +3622,7 @@ PRBool nsViewManager::AddToDisplayList(nsView *aView,
|
|||
*/
|
||||
void nsViewManager::OptimizeDisplayList(nsAutoVoidArray* aDisplayList, const nsRegion& aDamageRegion,
|
||||
nsRect& aFinalTransparentRect,
|
||||
nsRegion &aOpaqueRegion)
|
||||
nsRegion &aOpaqueRegion, PRBool aTreatUniformAsOpaque)
|
||||
{
|
||||
for (PRInt32 i = aDisplayList->Count() - 1; i >= 0; i--) {
|
||||
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, aDisplayList->ElementAt(i));
|
||||
|
@ -3628,7 +3637,8 @@ void nsViewManager::OptimizeDisplayList(nsAutoVoidArray* aDisplayList, const nsR
|
|||
element->mBounds = tmpRgn.GetBounds();
|
||||
|
||||
// a view is opaque if it is neither transparent nor transluscent
|
||||
if (!(element->mFlags & (VIEW_TRANSPARENT | VIEW_TRANSLUCENT))) {
|
||||
if (!(element->mFlags & (VIEW_TRANSPARENT | VIEW_TRANSLUCENT))
|
||||
|| (element->mView->HasUniformBackground() && aTreatUniformAsOpaque)) {
|
||||
aOpaqueRegion.Or(aOpaqueRegion, element->mBounds);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -282,7 +282,8 @@ private:
|
|||
nsRect& aDirtyRect, PRUint32 aFlags, nscoord aAbsX, nscoord aAbsY,
|
||||
PRBool aAssumeIntersection);
|
||||
void OptimizeDisplayList(nsAutoVoidArray* aDisplayList, const nsRegion& aDirtyRegion,
|
||||
nsRect& aFinalTransparentRect, nsRegion& aOpaqueRgn);
|
||||
nsRect& aFinalTransparentRect, nsRegion& aOpaqueRgn,
|
||||
PRBool aTreatUniformAsOpaque);
|
||||
// Remove redundant PUSH/POP_CLIP pairs.
|
||||
void ComputeViewOffset(nsView *aView, nsPoint *aOrigin);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче