void APZCCallbackHelper::UpdateRootFrame(FrameMetrics& aMetrics) { if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) { return; } nsIContent* content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId()); if (!content) { return; } nsCOMPtr<nsIPresShell> shell = GetPresShell(content); if (!shell || aMetrics.GetPresShellId() != shell->GetPresShellId()) { return; } MOZ_ASSERT(aMetrics.GetUseDisplayPortMargins()); if (gfxPrefs::APZAllowZooming()) { // If zooming is disabled then we don't really want to let APZ fiddle // with these things. In theory setting the resolution here should be a // no-op, but setting the SPCSPS is bad because it can cause a stale value // to be returned by window.innerWidth/innerHeight (see bug 1187792). float presShellResolution = nsLayoutUtils::GetResolution(shell); // If the pres shell resolution has changed on the content side side // the time this repaint request was fired, consider this request out of date // and drop it; setting a zoom based on the out-of-date resolution can have // the effect of getting us stuck with the stale resolution. if (presShellResolution != aMetrics.GetPresShellResolution()) { return; } // Set the scroll port size, which determines the scroll range. For example if // a 500-pixel document is shown in a 100-pixel frame, the scroll port length would // be 100, and gecko would limit the maximum scroll offset to 400 (so as to prevent // overscroll). Note that if the content here was zoomed to 2x, the document would // be 1000 pixels long but the frame would still be 100 pixels, and so the maximum // scroll range would be 900. Therefore this calculation depends on the zoom applied // to the content relative to the container. // Note that this needs to happen before scrolling the frame (in UpdateFrameCommon), // otherwise the scroll position may get clamped incorrectly. CSSSize scrollPort = aMetrics.CalculateCompositedSizeInCssPixels(); nsLayoutUtils::SetScrollPositionClampingScrollPortSize(shell, scrollPort); // The pres shell resolution is updated by the the async zoom since the // last paint. presShellResolution = aMetrics.GetPresShellResolution() * aMetrics.GetAsyncZoom().scale; nsLayoutUtils::SetResolutionAndScaleTo(shell, presShellResolution); } // Do this as late as possible since scrolling can flush layout. It also // adjusts the display port margins, so do it before we set those. ScrollFrame(content, aMetrics); SetDisplayPortMargins(shell, content, aMetrics); }
bool APZCCallbackHelper::HasValidPresShellId(nsIDOMWindowUtils* aUtils, const FrameMetrics& aMetrics) { MOZ_ASSERT(aUtils); uint32_t presShellId; nsresult rv = aUtils->GetPresShellId(&presShellId); MOZ_ASSERT(NS_SUCCEEDED(rv)); return NS_SUCCEEDED(rv) && aMetrics.GetPresShellId() == presShellId; }
void APZCCallbackHelper::UpdateRootFrame(FrameMetrics& aMetrics) { if (aMetrics.GetScrollId() == FrameMetrics::NULL_SCROLL_ID) { return; } nsIContent* content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId()); if (!content) { return; } nsCOMPtr<nsIPresShell> shell = GetPresShell(content); if (!shell || aMetrics.GetPresShellId() != shell->GetPresShellId()) { return; } MOZ_ASSERT(aMetrics.GetUseDisplayPortMargins()); if (gfxPrefs::APZAllowZooming()) { // If zooming is disabled then we don't really want to let APZ fiddle // with these things. In theory setting the resolution here should be a // no-op, but setting the SPCSPS is bad because it can cause a stale value // to be returned by window.innerWidth/innerHeight (see bug 1187792). float presShellResolution = shell->GetResolution(); // If the pres shell resolution has changed on the content side side // the time this repaint request was fired, consider this request out of date // and drop it; setting a zoom based on the out-of-date resolution can have // the effect of getting us stuck with the stale resolution. if (presShellResolution != aMetrics.GetPresShellResolution()) { return; } // The pres shell resolution is updated by the the async zoom since the // last paint. presShellResolution = aMetrics.GetPresShellResolution() * aMetrics.GetAsyncZoom().scale; shell->SetResolutionAndScaleTo(presShellResolution); } // Do this as late as possible since scrolling can flush layout. It also // adjusts the display port margins, so do it before we set those. ScrollFrame(content, aMetrics); MOZ_ASSERT(nsLayoutUtils::HasDisplayPort(content)); SetDisplayPortMargins(shell, content, aMetrics); SetPaintRequestTime(content, aMetrics.GetPaintRequestTime()); }
void AppendToString(std::stringstream& aStream, const FrameMetrics& m, const char* pfx, const char* sfx, bool detailed) { aStream << pfx; AppendToString(aStream, m.GetCompositionBounds(), "{ [cb="); AppendToString(aStream, m.GetScrollableRect(), "] [sr="); AppendToString(aStream, m.GetScrollOffset(), "] [s="); if (m.GetDoSmoothScroll()) { AppendToString(aStream, m.GetSmoothScrollOffset(), "] [ss="); } AppendToString(aStream, m.GetDisplayPort(), "] [dp="); AppendToString(aStream, m.GetCriticalDisplayPort(), "] [cdp="); AppendToString(aStream, m.GetBackgroundColor(), "] [color="); if (!detailed) { AppendToString(aStream, m.GetScrollId(), "] [scrollId="); if (m.GetScrollParentId() != FrameMetrics::NULL_SCROLL_ID) { AppendToString(aStream, m.GetScrollParentId(), "] [scrollParent="); } if (m.IsRootContent()) { aStream << "] [rcd"; } if (m.HasClipRect()) { AppendToString(aStream, m.ClipRect(), "] [clip="); } AppendToString(aStream, m.GetZoom(), "] [z=", "] }"); } else { AppendToString(aStream, m.GetDisplayPortMargins(), " [dpm="); aStream << nsPrintfCString("] um=%d", m.GetUseDisplayPortMargins()).get(); AppendToString(aStream, m.GetRootCompositionSize(), "] [rcs="); AppendToString(aStream, m.GetViewport(), "] [v="); aStream << nsPrintfCString("] [z=(ld=%.3f r=%.3f", m.GetDevPixelsPerCSSPixel().scale, m.GetPresShellResolution()).get(); AppendToString(aStream, m.GetCumulativeResolution(), " cr="); AppendToString(aStream, m.GetZoom(), " z="); AppendToString(aStream, m.GetExtraResolution(), " er="); aStream << nsPrintfCString(")] [u=(%d %d %lu)", m.GetScrollOffsetUpdated(), m.GetDoSmoothScroll(), m.GetScrollGeneration()).get(); AppendToString(aStream, m.GetScrollParentId(), "] [p="); aStream << nsPrintfCString("] [i=(%ld %lld %d)] }", m.GetPresShellId(), m.GetScrollId(), m.IsRootContent()).get(); } aStream << sfx; }
void AppendToString(std::stringstream& aStream, const FrameMetrics& m, const char* pfx, const char* sfx, bool detailed) { aStream << pfx; AppendToString(aStream, m.mCompositionBounds, "{ cb="); AppendToString(aStream, m.mScrollableRect, " sr="); AppendToString(aStream, m.GetScrollOffset(), " s="); if (m.GetDoSmoothScroll()) { AppendToString(aStream, m.GetSmoothScrollOffset(), " ss="); } AppendToString(aStream, m.mDisplayPort, " dp="); AppendToString(aStream, m.mCriticalDisplayPort, " cdp="); AppendToString(aStream, m.GetBackgroundColor(), " color="); if (!detailed) { AppendToString(aStream, m.GetScrollId(), " scrollId="); if (m.GetScrollParentId() != FrameMetrics::NULL_SCROLL_ID) { AppendToString(aStream, m.GetScrollParentId(), " scrollParent="); } aStream << nsPrintfCString(" z=%.3f }", m.GetZoom().scale).get(); } else { AppendToString(aStream, m.GetDisplayPortMargins(), " dpm="); aStream << nsPrintfCString(" um=%d", m.GetUseDisplayPortMargins()).get(); AppendToString(aStream, m.GetRootCompositionSize(), " rcs="); AppendToString(aStream, m.GetViewport(), " v="); aStream << nsPrintfCString(" z=(ld=%.3f r=%.3f cr=%.3f z=%.3f er=%.3f)", m.mDevPixelsPerCSSPixel.scale, m.mPresShellResolution, m.mCumulativeResolution.scale, m.GetZoom().scale, m.GetExtraResolution().scale).get(); aStream << nsPrintfCString(" u=(%d %d %lu)", m.GetScrollOffsetUpdated(), m.GetDoSmoothScroll(), m.GetScrollGeneration()).get(); AppendToString(aStream, m.GetScrollParentId(), " p="); aStream << nsPrintfCString(" i=(%ld %lld) }", m.GetPresShellId(), m.GetScrollId()).get(); } aStream << sfx; }