Backing out 99f6b3acc464 (bug 618975). Bug This caused a reftest crash. a=bustage

This commit is contained in:
Doug Turner
2011-03-08 22:02:50 -08:00
parent f43a11bf76
commit 80caa5bb4e
13 changed files with 152 additions and 259 deletions

View File

@@ -1749,7 +1749,6 @@ GK_ATOM(DeleteTxnName, "Deleting")
// IPC stuff
GK_ATOM(Remote, "remote")
GK_ATOM(RemoteId, "_remote_id")
GK_ATOM(DisplayPort, "_displayport")
// Names for system metrics
GK_ATOM(scrollbar_start_backward, "scrollbar-start-backward")

View File

@@ -48,7 +48,6 @@
#include "nsFocusManager.h"
#include "nsIEventStateManager.h"
#include "nsEventStateManager.h"
#include "nsFrameManager.h"
#include "nsIScrollableFrame.h"
@@ -259,25 +258,9 @@ nsDOMWindowUtils::SetCSSViewport(float aWidthPx, float aHeightPx)
return NS_OK;
}
static void DestroyNsRect(void* aObject, nsIAtom* aPropertyName,
void* aPropertyValue, void* aData)
{
nsRect* rect = static_cast<nsRect*>(aPropertyValue);
delete rect;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetDisplayPort(float aXPx, float aYPx,
float aWidthPx, float aHeightPx)
{
NS_ABORT_IF_FALSE(false, "This interface is deprecated.");
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
float aWidthPx, float aHeightPx,
nsIDOMElement* aElement)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
@@ -292,58 +275,9 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
nsPresContext::CSSPixelsToAppUnits(aYPx),
nsPresContext::CSSPixelsToAppUnits(aWidthPx),
nsPresContext::CSSPixelsToAppUnits(aHeightPx));
presShell->SetDisplayPort(displayport);
if (!aElement) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
if (!content) {
return NS_ERROR_INVALID_ARG;
}
nsRect lastDisplayPort;
if (nsLayoutUtils::GetDisplayPort(content, &lastDisplayPort) &&
displayport == lastDisplayPort) {
return NS_OK;
}
content->SetProperty(nsGkAtoms::DisplayPort, new nsRect(displayport),
DestroyNsRect);
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
if (rootScrollFrame) {
if (content == rootScrollFrame->GetContent()) {
// We are setting the root displayport. The pres context needs a special
// flag to be set.
presShell->SetIgnoreViewportScrolling(PR_TRUE);
}
}
// FIXME (Bug 593243 should fix this.)
//
// Invalidated content does not pay any attention to the displayport, so
// invalidating the subdocument's root frame could end up not repainting
// visible content.
//
// For instance, imagine the iframe is located at y=1000. Even though the
// displayport may intersect the iframe's viewport, the visual overflow
// rect of the root content could be (0, 0, 800, 500). Since the dirty region
// does not intersect the visible overflow rect, the display list for the
// iframe will not even be generated.
//
// Here, we find the very top presShell and use its root frame for
// invalidation instead.
//
nsPresContext* rootPresContext = GetPresContext()->GetRootPresContext();
if (rootPresContext) {
nsIPresShell* rootPresShell = rootPresContext->GetPresShell();
nsIFrame* rootFrame = rootPresShell->FrameManager()->GetRootFrame();
if (rootFrame) {
rootFrame->InvalidateFrameSubtree();
}
}
presShell->SetIgnoreViewportScrolling(PR_TRUE);
return NS_OK;
}

View File

@@ -129,7 +129,30 @@ interface nsIDOMWindowUtils : nsISupports {
void setCSSViewport(in float aWidthPx, in float aHeightPx);
/**
* @DEPRECATED See nsIDOMWindowUtils_MOZILLA_2_0_BRANCH.
* Set the "displayport" to be <xPx, yPx, widthPx, heightPx> in
* units of CSS pixels, regardless of the size of the enclosing
* widget/view. This will *not* trigger reflow.
*
* <x, y> is relative to the top-left of the CSS viewport. This
* means that the pixels rendered to the displayport take scrolling
* into account, for example.
*
* The displayport will be used as the window's visible region for
* the purposes of invalidation and painting. The displayport can
* approximately be thought of as a "persistent" drawWindow()
* (albeit with coordinates relative to the CSS viewport): the
* bounds are remembered by the platform, and layer pixels are
* retained and updated inside the viewport bounds.
*
* It's legal to set a displayport that extends beyond the CSS
* viewport in any direction (left/right/top/bottom).
*
* It's also legal to set a displayport that extends beyond the
* document's bounds. The value of the pixels rendered outside the
* document bounds is not yet defined.
*
* The caller of this method must have UniversalXPConnect
* privileges.
*/
void setDisplayPort(in float aXPx, in float aYPx,
in float aWidthPx, in float aHeightPx);
@@ -801,7 +824,7 @@ interface nsIDOMWindowUtils : nsISupports {
typedef unsigned long long nsViewID;
[scriptable, uuid(7ad49829-e631-4cdd-a237-95847d9bcbe6)]
[scriptable, uuid(be2e28c8-64f8-4100-906d-8a451ddd6835)]
interface nsIDOMWindowUtils_MOZILLA_2_0_BRANCH : nsISupports {
/**
* Get the type of the currently focused html input, if any.
@@ -815,36 +838,6 @@ interface nsIDOMWindowUtils_MOZILLA_2_0_BRANCH : nsISupports {
*/
nsIDOMElement findElementWithViewId(in nsViewID aId);
/**
* For any scrollable element, this allows you to override the
* visible region and draw more than what is visible, which is
* useful for asynchronous drawing. The "displayport" will be
* <xPx, yPx, widthPx, heightPx> in units of CSS pixels,
* regardless of the size of the enclosing container. This
* will *not* trigger reflow.
*
* For the root scroll area, pass in the root document element.
* For scrollable elements, pass in the container element (for
* instance, the element with overflow: scroll).
*
* <x, y> is relative to the top-left of what would normally be
* the visible area of the element. This means that the pixels
* rendered to the displayport take scrolling into account,
* for example.
*
* It's legal to set a displayport that extends beyond the overflow
* area in any direction (left/right/top/bottom).
*
* It's also legal to set a displayport that extends beyond the
* area's bounds. No pixels are rendered outside the area bounds.
*
* The caller of this method must have UniversalXPConnect
* privileges.
*/
void setDisplayPortForElement(in float aXPx, in float aYPx,
in float aWidthPx, in float aHeightPx,
in nsIDOMElement aElement);
/**
* Same as enterModalState, but returns the window associated with the
* current JS context.

View File

@@ -1252,8 +1252,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
item->GetLayerState(mBuilder, mManager);
// Assign the item to a layer
if (layerState == LAYER_ACTIVE_FORCE ||
layerState == LAYER_ACTIVE && (aClip.mRoundedClipRects.IsEmpty() ||
if (layerState == LAYER_ACTIVE && (aClip.mRoundedClipRects.IsEmpty() ||
// We can use the visible rect here only because the item has its own
// layer, like the comment below.
!aClip.IsRectClippedByRoundedCorner(item->GetVisibleRect()))) {

View File

@@ -56,10 +56,7 @@ namespace mozilla {
enum LayerState {
LAYER_NONE,
LAYER_INACTIVE,
LAYER_ACTIVE,
// Force an active layer even if it causes incorrect rendering, e.g.
// when the layer has rounded rect clips.
LAYER_ACTIVE_FORCE
LAYER_ACTIVE
};
/**

View File

@@ -149,13 +149,12 @@ static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
}
static void RecordFrameMetrics(nsIFrame* aForFrame,
nsIFrame* aViewportFrame,
ContainerLayer* aRoot,
nsRect aVisibleRect,
nsRect aViewport,
nsRect aDisplayPort,
ViewID aScrollId) {
nsPresContext* presContext = aForFrame->PresContext();
nsIPresShell* presShell = presContext->GetPresShell();
nsIntRect visible = aVisibleRect.ToNearestPixels(presContext->AppUnitsPerDevPixel());
aRoot->SetVisibleRegion(nsIntRegion(visible));
@@ -164,23 +163,23 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
PRInt32 auPerDevPixel = presContext->AppUnitsPerDevPixel();
metrics.mViewport = aViewport.ToNearestPixels(auPerDevPixel);
if (aViewport != aDisplayPort) {
metrics.mDisplayPort = aDisplayPort.ToNearestPixels(auPerDevPixel);
if (presShell->UsingDisplayPort()) {
metrics.mDisplayPort =
presShell->GetDisplayPort().ToNearestPixels(auPerDevPixel);
}
nsIScrollableFrame* scrollableFrame = NULL;
if (aViewportFrame)
scrollableFrame = aViewportFrame->GetScrollTargetFrame();
if (scrollableFrame) {
nsSize contentSize =
scrollableFrame->GetScrollRange().Size() +
scrollableFrame->GetScrollPortRect().Size();
nsIScrollableFrame* rootScrollableFrame =
presShell->GetRootScrollFrameAsScrollable();
if (rootScrollableFrame) {
nsSize contentSize =
rootScrollableFrame->GetScrollRange().Size() +
rootScrollableFrame->GetScrollPortRect().Size();
metrics.mContentSize = nsIntSize(NSAppUnitsToIntPixels(contentSize.width, auPerDevPixel),
NSAppUnitsToIntPixels(contentSize.height, auPerDevPixel));
metrics.mViewportScrollOffset =
scrollableFrame->GetScrollPosition().ToNearestPixels(auPerDevPixel);
rootScrollableFrame->GetScrollPosition().ToNearestPixels(auPerDevPixel);
}
else {
nsSize contentSize = aForFrame->GetSize();
@@ -524,18 +523,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID
: FrameMetrics::NULL_SCROLL_ID;
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
nsRect visibleRect = mVisibleRect;
if (rootScrollFrame) {
nsIContent* content = rootScrollFrame->GetContent();
if (content) {
// If there is a displayport defined for the root content element,
// it will be stored in visibleRect.
nsLayoutUtils::GetDisplayPort(content, &visibleRect);
}
}
RecordFrameMetrics(aForFrame, presShell->GetRootScrollFrame(),
root, mVisibleRect, mVisibleRect, visibleRect, id);
RecordFrameMetrics(aForFrame, root, mVisibleRect, mVisibleRect, id);
// If the layer manager supports resolution scaling, set that up
if (LayerManager::LAYERS_BASIC == layerManager->GetBackendType()) {
@@ -1706,11 +1694,9 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
nsDisplayList* aList,
nsIFrame* aForFrame,
nsIFrame* aViewportFrame,
const nsRect& aDisplayPort)
nsIFrame* aViewportFrame)
: nsDisplayOwnLayer(aBuilder, aForFrame, aList)
, mViewportFrame(aViewportFrame)
, mDisplayPort(aDisplayPort)
{
#ifdef NS_BUILD_REFCNT_LOGGING
MOZ_COUNT_CTOR(nsDisplayScrollLayer);
@@ -1735,8 +1721,7 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
mViewportFrame->GetPosition() +
aBuilder->ToReferenceFrame(mViewportFrame);
RecordFrameMetrics(mFrame, mViewportFrame, layer, mVisibleRect, viewport,
mDisplayPort, scrollId);
RecordFrameMetrics(mFrame, layer, mVisibleRect, viewport, scrollId);
return layer.forget();
}
@@ -1748,17 +1733,14 @@ nsDisplayScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder,
PRBool& aContainsRootContentDocBG)
{
nsPresContext* presContext = mFrame->PresContext();
nsIPresShell* presShell = presContext->GetPresShell();
nsRect viewport = mViewportFrame->GetRect() -
mViewportFrame->GetPosition() +
aBuilder->ToReferenceFrame(mViewportFrame);
if (mDisplayPort != viewport) {
if (presShell->UsingDisplayPort()) {
// The visible region for the children may be much bigger than the hole we
// are viewing the children from, so that the compositor process has enough
// content to asynchronously pan while content is being refreshed.
nsRegion childVisibleRegion = mDisplayPort + aBuilder->ToReferenceFrame(mViewportFrame);
nsRegion childVisibleRegion = presShell->GetDisplayPort() + aBuilder->ToReferenceFrame(mViewportFrame);
nsRect boundedRect;
boundedRect.IntersectRect(childVisibleRegion.GetBounds(), mList.GetBounds(aBuilder));

View File

@@ -1790,12 +1790,9 @@ public:
* @param aForFrame This will determine what the displayport is. It should be
* the root content frame of the scrolled area.
* @param aViewportFrame The viewport frame you see this content through.
* @param aDisplayPort Overrides the visibility of the child items if it
* is not equal to the visible area.
*/
nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
nsIFrame* aForFrame, nsIFrame* aViewportFrame,
const nsRect& aDisplayPort);
nsIFrame* aForFrame, nsIFrame* aViewportFrame);
NS_DISPLAY_DECL_NAME("ScrollLayer", TYPE_SCROLL_LAYER)
#ifdef NS_BUILD_REFCNT_LOGGING
@@ -1810,16 +1807,8 @@ public:
const nsRect& aAllowVisibleRegionExpansion,
PRBool& aContainsRootContentDocBG);
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager)
{
// Force this as a layer so we can scroll asynchronously.
// This causes incorrect rendering for rounded clips!
return mozilla::LAYER_ACTIVE_FORCE;
}
private:
nsIFrame* mViewportFrame;
nsRect mDisplayPort;
};
#endif

View File

@@ -1154,21 +1154,19 @@ public:
* Set up a "displayport", which overrides what everything else thinks
* is the visible region of this document with the specified
* displayport rect.
* @DEPRECATED Use nsLayoutUtils displayport methods
*/
virtual void SetDisplayPort(const nsRect& aDisplayPort) = 0;
PRBool UsingDisplayPort() const
{ NS_ABORT_IF_FALSE(false, "UsingDisplayPort is deprecated"); return false; }
{ return mRenderFlags & STATE_USING_DISPLAYPORT; }
/**
* Return the displayport being used. |UsingDisplayPort()| must be
* true.
* @DEPRECATED Use nsLayoutUtils displayport methods
*/
nsRect GetDisplayPort()
{
NS_ABORT_IF_FALSE(false, "GetDisplayPort is deprecated");
return nsRect();
NS_ABORT_IF_FALSE(UsingDisplayPort(), "no displayport defined!");
return mDisplayPort;
}
/**

View File

@@ -143,10 +143,6 @@ static void DestroyViewID(void* aObject, nsIAtom* aPropertyName,
delete id;
}
/**
* A namespace class for static layout utilities.
*/
ViewID
nsLayoutUtils::FindIDFor(nsIContent* aContent)
{
@@ -181,19 +177,9 @@ nsLayoutUtils::FindContentFor(ViewID aId)
}
}
bool
nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
{
void* property = aContent->GetProperty(nsGkAtoms::DisplayPort);
if (!property) {
return false;
}
if (aResult) {
*aResult = *static_cast<nsRect*>(property);
}
return true;
}
/**
* A namespace class for static layout utilities.
*/
nsIFrame*
nsLayoutUtils::GetLastContinuationWithChild(nsIFrame* aFrame)
@@ -1382,16 +1368,6 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
nsPresContext* presContext = aFrame->PresContext();
nsIPresShell* presShell = presContext->PresShell();
nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
bool usingDisplayPort = false;
nsRect displayport;
if (rootScrollFrame) {
nsIContent* content = rootScrollFrame->GetContent();
if (content) {
usingDisplayPort = nsLayoutUtils::GetDisplayPort(content, &displayport);
}
}
PRBool ignoreViewportScrolling = presShell->IgnoringViewportScrolling();
nsRegion visibleRegion;
if (aFlags & PAINT_WIDGET_LAYERS) {
@@ -1401,10 +1377,10 @@ nsLayoutUtils::PaintFrame(nsIRenderingContext* aRenderingContext, nsIFrame* aFra
// |ignoreViewportScrolling| and |usingDisplayPort| are persistent
// document-rendering state. We rely on PresShell to flush
// retained layers as needed when that persistent state changes.
if (!usingDisplayPort) {
if (!presShell->UsingDisplayPort()) {
visibleRegion = aFrame->GetVisualOverflowRectRelativeToSelf();
} else {
visibleRegion = displayport;
visibleRegion = presShell->GetDisplayPort();
}
} else {
visibleRegion = aDirtyRegion;

View File

@@ -94,11 +94,6 @@ public:
*/
static nsIContent* FindContentFor(ViewID aId);
/**
* Get display port for the given element.
*/
static bool GetDisplayPort(nsIContent* aContent, nsRect *aResult);
/**
* Use heuristics to figure out the name of the child list that
* aChildFrame is currently in.

View File

@@ -1037,10 +1037,12 @@ protected:
struct RenderingState {
RenderingState(PresShell* aPresShell)
: mRenderFlags(aPresShell->mRenderFlags)
, mDisplayPort(aPresShell->mDisplayPort)
, mXResolution(aPresShell->mXResolution)
, mYResolution(aPresShell->mYResolution)
{ }
PRUint32 mRenderFlags;
nsRect mDisplayPort;
float mXResolution;
float mYResolution;
};
@@ -1054,6 +1056,7 @@ protected:
~AutoSaveRestoreRenderingState()
{
mPresShell->mRenderFlags = mOldState.mRenderFlags;
mPresShell->mDisplayPort = mOldState.mDisplayPort;
mPresShell->mXResolution = mOldState.mXResolution;
mPresShell->mYResolution = mOldState.mYResolution;
}
@@ -6014,7 +6017,14 @@ void PresShell::SetIgnoreViewportScrolling(PRBool aIgnore)
void PresShell::SetDisplayPort(const nsRect& aDisplayPort)
{
NS_ABORT_IF_FALSE(false, "SetDisplayPort is deprecated");
if (UsingDisplayPort() && mDisplayPort == aDisplayPort) {
return;
}
RenderingState state(this);
state.mRenderFlags = ChangeFlag(mRenderFlags, PR_TRUE,
STATE_USING_DISPLAYPORT);
state.mDisplayPort = aDisplayPort;
SetRenderingState(state);
}
nsresult PresShell::SetResolution(float aXResolution, float aYResolution)
@@ -6044,8 +6054,37 @@ void PresShell::SetRenderingState(const RenderingState& aState)
}
mRenderFlags = aState.mRenderFlags;
if (UsingDisplayPort()) {
mDisplayPort = aState.mDisplayPort;
} else {
mDisplayPort = nsRect();
}
mXResolution = aState.mXResolution;
mYResolution = aState.mYResolution;
// FIXME (Bug 593243 should fix this.)
//
// Invalidated content does not pay any attention to the displayport, so
// invalidating the subdocument's root frame could end up not repainting
// visible content.
//
// For instance, imagine the iframe is located at y=1000. Even though the
// displayport may intersect the iframe's viewport, the visual overflow
// rect of the root content could be (0, 0, 800, 500). Since the dirty region
// does not intersect the visible overflow rect, the display list for the
// iframe will not even be generated.
//
// Here, we find the very top presShell and use its root frame for
// invalidation instead.
//
nsPresContext* rootPresContext = mPresContext->GetRootPresContext();
if (rootPresContext) {
nsIPresShell* rootPresShell = rootPresContext->GetPresShell();
nsIFrame* rootFrame = rootPresShell->FrameManager()->GetRootFrame();
if (rootFrame) {
rootFrame->InvalidateFrameSubtree();
}
}
}
void PresShell::SynthesizeMouseMove(PRBool aFromScroll)

View File

@@ -1863,12 +1863,9 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
scrollParts, createLayersForScrollbars);
}
nsRect displayport;
PRBool usingDisplayPort = nsLayoutUtils::GetDisplayPort(mOuter->GetContent(),
&displayport);
if (!usingDisplayPort) {
displayport = mScrollPort;
}
nsIPresShell* presShell = mOuter->PresContext()->GetPresShell();
nsRect scrollPort = (mIsRoot && presShell->UsingDisplayPort()) ?
(presShell->GetDisplayPort()) : mScrollPort;
// Overflow clipping can never clip frames outside our subtree, so there
// is no need to worry about whether we are a moving frame that might clip
@@ -1879,69 +1876,18 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// had dirty rects saved for them by their parent frames calling
// MarkOutOfFlowChildrenForDisplayList, so it's safe to restrict our
// dirty rect here.
dirtyRect.IntersectRect(aDirtyRect, mScrollPort);
if (usingDisplayPort) {
dirtyRect = displayport;
}
dirtyRect.IntersectRect(aDirtyRect, scrollPort);
nsDisplayListCollection set;
nsPresContext* presContext = mOuter->PresContext();
PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
#ifdef MOZ_IPC
// Since making new layers is expensive, only use nsDisplayScrollLayer
// if the area is scrollable.
//
// Scroll frames can be generated with a scroll range that is 0, 0.
// Furthermore, it is not worth the memory tradeoff to allow asynchronous
// scrolling of small scroll frames. We use an arbitrary minimum scroll
// range of 20 pixels to eliminate many gfx scroll frames from becoming a
// layer.
//
nsRect scrollRange = GetScrollRange();
PRBool buildingLayer =
(XRE_GetProcessType() == GeckoProcessType_Content &&
(scrollRange.width >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel) ||
scrollRange.height >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel))) &&
(!mIsRoot || !mOuter->PresContext()->IsRootContentDocument());
#else
PRBool buildingLayer = false;
#endif
if (buildingLayer) {
// Note that using StackingContext breaks z order, so the resulting
// rendering can be incorrect for weird edge cases!
rv = mScrolledFrame->BuildDisplayListForStackingContext(
aBuilder,
dirtyRect + mOuter->GetOffsetTo(mScrolledFrame),
set.Content()
);
nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollLayer(
aBuilder,
set.Content(),
mScrolledFrame,
mOuter,
displayport
);
set.Content()->AppendNewToTop(layerItem);
} else {
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set);
}
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set);
NS_ENSURE_SUCCESS(rv, rv);
nsRect clip;
clip = mScrollPort + aBuilder->ToReferenceFrame(mOuter);
clip = scrollPort + aBuilder->ToReferenceFrame(mOuter);
nscoord radii[8];
// Our override of GetBorderRadii ensures we never have a radius at
// the corners where we have a scrollbar.
mOuter->GetPaddingBoxBorderRadii(radii);
// mScrolledFrame may have given us a background, e.g., the scrolled canvas
// frame below the viewport. If so, we want it to be clipped. We also want
// to end up on our BorderBackground list.

View File

@@ -340,12 +340,32 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
PRInt32 parentAPD = PresContext()->AppUnitsPerDevPixel();
PRInt32 subdocAPD = presContext->AppUnitsPerDevPixel();
nsIFrame* subdocRootScrollFrame = presShell->GetRootScrollFrame();
nsRect dirty;
if (subdocRootFrame) {
// get the dirty rect relative to the root frame of the subdoc
dirty = aDirtyRect + GetOffsetToCrossDoc(subdocRootFrame);
// and convert into the appunits of the subdoc
dirty = dirty.ConvertAppUnitsRoundOut(parentAPD, subdocAPD);
if (presShell->UsingDisplayPort() && subdocRootScrollFrame) {
dirty = presShell->GetDisplayPort();
// The visual overflow rect of our viewport frame unfortunately may not
// intersect with the displayport of that frame. For example, the scroll
// offset of the frame may be (0, 0) so that the visual overflow rect
// is (0, 0, 800px, 500px) while the display port may have its top-left
// corner below y=500px.
//
// We have to force the frame to have a little faith and build a display
// list anyway. (see nsIFrame::BuildDisplayListForChild for the short-
// circuit code we are evading here).
//
subdocRootScrollFrame->AddStateBits(
NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO);
} else {
// get the dirty rect relative to the root frame of the subdoc
dirty = aDirtyRect + GetOffsetToCrossDoc(subdocRootFrame);
// and convert into the appunits of the subdoc
dirty = dirty.ConvertAppUnitsRoundOut(parentAPD, subdocAPD);
}
aBuilder->EnterPresShell(subdocRootFrame, dirty);
}
@@ -405,6 +425,32 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
bool addedLayer = false;
#ifdef MOZ_IPC
// Make a scrollable layer in the child process so it can be manipulated
// with transforms in the parent process.
if (XRE_GetProcessType() == GeckoProcessType_Content) {
nsIScrollableFrame* scrollFrame = presShell->GetRootScrollFrameAsScrollable();
if (scrollFrame) {
NS_ASSERTION(subdocRootFrame, "Root scroll frame should be non-null");
nsRect scrollRange = scrollFrame->GetScrollRange();
// Since making new layers is expensive, only use nsDisplayScrollLayer
// if the area is scrollable.
if (scrollRange.width != 0 || scrollRange.height != 0) {
addedLayer = true;
nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollLayer(
aBuilder,
&childItems,
subdocRootScrollFrame,
subdocRootFrame
);
childItems.AppendToTop(layerItem);
}
}
}
#endif
if (subdocRootFrame && parentAPD != subdocAPD) {
NS_WARN_IF_FALSE(!addedLayer,
"Two container layers have been added. "