author | Timothy Nikkel <tnikkel@gmail.com> |
Wed, 26 Mar 2014 19:24:25 -0400 | |
changeset 175588 | ab216bb516fc770bcfee346bf381addd43116a86 |
parent 175587 | 475ee7cda2d116efd30a88aa21665a0c4bb980d2 |
child 175589 | 40651e2d3cbc94cfef28e23e1d0e63bf94c37b4a |
push id | 26494 |
push user | cbook@mozilla.com |
push date | Thu, 27 Mar 2014 13:09:48 +0000 |
treeherder | mozilla-central@d2ecc6d31622 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kats |
bugs | 986413 |
milestone | 31.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -239,16 +239,18 @@ TabChildBase::HandlePossibleViewportChan oldScreenWidth = mInnerSize.width; } FrameMetrics metrics(mLastRootMetrics); metrics.mViewport = CSSRect(CSSPoint(), viewport); metrics.mCompositionBounds = ParentLayerIntRect( ParentLayerIntPoint(), ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot)); + metrics.SetRootCompositionSize( + ScreenSize(mInnerSize) * ScreenToLayoutDeviceScale(1.0f) / metrics.mDevPixelsPerCSSPixel); // This change to the zoom accounts for all types of changes I can conceive: // 1. screen size changes, CSS viewport does not (pages with no meta viewport // or a fixed size viewport) // 2. screen size changes, CSS viewport also does (pages with a device-width // viewport) // 3. screen size remains constant, but CSS viewport changes (meta viewport // tag is added or removed)
--- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -558,20 +558,20 @@ struct ParamTraits< mozilla::gfx::IntPoi static bool Read(const Message* msg, void** iter, paramType* result) { return (ReadParam(msg, iter, &result->x) && ReadParam(msg, iter, &result->y)); } }; -template<> -struct ParamTraits<mozilla::gfx::Size> +template<class T> +struct ParamTraits< mozilla::gfx::SizeTyped<T> > { - typedef mozilla::gfx::Size paramType; + typedef mozilla::gfx::SizeTyped<T> paramType; static void Write(Message* msg, const paramType& param) { WriteParam(msg, param.width); WriteParam(msg, param.height); } static bool Read(const Message* msg, void** iter, paramType* result) @@ -704,16 +704,17 @@ struct ParamTraits<mozilla::layers::Fram static void Write(Message* aMsg, const paramType& aParam) { WriteParam(aMsg, aParam.mScrollableRect); WriteParam(aMsg, aParam.mViewport); WriteParam(aMsg, aParam.mScrollOffset); WriteParam(aMsg, aParam.mDisplayPort); WriteParam(aMsg, aParam.mCriticalDisplayPort); WriteParam(aMsg, aParam.mCompositionBounds); + WriteParam(aMsg, aParam.mRootCompositionSize); WriteParam(aMsg, aParam.mScrollId); WriteParam(aMsg, aParam.mResolution); WriteParam(aMsg, aParam.mCumulativeResolution); WriteParam(aMsg, aParam.mZoom); WriteParam(aMsg, aParam.mDevPixelsPerCSSPixel); WriteParam(aMsg, aParam.mMayHaveTouchListeners); WriteParam(aMsg, aParam.mPresShellId); WriteParam(aMsg, aParam.mIsRoot); @@ -727,16 +728,17 @@ struct ParamTraits<mozilla::layers::Fram static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { return (ReadParam(aMsg, aIter, &aResult->mScrollableRect) && ReadParam(aMsg, aIter, &aResult->mViewport) && ReadParam(aMsg, aIter, &aResult->mScrollOffset) && ReadParam(aMsg, aIter, &aResult->mDisplayPort) && ReadParam(aMsg, aIter, &aResult->mCriticalDisplayPort) && ReadParam(aMsg, aIter, &aResult->mCompositionBounds) && + ReadParam(aMsg, aIter, &aResult->mRootCompositionSize) && ReadParam(aMsg, aIter, &aResult->mScrollId) && ReadParam(aMsg, aIter, &aResult->mResolution) && ReadParam(aMsg, aIter, &aResult->mCumulativeResolution) && ReadParam(aMsg, aIter, &aResult->mZoom) && ReadParam(aMsg, aIter, &aResult->mDevPixelsPerCSSPixel) && ReadParam(aMsg, aIter, &aResult->mMayHaveTouchListeners) && ReadParam(aMsg, aIter, &aResult->mPresShellId) && ReadParam(aMsg, aIter, &aResult->mIsRoot) &&
--- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -80,25 +80,27 @@ public: , mMayHaveTouchListeners(false) , mIsRoot(false) , mHasScrollgrab(false) , mScrollId(NULL_SCROLL_ID) , mScrollOffset(0, 0) , mZoom(1) , mUpdateScrollOffset(false) , mScrollGeneration(0) + , mRootCompositionSize(0, 0) {} // Default copy ctor and operator= are fine bool operator==(const FrameMetrics& aOther) const { // mContentDescription is not compared on purpose as it's only used // for debugging. return mCompositionBounds.IsEqualEdges(aOther.mCompositionBounds) && + mRootCompositionSize == aOther.mRootCompositionSize && mDisplayPort.IsEqualEdges(aOther.mDisplayPort) && mCriticalDisplayPort.IsEqualEdges(aOther.mCriticalDisplayPort) && mViewport.IsEqualEdges(aOther.mViewport) && mScrollableRect.IsEqualEdges(aOther.mScrollableRect) && mResolution == aOther.mResolution && mCumulativeResolution == aOther.mCumulativeResolution && mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel && mMayHaveTouchListeners == aOther.mMayHaveTouchListeners && @@ -371,17 +373,27 @@ public: { return mScrollId; } void SetScrollId(ViewID scrollId) { mScrollId = scrollId; } - + + void SetRootCompositionSize(const CSSSize& aRootCompositionSize) + { + mRootCompositionSize = aRootCompositionSize; + } + + const CSSSize& GetRootCompositionSize() const + { + return mRootCompositionSize; + } + private: // New fields from now on should be made private and old fields should // be refactored to be private. // A unique ID assigned to each scrollable frame. ViewID mScrollId; // The position of the top-left of the CSS viewport, relative to the document @@ -411,16 +423,19 @@ private: // if the APZC receiving this metrics should update its local copy. bool mUpdateScrollOffset; // The scroll generation counter used to acknowledge the scroll offset update. uint32_t mScrollGeneration; // A description of the content element corresponding to this frame. // This is empty unless the apz.printtree pref is turned on. std::string mContentDescription; + + // The size of the root scrollable's composition bounds, but in local CSS pixels. + CSSSize mRootCompositionSize; }; /** * This class allows us to uniquely identify a scrollable layer. The * mLayersId identifies the layer tree (corresponding to a child process * and/or tab) that the scrollable layer belongs to. The mPresShellId * is a temporal identifier (corresponding to the document loaded that * contains the scrollable layer, which may change over time). The
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -61,21 +61,22 @@ #include "SharedMemoryBasic.h" // for SharedMemoryBasic // #define APZC_ENABLE_RENDERTRACE #define APZC_LOG(...) // #define APZC_LOG(...) printf_stderr("APZC: " __VA_ARGS__) #define APZC_LOG_FM(fm, prefix, ...) \ APZC_LOG(prefix ":" \ - " i=(%ld %lld) cb=(%d %d %d %d) dp=(%.3f %.3f %.3f %.3f) v=(%.3f %.3f %.3f %.3f) " \ + " i=(%ld %lld) cb=(%d %d %d %d) rcs=(%.3f %.3f) dp=(%.3f %.3f %.3f %.3f) v=(%.3f %.3f %.3f %.3f) " \ "s=(%.3f %.3f) sr=(%.3f %.3f %.3f %.3f) z=(%.3f %.3f %.3f %.3f) u=(%d %llu)\n", \ __VA_ARGS__, \ fm.mPresShellId, fm.GetScrollId(), \ fm.mCompositionBounds.x, fm.mCompositionBounds.y, fm.mCompositionBounds.width, fm.mCompositionBounds.height, \ + fm.GetRootCompositionSize().width, fm.GetRootCompositionSize().height, \ fm.mDisplayPort.x, fm.mDisplayPort.y, fm.mDisplayPort.width, fm.mDisplayPort.height, \ fm.mViewport.x, fm.mViewport.y, fm.mViewport.width, fm.mViewport.height, \ fm.GetScrollOffset().x, fm.GetScrollOffset().y, \ fm.mScrollableRect.x, fm.mScrollableRect.y, fm.mScrollableRect.width, fm.mScrollableRect.height, \ fm.mDevPixelsPerCSSPixel.scale, fm.mResolution.scale, fm.mCumulativeResolution.scale, fm.GetZoom().scale, \ fm.GetScrollOffsetUpdated(), fm.GetScrollGeneration()); \ // Static helper functions @@ -1363,37 +1364,36 @@ void AsyncPanZoomController::ScaleWithFo // in-depth explanation of how. mFrameMetrics.SetScrollOffset((mFrameMetrics.GetScrollOffset() + aFocus) - (aFocus / aScale)); } /** * Enlarges the displayport along both axes based on the velocity. */ static CSSSize -CalculateDisplayPortSize(const CSSRect& aCompositionBounds, +CalculateDisplayPortSize(const CSSSize& aCompositionSize, const CSSPoint& aVelocity) { float xMultiplier = fabsf(aVelocity.x) < gMinSkateSpeed ? gXStationarySizeMultiplier : gXSkateSizeMultiplier; float yMultiplier = fabsf(aVelocity.y) < gMinSkateSpeed ? gYStationarySizeMultiplier : gYSkateSizeMultiplier; - return CSSSize(aCompositionBounds.width * xMultiplier, - aCompositionBounds.height * yMultiplier); + return CSSSize(aCompositionSize.width * xMultiplier, + aCompositionSize.height * yMultiplier); } /** * Attempts to redistribute any area in the displayport that would get clipped * by the scrollable rect, or be inaccessible due to disabled scrolling, to the * other axis, while maintaining total displayport area. */ static void RedistributeDisplayPortExcess(CSSSize& aDisplayPortSize, - const CSSRect& aCompositionBounds, const CSSRect& aScrollableRect) { float xSlack = std::max(0.0f, aDisplayPortSize.width - aScrollableRect.width); float ySlack = std::max(0.0f, aDisplayPortSize.height - aScrollableRect.height); if (ySlack > 0) { // Reassign wasted y-axis displayport to the x-axis aDisplayPortSize.height -= ySlack; @@ -1409,37 +1409,41 @@ RedistributeDisplayPortExcess(CSSSize& a /* static */ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort( const FrameMetrics& aFrameMetrics, const ScreenPoint& aVelocity, double aEstimatedPaintDuration) { CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels()); + CSSSize compositionSize = aFrameMetrics.GetRootCompositionSize(); + compositionSize = + CSSSize(std::min(compositionBounds.width, compositionSize.width), + std::min(compositionBounds.height, compositionSize.height)); CSSPoint velocity = aVelocity / aFrameMetrics.GetZoom(); CSSPoint scrollOffset = aFrameMetrics.GetScrollOffset(); CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect(); // Calculate the displayport size based on how fast we're moving along each axis. - CSSSize displayPortSize = CalculateDisplayPortSize(compositionBounds, velocity); + CSSSize displayPortSize = CalculateDisplayPortSize(compositionSize, velocity); if (gEnlargeDisplayPortWhenClipped) { - RedistributeDisplayPortExcess(displayPortSize, compositionBounds, scrollableRect); + RedistributeDisplayPortExcess(displayPortSize, scrollableRect); } // Offset the displayport, depending on how fast we're moving and the // estimated time it takes to paint, to try to minimise checkerboarding. float estimatedPaintDurationMillis = (float)(aEstimatedPaintDuration * 1000.0); float paintFactor = (gUsePaintDuration ? estimatedPaintDurationMillis : 50.0f); CSSRect displayPort = CSSRect(scrollOffset + (velocity * paintFactor * gVelocityBias), displayPortSize); - // Re-center the displayport based on its expansion over the composition bounds. - displayPort.MoveBy((compositionBounds.width - displayPort.width)/2.0f, - (compositionBounds.height - displayPort.height)/2.0f); + // Re-center the displayport based on its expansion over the composition size. + displayPort.MoveBy((compositionSize.width - displayPort.width)/2.0f, + (compositionSize.height - displayPort.height)/2.0f); // Make sure the displayport remains within the scrollable rect. displayPort = displayPort.ForceInside(scrollableRect) - scrollOffset; APZC_LOG_FM(aFrameMetrics, "Calculated displayport as (%f %f %f %f) from velocity (%f %f) paint time %f metrics", displayPort.x, displayPort.y, displayPort.width, displayPort.height, aVelocity.x, aVelocity.y, (float)estimatedPaintDurationMillis); @@ -1744,16 +1748,17 @@ void AsyncPanZoomController::NotifyLayer } else { // Take the new zoom as either device scale or composition width or both // got changed (e.g. due to orientation change). mFrameMetrics.SetZoom(aLayerMetrics.GetZoom()); mFrameMetrics.mDevPixelsPerCSSPixel.scale = aLayerMetrics.mDevPixelsPerCSSPixel.scale; } mFrameMetrics.mScrollableRect = aLayerMetrics.mScrollableRect; mFrameMetrics.mCompositionBounds = aLayerMetrics.mCompositionBounds; + mFrameMetrics.SetRootCompositionSize(aLayerMetrics.GetRootCompositionSize()); mFrameMetrics.mResolution = aLayerMetrics.mResolution; mFrameMetrics.mCumulativeResolution = aLayerMetrics.mCumulativeResolution; mFrameMetrics.mHasScrollgrab = aLayerMetrics.mHasScrollgrab; // If the layers update was not triggered by our own repaint request, then // we want to take the new scroll offset. if (aLayerMetrics.GetScrollOffsetUpdated()) { APZC_LOG("%p updating scroll offset from (%f, %f) to (%f, %f)\n", this,
--- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -633,16 +633,95 @@ static bool GetApzcTreePrintPref() { static bool initialized = false; if (!initialized) { Preferences::AddBoolVarCache(&gPrintApzcTree, "apz.printtree", gPrintApzcTree); initialized = true; } return gPrintApzcTree; } +static CSSSize +CalculateRootCompositionSize(FrameMetrics& aMetrics, + bool aIsRootContentDocRootScrollFrame, + nsPresContext* aPresContext, + nsIFrame* aForFrame, nsIFrame* aScrollFrame) +{ + + if (aIsRootContentDocRootScrollFrame) { + // convert from parent layer pixels to layer pixels to css pixels + return ParentLayerSize(aMetrics.mCompositionBounds.Size()) + * aMetrics.mResolution / aMetrics.LayersPixelsPerCSSPixel(); + } + ParentLayerIntSize rootCompositionSize; + nsPresContext* rootPresContext = + aPresContext->GetToplevelContentDocumentPresContext(); + if (!rootPresContext) { + rootPresContext = aPresContext->GetRootPresContext(); + } + nsIPresShell* rootPresShell = nullptr; + if (rootPresContext) { + nsIPresShell* rootPresShell = rootPresContext->PresShell(); + if (nsIFrame* rootFrame = rootPresShell->GetRootFrame()) { + if (nsView* view = rootFrame->GetView()) { + nsIWidget* widget = view->GetWidget(); + #ifdef MOZ_WIDGET_ANDROID + // Android hack - temporary workaround for bug 983208 until we figure + // out what a proper fix is. + if (!widget) { + widget = rootFrame->GetNearestWidget(); + } + #endif + if (widget) { + nsIntRect bounds; + widget->GetBounds(bounds); + rootCompositionSize = ParentLayerIntSize::FromUnknownSize(mozilla::gfx::IntSize( + bounds.width, bounds.height)); + } else { + gfxSize res = rootPresShell->GetCumulativeResolution(); + LayoutDeviceToParentLayerScale parentResolution(res.width); + int32_t rootAUPerDevPixel = rootPresContext->AppUnitsPerDevPixel(); + nsRect viewBounds = view->GetBounds(); + rootCompositionSize = + RoundedToInt(LayoutDeviceRect::FromAppUnits(viewBounds, rootAUPerDevPixel) + * parentResolution).Size(); + } + } + } + } else { + nsIWidget* widget = (aScrollFrame ? aScrollFrame : aForFrame)->GetNearestWidget(); + nsIntRect bounds; + widget->GetBounds(bounds); + rootCompositionSize = ParentLayerIntSize::FromUnknownSize(mozilla::gfx::IntSize( + bounds.width, bounds.height)); + } + + LayoutDeviceToParentLayerScale parentResolution(1.0f); + if (rootPresShell) { + parentResolution.scale = + rootPresShell->GetCumulativeResolution().width / rootPresShell->GetResolution().width; + } + + CSSSize size = + ParentLayerSize(rootCompositionSize) / (parentResolution * aMetrics.mDevPixelsPerCSSPixel); + + // Adjust composition size for the size of scroll bars. + nsIFrame* rootRootScrollFrame = rootPresShell ? rootPresShell->GetRootScrollFrame() : nullptr; + nsIScrollableFrame* rootScrollableFrame = nullptr; + if (rootRootScrollFrame) { + rootScrollableFrame = aScrollFrame->GetScrollTargetFrame(); + } + if (rootScrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) { + CSSMargin margins = CSSMargin::FromAppUnits(rootScrollableFrame->GetActualScrollbarSizes()); + size.width -= margins.LeftRight(); + size.height -= margins.TopBottom(); + } + + return size; +} + static void RecordFrameMetrics(nsIFrame* aForFrame, nsIFrame* aScrollFrame, const nsIFrame* aReferenceFrame, ContainerLayer* aRoot, const nsRect& aVisibleRect, const nsRect& aViewport, nsRect* aDisplayPort, nsRect* aCriticalDisplayPort, @@ -801,16 +880,20 @@ static void RecordFrameMetrics(nsIFrame* // Adjust composition bounds for the size of scroll bars. if (scrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) { nsMargin sizes = scrollableFrame->GetActualScrollbarSizes(); // Scrollbars are not subject to scaling, so CSS pixels = layer pixels for them. ParentLayerIntMargin boundMargins = RoundedToInt(CSSMargin::FromAppUnits(sizes) * CSSToParentLayerScale(1.0f)); metrics.mCompositionBounds.Deflate(boundMargins); } + metrics.SetRootCompositionSize( + CalculateRootCompositionSize(metrics, isRootContentDocRootScrollFrame, + presContext, aForFrame, aScrollFrame)); + if (GetApzcTreePrintPref()) { if (nsIContent* content = frameForCompositionBoundsCalculation->GetContent()) { nsAutoString contentDescription; content->Describe(contentDescription); metrics.SetContentDescription(NS_LossyConvertUTF16toASCII(contentDescription).get()); } }