Bug 618975 Pan overflow elements in parent process r=cjones r=tn sr=roc a=blocking-fennec

This commit is contained in:
Benjamin Stover 2011-03-15 16:20:19 -07:00
Родитель da9f0ff6e6
Коммит 9bb1728211
15 изменённых файлов: 272 добавлений и 140 удалений

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

@ -1749,6 +1749,7 @@ 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")

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

@ -48,6 +48,7 @@
#include "nsFocusManager.h"
#include "nsIEventStateManager.h"
#include "nsEventStateManager.h"
#include "nsFrameManager.h"
#include "nsIScrollableFrame.h"
@ -258,9 +259,25 @@ 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;
@ -275,9 +292,59 @@ nsDOMWindowUtils::SetDisplayPort(float aXPx, float aYPx,
nsPresContext::CSSPixelsToAppUnits(aYPx),
nsPresContext::CSSPixelsToAppUnits(aWidthPx),
nsPresContext::CSSPixelsToAppUnits(aHeightPx));
presShell->SetDisplayPort(displayport);
presShell->SetIgnoreViewportScrolling(PR_TRUE);
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->InvalidateWithFlags(rootFrame->GetVisualOverflowRectRelativeToSelf(),
nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
}
}
return NS_OK;
}

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

@ -129,30 +129,7 @@ interface nsIDOMWindowUtils : nsISupports {
void setCSSViewport(in float aWidthPx, in float aHeightPx);
/**
* 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.
* @DEPRECATED See nsIDOMWindowUtils_MOZILLA_2_0_BRANCH.
*/
void setDisplayPort(in float aXPx, in float aYPx,
in float aWidthPx, in float aHeightPx);
@ -824,7 +801,7 @@ interface nsIDOMWindowUtils : nsISupports {
typedef unsigned long long nsViewID;
[scriptable, uuid(be2e28c8-64f8-4100-906d-8a451ddd6835)]
[scriptable, uuid(7ad49829-e631-4cdd-a237-95847d9bcbe6)]
interface nsIDOMWindowUtils_MOZILLA_2_0_BRANCH : nsISupports {
/**
* Get the type of the currently focused html input, if any.
@ -838,6 +815,36 @@ 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.

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

@ -1295,7 +1295,8 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
item->GetLayerState(mBuilder, mManager);
// Assign the item to a layer
if (layerState == LAYER_ACTIVE && (aClip.mRoundedClipRects.IsEmpty() ||
if (layerState == LAYER_ACTIVE_FORCE ||
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()))) {

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

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

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

@ -149,12 +149,13 @@ 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));
@ -163,23 +164,23 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
PRInt32 auPerDevPixel = presContext->AppUnitsPerDevPixel();
metrics.mViewport = aViewport.ToNearestPixels(auPerDevPixel);
if (presShell->UsingDisplayPort()) {
metrics.mDisplayPort =
presShell->GetDisplayPort().ToNearestPixels(auPerDevPixel);
if (aViewport != aDisplayPort) {
metrics.mDisplayPort = aDisplayPort.ToNearestPixels(auPerDevPixel);
}
nsIScrollableFrame* rootScrollableFrame =
presShell->GetRootScrollFrameAsScrollable();
if (rootScrollableFrame) {
nsSize contentSize =
rootScrollableFrame->GetScrollRange().Size() +
rootScrollableFrame->GetScrollPortRect().Size();
nsIScrollableFrame* scrollableFrame = NULL;
if (aViewportFrame)
scrollableFrame = aViewportFrame->GetScrollTargetFrame();
if (scrollableFrame) {
nsSize contentSize =
scrollableFrame->GetScrollRange().Size() +
scrollableFrame->GetScrollPortRect().Size();
metrics.mContentSize = nsIntSize(NSAppUnitsToIntPixels(contentSize.width, auPerDevPixel),
NSAppUnitsToIntPixels(contentSize.height, auPerDevPixel));
metrics.mViewportScrollOffset =
rootScrollableFrame->GetScrollPosition().ToNearestPixels(auPerDevPixel);
scrollableFrame->GetScrollPosition().ToNearestPixels(auPerDevPixel);
}
else {
nsSize contentSize = aForFrame->GetSize();
@ -523,7 +524,18 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID
: FrameMetrics::NULL_SCROLL_ID;
RecordFrameMetrics(aForFrame, root, mVisibleRect, mVisibleRect, 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);
// If the layer manager supports resolution scaling, set that up
if (LayerManager::LAYERS_BASIC == layerManager->GetBackendType()) {
@ -1694,9 +1706,11 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
nsDisplayList* aList,
nsIFrame* aForFrame,
nsIFrame* aViewportFrame)
nsIFrame* aViewportFrame,
const nsRect& aDisplayPort)
: nsDisplayOwnLayer(aBuilder, aForFrame, aList)
, mViewportFrame(aViewportFrame)
, mDisplayPort(aDisplayPort)
{
#ifdef NS_BUILD_REFCNT_LOGGING
MOZ_COUNT_CTOR(nsDisplayScrollLayer);
@ -1721,7 +1735,8 @@ nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
mViewportFrame->GetPosition() +
aBuilder->ToReferenceFrame(mViewportFrame);
RecordFrameMetrics(mFrame, layer, mVisibleRect, viewport, scrollId);
RecordFrameMetrics(mFrame, mViewportFrame, layer, mVisibleRect, viewport,
mDisplayPort, scrollId);
return layer.forget();
}
@ -1733,14 +1748,17 @@ nsDisplayScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder,
PRBool& aContainsRootContentDocBG)
{
nsPresContext* presContext = mFrame->PresContext();
nsIPresShell* presShell = presContext->GetPresShell();
if (presShell->UsingDisplayPort()) {
nsRect viewport = mViewportFrame->GetRect() -
mViewportFrame->GetPosition() +
aBuilder->ToReferenceFrame(mViewportFrame);
if (mDisplayPort != viewport) {
// 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 = presShell->GetDisplayPort() + aBuilder->ToReferenceFrame(mViewportFrame);
nsRegion childVisibleRegion = mDisplayPort + aBuilder->ToReferenceFrame(mViewportFrame);
nsRect boundedRect;
boundedRect.IntersectRect(childVisibleRegion.GetBounds(), mList.GetBounds(aBuilder));

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

@ -1790,9 +1790,12 @@ 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);
nsIFrame* aForFrame, nsIFrame* aViewportFrame,
const nsRect& aDisplayPort);
NS_DISPLAY_DECL_NAME("ScrollLayer", TYPE_SCROLL_LAYER)
#ifdef NS_BUILD_REFCNT_LOGGING
@ -1807,8 +1810,16 @@ 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

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

@ -1154,19 +1154,21 @@ 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
{ return mRenderFlags & STATE_USING_DISPLAYPORT; }
{ NS_ABORT_IF_FALSE(false, "UsingDisplayPort is deprecated"); return false; }
/**
* Return the displayport being used. |UsingDisplayPort()| must be
* true.
* @DEPRECATED Use nsLayoutUtils displayport methods
*/
nsRect GetDisplayPort()
{
NS_ABORT_IF_FALSE(UsingDisplayPort(), "no displayport defined!");
return mDisplayPort;
NS_ABORT_IF_FALSE(false, "GetDisplayPort is deprecated");
return nsRect();
}
/**

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

@ -143,6 +143,10 @@ static void DestroyViewID(void* aObject, nsIAtom* aPropertyName,
delete id;
}
/**
* A namespace class for static layout utilities.
*/
ViewID
nsLayoutUtils::FindIDFor(nsIContent* aContent)
{
@ -177,9 +181,19 @@ nsLayoutUtils::FindContentFor(ViewID aId)
}
}
/**
* A namespace class for static layout utilities.
*/
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;
}
nsIFrame*
nsLayoutUtils::GetLastContinuationWithChild(nsIFrame* aFrame)
@ -1368,6 +1382,16 @@ 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) {
@ -1377,10 +1401,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 (!presShell->UsingDisplayPort()) {
if (!usingDisplayPort) {
visibleRegion = aFrame->GetVisualOverflowRectRelativeToSelf();
} else {
visibleRegion = presShell->GetDisplayPort();
visibleRegion = displayport;
}
} else {
visibleRegion = aDirtyRegion;

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

@ -94,6 +94,11 @@ 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.

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

@ -1037,12 +1037,10 @@ 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;
};
@ -1056,7 +1054,6 @@ protected:
~AutoSaveRestoreRenderingState()
{
mPresShell->mRenderFlags = mOldState.mRenderFlags;
mPresShell->mDisplayPort = mOldState.mDisplayPort;
mPresShell->mXResolution = mOldState.mXResolution;
mPresShell->mYResolution = mOldState.mYResolution;
}
@ -6017,14 +6014,7 @@ void PresShell::SetIgnoreViewportScrolling(PRBool aIgnore)
void PresShell::SetDisplayPort(const nsRect& aDisplayPort)
{
if (UsingDisplayPort() && mDisplayPort == aDisplayPort) {
return;
}
RenderingState state(this);
state.mRenderFlags = ChangeFlag(mRenderFlags, PR_TRUE,
STATE_USING_DISPLAYPORT);
state.mDisplayPort = aDisplayPort;
SetRenderingState(state);
NS_ABORT_IF_FALSE(false, "SetDisplayPort is deprecated");
}
nsresult PresShell::SetResolution(float aXResolution, float aYResolution)
@ -6054,11 +6044,6 @@ void PresShell::SetRenderingState(const RenderingState& aState)
}
mRenderFlags = aState.mRenderFlags;
if (UsingDisplayPort()) {
mDisplayPort = aState.mDisplayPort;
} else {
mDisplayPort = nsRect();
}
mXResolution = aState.mXResolution;
mYResolution = aState.mYResolution;
@ -6066,16 +6051,6 @@ void PresShell::SetRenderingState(const RenderingState& aState)
if (NS_SUCCEEDED(mViewManager->GetRootView(rootView)) && rootView) {
rootView->SetInvalidationDimensions(&mDisplayPort);
}
nsPresContext* rootPresContext = mPresContext->GetRootPresContext();
if (rootPresContext) {
nsIPresShell* rootPresShell = rootPresContext->GetPresShell();
nsIFrame* rootFrame = rootPresShell->FrameManager()->GetRootFrame();
if (rootFrame) {
rootFrame->InvalidateWithFlags(rootFrame->GetVisualOverflowRectRelativeToSelf(),
nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
}
}
}
void PresShell::SynthesizeMouseMove(PRBool aFromScroll)

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

@ -1879,9 +1879,12 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
scrollParts, createLayersForScrollbars);
}
nsIPresShell* presShell = mOuter->PresContext()->GetPresShell();
nsRect scrollPort = (mIsRoot && presShell->UsingDisplayPort()) ?
(presShell->GetDisplayPort()) : mScrollPort;
nsRect displayport;
PRBool usingDisplayPort = nsLayoutUtils::GetDisplayPort(mOuter->GetContent(),
&displayport);
if (!usingDisplayPort) {
displayport = 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
@ -1892,18 +1895,69 @@ 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, scrollPort);
dirtyRect.IntersectRect(aDirtyRect, mScrollPort);
if (usingDisplayPort) {
dirtyRect = displayport;
}
nsDisplayListCollection set;
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, 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);
}
NS_ENSURE_SUCCESS(rv, rv);
nsRect clip;
clip = scrollPort + aBuilder->ToReferenceFrame(mOuter);
clip = mScrollPort + 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.

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

@ -340,32 +340,12 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
PRInt32 parentAPD = PresContext()->AppUnitsPerDevPixel();
PRInt32 subdocAPD = presContext->AppUnitsPerDevPixel();
nsIFrame* subdocRootScrollFrame = presShell->GetRootScrollFrame();
nsRect dirty;
if (subdocRootFrame) {
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);
}
// 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);
}
@ -425,32 +405,6 @@ 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. "

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

@ -3,6 +3,11 @@ function windowUtils() {
.getInterface(Components.interfaces.nsIDOMWindowUtils);
}
function windowUtils20() {
return windowUtils()
.QueryInterface(Components.interfaces.nsIDOMWindowUtils_MOZILLA_2_0_BRANCH);
}
function recvSetViewport(w, h) {
dump("setting viewport to "+ w +"x"+ h +"\n");
@ -14,7 +19,7 @@ function recvSetDisplayPort(x, y, w, h) {
dump("setting displayPort to <"+ x +", "+ y +", "+ w +", "+ h +">\n");
windowUtils().setDisplayPort(x, y, w, h);
windowUtils20().setDisplayPortForElement(x, y, w, h, content.document.documentElement);
}
function recvSetResolution(xres, yres) {

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

@ -120,6 +120,11 @@ function windowUtils() {
.getInterface(CI.nsIDOMWindowUtils);
}
function windowUtils20() {
return windowUtils()
.QueryInterface(Components.interfaces.nsIDOMWindowUtils_MOZILLA_2_0_BRANCH);
}
function IDForEventTarget(event)
{
try {
@ -253,7 +258,7 @@ function setupDisplayport(contentRootElement) {
var dph = attrOrDefault("reftest-displayport-h", 0);
if (dpw !== 0 || dph !== 0) {
LogInfo("Setting displayport to <x=0, y=0, w="+ dpw +", h="+ dph +">");
windowUtils().setDisplayPort(0, 0, dpw, dph);
windowUtils20().setDisplayPortForElement(0, 0, dpw, dph, content.document.documentElement);
}
// XXX support resolution when needed