diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index ef1ea7ca9dd0..2f1d855016cf 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -47,7 +47,12 @@ #include "gfxPlatform.h" using namespace mozilla::layers; - + +typedef FrameMetrics::ViewID ViewID; +const ViewID FrameMetrics::NULL_SCROLL_ID = 0; +const ViewID FrameMetrics::ROOT_SCROLL_ID = 1; +const ViewID FrameMetrics::START_SCROLL_ID = 2; + #ifdef MOZ_LAYERS_HAVE_LOG FILE* FILEOrDefault(FILE* aFile) @@ -79,6 +84,15 @@ AppendToString(nsACString& s, const gfxPattern::GraphicsFilter& f, return s += sfx; } +nsACString& +AppendToString(nsACString& s, ViewID n, + const char* pfx="", const char* sfx="") +{ + s += pfx; + s.AppendInt(n); + return s += sfx; +} + nsACString& AppendToString(nsACString& s, const gfxRGBA& c, const char* pfx="", const char* sfx="") @@ -164,9 +178,10 @@ AppendToString(nsACString& s, const FrameMetrics& m, const char* pfx="", const char* sfx="") { s += pfx; - AppendToString(s, m.mViewportSize, "{ viewport="); + AppendToString(s, m.mViewport, "{ viewport="); AppendToString(s, m.mViewportScrollOffset, " viewportScroll="); - AppendToString(s, m.mDisplayPort, " displayport=", " }"); + AppendToString(s, m.mDisplayPort, " displayport="); + AppendToString(s, m.mScrollId, " scrollId=", " }"); return s += sfx; } diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 176107d2e7c5..d85ddf7c40c2 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -87,18 +87,28 @@ class SpecificLayerAttributes; * atomically with new pixels. */ struct FrameMetrics { +public: + // We use IDs to identify frames across processes. + typedef PRUint64 ViewID; + static const ViewID NULL_SCROLL_ID; // This container layer does not scroll. + static const ViewID ROOT_SCROLL_ID; // This is the root scroll frame. + static const ViewID START_SCROLL_ID; // This is the ID that scrolling subframes + // will begin at. + FrameMetrics() - : mViewportSize(0, 0) + : mViewport(0, 0, 0, 0) , mViewportScrollOffset(0, 0) + , mScrollId(NULL_SCROLL_ID) {} // Default copy ctor and operator= are fine PRBool operator==(const FrameMetrics& aOther) const { - return (mViewportSize == aOther.mViewportSize && + return (mViewport == aOther.mViewport && mViewportScrollOffset == aOther.mViewportScrollOffset && - mDisplayPort == aOther.mDisplayPort); + mDisplayPort == aOther.mDisplayPort && + mScrollId == aOther.mScrollId); } PRBool IsDefault() const @@ -106,9 +116,20 @@ struct FrameMetrics { return (FrameMetrics() == *this); } - nsIntSize mViewportSize; + PRBool IsRootScrollable() const + { + return mScrollId == ROOT_SCROLL_ID; + } + + PRBool IsScrollable() const + { + return mScrollId != NULL_SCROLL_ID; + } + + nsIntRect mViewport; nsIntPoint mViewportScrollOffset; nsIntRect mDisplayPort; + ViewID mScrollId; }; #define MOZ_LAYER_DECL_NAME(n, e) \ diff --git a/gfx/layers/ipc/ShadowLayerUtils.h b/gfx/layers/ipc/ShadowLayerUtils.h index 099d8e594a63..4fff40cfe2ba 100644 --- a/gfx/layers/ipc/ShadowLayerUtils.h +++ b/gfx/layers/ipc/ShadowLayerUtils.h @@ -63,16 +63,18 @@ struct ParamTraits static void Write(Message* aMsg, const paramType& aParam) { - WriteParam(aMsg, aParam.mViewportSize); + WriteParam(aMsg, aParam.mViewport); WriteParam(aMsg, aParam.mViewportScrollOffset); WriteParam(aMsg, aParam.mDisplayPort); + WriteParam(aMsg, aParam.mScrollId); } static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { - return (ReadParam(aMsg, aIter, &aResult->mViewportSize) && + return (ReadParam(aMsg, aIter, &aResult->mViewport) && ReadParam(aMsg, aIter, &aResult->mViewportScrollOffset) && - ReadParam(aMsg, aIter, &aResult->mDisplayPort)); + ReadParam(aMsg, aIter, &aResult->mDisplayPort) && + ReadParam(aMsg, aIter, &aResult->mScrollId)); } }; diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index e8ad5cb4f823..2fbc9e1c7e3a 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -67,6 +67,7 @@ using namespace mozilla; using namespace mozilla::layers; +typedef FrameMetrics::ViewID ViewID; nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, PRBool aBuildCaret) @@ -147,6 +148,38 @@ static void UnmarkFrameForDisplay(nsIFrame* aFrame) { } } +static void RecordFrameMetrics(nsIFrame* aForFrame, + ContainerLayer* aRoot, + nsRect aVisibleRect, + nsRect aViewport, + ViewID aScrollId) { + nsPresContext* presContext = aForFrame->PresContext(); + nsIPresShell* presShell = presContext->GetPresShell(); + + nsIntRect visible = aVisibleRect.ToNearestPixels(presContext->AppUnitsPerDevPixel()); + aRoot->SetVisibleRegion(nsIntRegion(visible)); + + FrameMetrics metrics; + + PRInt32 auPerDevPixel = presContext->AppUnitsPerDevPixel(); + metrics.mViewport = aViewport.ToNearestPixels(auPerDevPixel); + if (presShell->UsingDisplayPort()) { + metrics.mDisplayPort = + presShell->GetDisplayPort().ToNearestPixels(auPerDevPixel); + } + + nsIScrollableFrame* rootScrollableFrame = + presShell->GetRootScrollFrameAsScrollable(); + if (rootScrollableFrame) { + metrics.mViewportScrollOffset = + rootScrollableFrame->GetScrollPosition().ToNearestPixels(auPerDevPixel); + + metrics.mScrollId = aScrollId; + } + + aRoot->SetFrameMetrics(metrics); +} + nsDisplayListBuilder::~nsDisplayListBuilder() { NS_ASSERTION(mFramesMarkedForDisplay.Length() == 0, "All frames should have been unmarked"); @@ -467,28 +500,10 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder, nsPresContext* presContext = aForFrame->PresContext(); nsIPresShell* presShell = presContext->GetPresShell(); - nsIntRect visible = mVisibleRect.ToNearestPixels(presContext->AppUnitsPerDevPixel()); - root->SetVisibleRegion(nsIntRegion(visible)); + ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID + : FrameMetrics::NULL_SCROLL_ID; - // Collect frame metrics with which to stamp the root layer. - FrameMetrics metrics; - - PRInt32 auPerCSSPixel = nsPresContext::AppUnitsPerCSSPixel(); - metrics.mViewportSize = - presContext->GetVisibleArea().ToNearestPixels(auPerCSSPixel).Size(); - if (presShell->UsingDisplayPort()) { - metrics.mDisplayPort = - presShell->GetDisplayPort().ToNearestPixels(auPerCSSPixel); - } - - nsIScrollableFrame* rootScrollableFrame = - presShell->GetRootScrollFrameAsScrollable(); - if (rootScrollableFrame) { - metrics.mViewportScrollOffset = - rootScrollableFrame->GetScrollPosition().ToNearestPixels(auPerCSSPixel); - } - - root->SetFrameMetrics(metrics); + RecordFrameMetrics(aForFrame, root, mVisibleRect, mVisibleRect, id); // If the layer manager supports resolution scaling, set that up if (LayerManager::LAYERS_BASIC == layerManager->GetBackendType()) {