зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1076163 - Basic APZ support for css-driven resolution. r=kats,tn
This makes APZ behave nicely with most uses of a css transform:scale. Summary of changes: - FrameMetrics::mCumulativeResolution now includes the css-driven resolution in addition to the pres-shell resolution. - Displayports are now stored in Screen pixels rather than Layer pixels. This is what we want anyways (as we'd like the displayport size to remain constant as a fraction of the screen size), but it was necessary to make this change as part of this patch because continuing to store them in Layer pixels in the presence of a css-driven resolution would have required a bunch of infrastructure to implement correctly. Remaining work: - Layout painting a scrollable layer at a resolution different from the scale induced by the css transform causes problems. These will go away with bug 1076192. - Different resolutions on the x and y axes are not supported. This is tracked by bug 1039967.
This commit is contained in:
Родитель
d6f9c2f3a4
Коммит
57adf459d4
|
@ -444,11 +444,11 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
|
|||
}
|
||||
|
||||
// Note order change of arguments between our function signature and
|
||||
// LayerMargin constructor.
|
||||
LayerMargin displayportMargins(aTopMargin,
|
||||
aRightMargin,
|
||||
aBottomMargin,
|
||||
aLeftMargin);
|
||||
// ScreenMargin constructor.
|
||||
ScreenMargin displayportMargins(aTopMargin,
|
||||
aRightMargin,
|
||||
aBottomMargin,
|
||||
aLeftMargin);
|
||||
|
||||
nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins,
|
||||
aAlignmentX, aAlignmentY, aPriority);
|
||||
|
|
|
@ -181,7 +181,7 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
* that each edge is located at a multiple of the "alignment" value.
|
||||
*
|
||||
* Note that both the margin values and alignment are treated as values in
|
||||
* LayerPixels. Refer to layout/base/Units.h for a description of this unit.
|
||||
* ScreenPixels. Refer to layout/base/Units.h for a description of this unit.
|
||||
* The base rect values are in app units.
|
||||
*/
|
||||
void setDisplayPortMarginsForElement(in float aLeftMargin,
|
||||
|
|
|
@ -753,6 +753,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
|||
WriteParam(aMsg, aParam.mUpdateScrollOffset);
|
||||
WriteParam(aMsg, aParam.mScrollGeneration);
|
||||
WriteParam(aMsg, aParam.mTransformScale);
|
||||
WriteParam(aMsg, aParam.mExtraResolution);
|
||||
WriteParam(aMsg, aParam.mBackgroundColor);
|
||||
WriteParam(aMsg, aParam.mDoSmoothScroll);
|
||||
WriteParam(aMsg, aParam.mSmoothScrollOffset);
|
||||
|
@ -794,6 +795,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
|||
ReadParam(aMsg, aIter, &aResult->mUpdateScrollOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollGeneration) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mTransformScale) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mExtraResolution) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mBackgroundColor) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDoSmoothScroll) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mSmoothScrollOffset) &&
|
||||
|
|
|
@ -97,6 +97,7 @@ public:
|
|||
, mUseDisplayPortMargins(false)
|
||||
, mPresShellId(-1)
|
||||
, mViewport(0, 0, 0, 0)
|
||||
, mExtraResolution(1)
|
||||
, mBackgroundColor(0, 0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
@ -126,6 +127,7 @@ public:
|
|||
mSmoothScrollOffset == aOther.mSmoothScrollOffset &&
|
||||
mHasScrollgrab == aOther.mHasScrollgrab &&
|
||||
mUpdateScrollOffset == aOther.mUpdateScrollOffset &&
|
||||
mExtraResolution == aOther.mExtraResolution &&
|
||||
mBackgroundColor == aOther.mBackgroundColor &&
|
||||
mDoSmoothScroll == aOther.mDoSmoothScroll;
|
||||
}
|
||||
|
@ -152,6 +154,18 @@ public:
|
|||
return mScrollId != NULL_SCROLL_ID;
|
||||
}
|
||||
|
||||
CSSToScreenScale DisplayportPixelsPerCSSPixel() const
|
||||
{
|
||||
// Note: use 'mZoom * ScreenToLayerScale(1.0f)' as the CSS-to-Layer scale
|
||||
// instead of LayersPixelsPerCSSPixel(), because displayport calculations
|
||||
// are done in the context of a repaint request, where we ask Layout to
|
||||
// repaint at a new resolution that includes any async zoom. Until this
|
||||
// repaint request is processed, LayersPixelsPerCSSPixel() does not yet
|
||||
// include the async zoom, but it will when the displayport is interpreted
|
||||
// for the repaint.
|
||||
return mZoom * ScreenToLayerScale(1.0f) / mExtraResolution;
|
||||
}
|
||||
|
||||
CSSToLayerScale LayersPixelsPerCSSPixel() const
|
||||
{
|
||||
return mCumulativeResolution * mDevPixelsPerCSSPixel;
|
||||
|
@ -339,15 +353,7 @@ public:
|
|||
// This information is provided by Gecko at layout/paint time.
|
||||
LayoutDeviceToLayerScale mCumulativeResolution;
|
||||
|
||||
// The conversion factor between local screen pixels (the coordinate
|
||||
// system in which APZCs receive input events) and our parent layer's
|
||||
// layer pixels (the coordinate system of mCompositionBounds).
|
||||
// This consists of the scale of the local CSS transform and the
|
||||
// nontransient async transform.
|
||||
// TODO: APZ does not currently work well if there is a CSS transform
|
||||
// on the layer being scrolled that's not just a scale that's
|
||||
// the same in both directions. When we fix this, mTransformScale
|
||||
// will probably need to turn into a matrix.
|
||||
// TODO(botond): This is now always 1 and should be removed (see bug 1055741).
|
||||
ScreenToParentLayerScale mTransformScale;
|
||||
|
||||
// The conversion factor between CSS pixels and device pixels for this frame.
|
||||
|
@ -464,12 +470,12 @@ public:
|
|||
return mRootCompositionSize;
|
||||
}
|
||||
|
||||
void SetDisplayPortMargins(const LayerMargin& aDisplayPortMargins)
|
||||
void SetDisplayPortMargins(const ScreenMargin& aDisplayPortMargins)
|
||||
{
|
||||
mDisplayPortMargins = aDisplayPortMargins;
|
||||
}
|
||||
|
||||
const LayerMargin& GetDisplayPortMargins() const
|
||||
const ScreenMargin& GetDisplayPortMargins() const
|
||||
{
|
||||
return mDisplayPortMargins;
|
||||
}
|
||||
|
@ -504,6 +510,16 @@ public:
|
|||
return mViewport;
|
||||
}
|
||||
|
||||
void SetExtraResolution(const ScreenToLayerScale& aExtraResolution)
|
||||
{
|
||||
mExtraResolution = aExtraResolution;
|
||||
}
|
||||
|
||||
ScreenToLayerScale GetExtraResolution() const
|
||||
{
|
||||
return mExtraResolution;
|
||||
}
|
||||
|
||||
const gfxRGBA& GetBackgroundColor() const
|
||||
{
|
||||
return mBackgroundColor;
|
||||
|
@ -605,7 +621,7 @@ private:
|
|||
|
||||
// A display port expressed as layer margins that apply to the rect of what
|
||||
// is drawn of the scrollable element.
|
||||
LayerMargin mDisplayPortMargins;
|
||||
ScreenMargin mDisplayPortMargins;
|
||||
|
||||
// If this is true then we use the display port margins on this metrics,
|
||||
// otherwise use the display port rect.
|
||||
|
@ -624,6 +640,10 @@ private:
|
|||
// meaningless and invalid.
|
||||
CSSRect mViewport;
|
||||
|
||||
// The extra resolution at which content in this scroll frame is drawn beyond
|
||||
// that necessary to draw one Layer pixel per Screen pixel.
|
||||
ScreenToLayerScale mExtraResolution;
|
||||
|
||||
// The background color to use when overscrolling.
|
||||
gfxRGBA mBackgroundColor;
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ struct APZCTreeManager::TreeBuildingState {
|
|||
std::map<ScrollableLayerGuid, AsyncPanZoomController*> mApzcMap;
|
||||
};
|
||||
|
||||
/*static*/ const LayerMargin
|
||||
/*static*/ const ScreenMargin
|
||||
APZCTreeManager::CalculatePendingDisplayPort(
|
||||
const FrameMetrics& aFrameMetrics,
|
||||
const ScreenPoint& aVelocity,
|
||||
|
|
|
@ -245,7 +245,7 @@ public:
|
|||
* function simply delegates to that one, so that non-layers code
|
||||
* never needs to include AsyncPanZoomController.h
|
||||
*/
|
||||
static const LayerMargin CalculatePendingDisplayPort(
|
||||
static const ScreenMargin CalculatePendingDisplayPort(
|
||||
const FrameMetrics& aFrameMetrics,
|
||||
const ScreenPoint& aVelocity,
|
||||
double aEstimatedPaintDuration);
|
||||
|
|
|
@ -2198,7 +2198,7 @@ RedistributeDisplayPortExcess(CSSSize& aDisplayPortSize,
|
|||
}
|
||||
|
||||
/* static */
|
||||
const LayerMargin AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||
const ScreenMargin AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||
const FrameMetrics& aFrameMetrics,
|
||||
const ScreenPoint& aVelocity,
|
||||
double aEstimatedPaintDuration)
|
||||
|
@ -2240,9 +2240,7 @@ const LayerMargin AsyncPanZoomController::CalculatePendingDisplayPort(
|
|||
cssMargins.right = displayPort.width - compositionSize.width - cssMargins.left;
|
||||
cssMargins.bottom = displayPort.height - compositionSize.height - cssMargins.top;
|
||||
|
||||
LayerMargin layerMargins = cssMargins * aFrameMetrics.LayersPixelsPerCSSPixel();
|
||||
|
||||
return layerMargins;
|
||||
return cssMargins * aFrameMetrics.DisplayportPixelsPerCSSPixel();
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::ScheduleComposite() {
|
||||
|
@ -2320,8 +2318,8 @@ void AsyncPanZoomController::RequestContentRepaint(FrameMetrics& aFrameMetrics,
|
|||
|
||||
// If we're trying to paint what we already think is painted, discard this
|
||||
// request since it's a pointless paint.
|
||||
LayerMargin marginDelta = mLastPaintRequestMetrics.GetDisplayPortMargins()
|
||||
- aFrameMetrics.GetDisplayPortMargins();
|
||||
ScreenMargin marginDelta = (mLastPaintRequestMetrics.GetDisplayPortMargins()
|
||||
- aFrameMetrics.GetDisplayPortMargins());
|
||||
if (fabsf(marginDelta.left) < EPSILON &&
|
||||
fabsf(marginDelta.top) < EPSILON &&
|
||||
fabsf(marginDelta.right) < EPSILON &&
|
||||
|
@ -2359,7 +2357,7 @@ GetDisplayPortRect(const FrameMetrics& aFrameMetrics)
|
|||
// changes then this might need to change too
|
||||
CSSRect baseRect(aFrameMetrics.GetScrollOffset(),
|
||||
aFrameMetrics.CalculateBoundedCompositedSizeInCssPixels());
|
||||
baseRect.Inflate(aFrameMetrics.GetDisplayPortMargins() / aFrameMetrics.LayersPixelsPerCSSPixel());
|
||||
baseRect.Inflate(aFrameMetrics.GetDisplayPortMargins() / aFrameMetrics.DisplayportPixelsPerCSSPixel());
|
||||
return baseRect;
|
||||
}
|
||||
|
||||
|
@ -2694,7 +2692,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
|
|||
mLastDispatchedPaintMetrics = aLayerMetrics;
|
||||
ShareCompositorFrameMetrics();
|
||||
|
||||
if (mFrameMetrics.GetDisplayPortMargins() != LayerMargin()) {
|
||||
if (mFrameMetrics.GetDisplayPortMargins() != ScreenMargin()) {
|
||||
// A non-zero display port margin here indicates a displayport has
|
||||
// been set by a previous APZC for the content at this guid. The
|
||||
// scrollable rect may have changed since then, making the margins
|
||||
|
|
|
@ -245,7 +245,7 @@ public:
|
|||
* checkerboard immediately. This includes a bunch of logic, including
|
||||
* algorithms to bias painting in the direction of the velocity.
|
||||
*/
|
||||
static const LayerMargin CalculatePendingDisplayPort(
|
||||
static const ScreenMargin CalculatePendingDisplayPort(
|
||||
const FrameMetrics& aFrameMetrics,
|
||||
const ScreenPoint& aVelocity,
|
||||
double aEstimatedPaintDuration);
|
||||
|
|
|
@ -35,10 +35,10 @@ AdjustDisplayPortForScrollDelta(mozilla::layers::FrameMetrics& aFrameMetrics,
|
|||
{
|
||||
// Correct the display-port by the difference between the requested scroll
|
||||
// offset and the resulting scroll offset after setting the requested value.
|
||||
LayerPoint shift =
|
||||
ScreenPoint shift =
|
||||
(aFrameMetrics.GetScrollOffset() - aActualScrollOffset) *
|
||||
aFrameMetrics.LayersPixelsPerCSSPixel();
|
||||
LayerMargin margins = aFrameMetrics.GetDisplayPortMargins();
|
||||
aFrameMetrics.DisplayportPixelsPerCSSPixel();
|
||||
ScreenMargin margins = aFrameMetrics.GetDisplayPortMargins();
|
||||
margins.left -= shift.x;
|
||||
margins.right += shift.x;
|
||||
margins.top -= shift.y;
|
||||
|
@ -49,7 +49,7 @@ AdjustDisplayPortForScrollDelta(mozilla::layers::FrameMetrics& aFrameMetrics,
|
|||
static void
|
||||
RecenterDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics)
|
||||
{
|
||||
LayerMargin margins = aFrameMetrics.GetDisplayPortMargins();
|
||||
ScreenMargin margins = aFrameMetrics.GetDisplayPortMargins();
|
||||
margins.right = margins.left = margins.LeftRight() / 2;
|
||||
margins.top = margins.bottom = margins.TopBottom() / 2;
|
||||
aFrameMetrics.SetDisplayPortMargins(margins);
|
||||
|
@ -170,7 +170,7 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
|
|||
gfx::IntSize alignment = gfxPlatform::GetPlatform()->UseTiling()
|
||||
? gfx::IntSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight()) :
|
||||
gfx::IntSize(0, 0);
|
||||
LayerMargin margins = aMetrics.GetDisplayPortMargins();
|
||||
ScreenMargin margins = aMetrics.GetDisplayPortMargins();
|
||||
aUtils->SetDisplayPortMarginsForElement(margins.left,
|
||||
margins.top,
|
||||
margins.right,
|
||||
|
@ -219,7 +219,7 @@ APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent,
|
|||
gfx::IntSize alignment = gfxPlatform::GetPlatform()->UseTiling()
|
||||
? gfx::IntSize(gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight()) :
|
||||
gfx::IntSize(0, 0);
|
||||
LayerMargin margins = aMetrics.GetDisplayPortMargins();
|
||||
ScreenMargin margins = aMetrics.GetDisplayPortMargins();
|
||||
utils->SetDisplayPortMarginsForElement(margins.left,
|
||||
margins.top,
|
||||
margins.right,
|
||||
|
|
|
@ -198,6 +198,11 @@ struct LayoutDevicePixel {
|
|||
NSAppUnitsToFloatPixels(aRect.height, float(aAppUnitsPerDevPixel)));
|
||||
}
|
||||
|
||||
static LayoutDevicePoint FromAppUnits(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
|
||||
return LayoutDevicePoint(NSAppUnitsToFloatPixels(aPoint.x, aAppUnitsPerDevPixel),
|
||||
NSAppUnitsToFloatPixels(aPoint.y, aAppUnitsPerDevPixel));
|
||||
}
|
||||
|
||||
static LayoutDeviceIntPoint FromAppUnitsRounded(const nsPoint& aPoint, nscoord aAppUnitsPerDevPixel) {
|
||||
return LayoutDeviceIntPoint(NSAppUnitsToIntPixels(aPoint.x, aAppUnitsPerDevPixel),
|
||||
NSAppUnitsToIntPixels(aPoint.y, aAppUnitsPerDevPixel));
|
||||
|
@ -215,6 +220,13 @@ struct LayoutDevicePixel {
|
|||
return nsSize(aSize.width * aAppUnitsPerDevPixel,
|
||||
aSize.height * aAppUnitsPerDevPixel);
|
||||
}
|
||||
|
||||
static nsRect ToAppUnits(const LayoutDeviceRect& aRect, nscoord aAppUnitsPerDevPixel) {
|
||||
return nsRect(NSFloatPixelsToAppUnits(aRect.x, aAppUnitsPerDevPixel),
|
||||
NSFloatPixelsToAppUnits(aRect.y, aAppUnitsPerDevPixel),
|
||||
NSFloatPixelsToAppUnits(aRect.width, aAppUnitsPerDevPixel),
|
||||
NSFloatPixelsToAppUnits(aRect.height, aAppUnitsPerDevPixel));
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -663,7 +663,6 @@ nsDisplayScrollLayer::ComputeFrameMetrics(nsIFrame* aForFrame,
|
|||
{
|
||||
nsPresContext* presContext = aForFrame->PresContext();
|
||||
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||
LayoutDeviceToLayerScale resolution(aContainerParameters.mXScale, aContainerParameters.mYScale);
|
||||
|
||||
nsIPresShell* presShell = presContext->GetPresShell();
|
||||
FrameMetrics metrics;
|
||||
|
@ -730,18 +729,18 @@ nsDisplayScrollLayer::ComputeFrameMetrics(nsIFrame* aForFrame,
|
|||
} else {
|
||||
metrics.mResolution = ParentLayerToLayerScale(1.0f);
|
||||
}
|
||||
// The cumulative resolution is the resolution at which the scroll frame's
|
||||
// content is actually rendered. It includes the pres shell resolutions of
|
||||
// all the pres shells from here up to the root, as well as any css-driven
|
||||
// resolution. We don't need to compute it as it's already stored in the
|
||||
// container parameters.
|
||||
metrics.mCumulativeResolution = LayoutDeviceToLayerScale(aContainerParameters.mXScale,
|
||||
aContainerParameters.mYScale);
|
||||
|
||||
// For the cumulateive resolution, multiply the resolutions of all the
|
||||
// presShells back up to the root
|
||||
metrics.mCumulativeResolution = LayoutDeviceToLayerScale(1.0f);
|
||||
nsIPresShell* curPresShell = presShell;
|
||||
while (curPresShell != nullptr) {
|
||||
ParentLayerToLayerScale presShellResolution(curPresShell->GetXResolution(),
|
||||
curPresShell->GetYResolution());
|
||||
metrics.mCumulativeResolution.scale *= presShellResolution.scale;
|
||||
nsPresContext* parentContext = curPresShell->GetPresContext()->GetParentPresContext();
|
||||
curPresShell = parentContext ? parentContext->GetPresShell() : nullptr;
|
||||
}
|
||||
LayoutDeviceToScreenScale resolutionToScreen(
|
||||
presShell->GetCumulativeResolution().width
|
||||
* nsLayoutUtils::GetTransformToAncestorScale(aScrollFrame ? aScrollFrame : aForFrame).width);
|
||||
metrics.SetExtraResolution(metrics.mCumulativeResolution / resolutionToScreen);
|
||||
|
||||
metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(
|
||||
(float)nsPresContext::AppUnitsPerCSSPixel() / auPerDevPixel);
|
||||
|
|
|
@ -836,32 +836,41 @@ GetDisplayPortFromMarginsData(nsIContent* aContent,
|
|||
|
||||
nsPresContext* presContext = frame->PresContext();
|
||||
int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||
gfxSize res = presContext->PresShell()->GetCumulativeResolution();
|
||||
|
||||
// First convert the base rect to layer pixels
|
||||
gfxSize parentRes = res;
|
||||
LayoutDeviceToScreenScale res(presContext->PresShell()->GetCumulativeResolution().width
|
||||
* nsLayoutUtils::GetTransformToAncestorScale(frame).width);
|
||||
|
||||
// First convert the base rect to screen pixels
|
||||
LayoutDeviceToScreenScale parentRes = res;
|
||||
if (isRoot) {
|
||||
// the base rect for root scroll frames is specified in the parent document
|
||||
// coordinate space, so it doesn't include the local resolution.
|
||||
gfxSize localRes = presContext->PresShell()->GetResolution();
|
||||
parentRes.width /= localRes.width;
|
||||
parentRes.height /= localRes.height;
|
||||
parentRes.scale /= localRes.width;
|
||||
}
|
||||
LayerRect layerRect(NSAppUnitsToFloatPixels(base.x, auPerDevPixel) * parentRes.width,
|
||||
NSAppUnitsToFloatPixels(base.y, auPerDevPixel) * parentRes.height,
|
||||
NSAppUnitsToFloatPixels(base.width, auPerDevPixel) * parentRes.width,
|
||||
NSAppUnitsToFloatPixels(base.height, auPerDevPixel) * parentRes.height);
|
||||
ScreenRect screenRect = LayoutDeviceRect::FromAppUnits(base, auPerDevPixel)
|
||||
* parentRes;
|
||||
|
||||
// Expand the rect by the margins
|
||||
layerRect.Inflate(aMarginsData->mMargins);
|
||||
screenRect.Inflate(aMarginsData->mMargins);
|
||||
|
||||
// And then align it to the requested alignment
|
||||
// And then align it to the requested alignment.
|
||||
// Note on the correctness of applying the alignment in Screen space:
|
||||
// The correct space to apply the alignment in would be Layer space, but
|
||||
// we don't necessarily know the scale to convert to Layer space at this
|
||||
// point because Layout may not yet have chosen the resolution at which to
|
||||
// render (it chooses that in FrameLayerBuilder, but this can be called
|
||||
// during display list building). Therefore, we perform the alignment in
|
||||
// Screen space, which basically assumes that Layout chose to render at
|
||||
// screen resolution; since this is what Layout does most of the time,
|
||||
// this is a good approximation. A proper solution would involve moving the
|
||||
// choosing of the resolution to display-list building time.
|
||||
if (aMarginsData->mAlignmentX > 0 || aMarginsData->mAlignmentY > 0) {
|
||||
// Inflate the rectangle by 1 so that we always push to the next tile
|
||||
// boundary. This is desirable to stop from having a rectangle with a
|
||||
// moving origin occasionally being smaller when it coincidentally lines
|
||||
// up to tile boundaries.
|
||||
layerRect.Inflate(1);
|
||||
screenRect.Inflate(1);
|
||||
|
||||
// Avoid division by zero.
|
||||
if (aMarginsData->mAlignmentX == 0) {
|
||||
|
@ -871,23 +880,20 @@ GetDisplayPortFromMarginsData(nsIContent* aContent,
|
|||
aMarginsData->mAlignmentY = 1;
|
||||
}
|
||||
|
||||
LayerPoint scrollPosLayer(NSAppUnitsToFloatPixels(scrollPos.x, auPerDevPixel) * res.width,
|
||||
NSAppUnitsToFloatPixels(scrollPos.y, auPerDevPixel) * res.height);
|
||||
ScreenPoint scrollPosScreen = LayoutDevicePoint::FromAppUnits(scrollPos, auPerDevPixel)
|
||||
* res;
|
||||
|
||||
layerRect += scrollPosLayer;
|
||||
float x = aMarginsData->mAlignmentX * floor(layerRect.x / aMarginsData->mAlignmentX);
|
||||
float y = aMarginsData->mAlignmentY * floor(layerRect.y / aMarginsData->mAlignmentY);
|
||||
float w = aMarginsData->mAlignmentX * ceil(layerRect.XMost() / aMarginsData->mAlignmentX) - x;
|
||||
float h = aMarginsData->mAlignmentY * ceil(layerRect.YMost() / aMarginsData->mAlignmentY) - y;
|
||||
layerRect = LayerRect(x, y, w, h);
|
||||
layerRect -= scrollPosLayer;
|
||||
screenRect += scrollPosScreen;
|
||||
float x = aMarginsData->mAlignmentX * floor(screenRect.x / aMarginsData->mAlignmentX);
|
||||
float y = aMarginsData->mAlignmentY * floor(screenRect.y / aMarginsData->mAlignmentY);
|
||||
float w = aMarginsData->mAlignmentX * ceil(screenRect.XMost() / aMarginsData->mAlignmentX) - x;
|
||||
float h = aMarginsData->mAlignmentY * ceil(screenRect.YMost() / aMarginsData->mAlignmentY) - y;
|
||||
screenRect = ScreenRect(x, y, w, h);
|
||||
screenRect -= scrollPosScreen;
|
||||
}
|
||||
|
||||
// Convert the aligned rect back into app units
|
||||
nsRect result(NSFloatPixelsToAppUnits(layerRect.x / res.width, auPerDevPixel),
|
||||
NSFloatPixelsToAppUnits(layerRect.y / res.height, auPerDevPixel),
|
||||
NSFloatPixelsToAppUnits(layerRect.width / res.width, auPerDevPixel),
|
||||
NSFloatPixelsToAppUnits(layerRect.height / res.height, auPerDevPixel));
|
||||
nsRect result = LayoutDeviceRect::ToAppUnits(screenRect / res, auPerDevPixel);
|
||||
|
||||
// Expand it for the low-res buffer if needed
|
||||
result = ApplyRectMultiplier(result, aMultiplier);
|
||||
|
@ -950,7 +956,7 @@ nsLayoutUtils::GetDisplayPort(nsIContent* aContent, nsRect *aResult)
|
|||
void
|
||||
nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell,
|
||||
const LayerMargin& aMargins,
|
||||
const ScreenMargin& aMargins,
|
||||
uint32_t aAlignmentX,
|
||||
uint32_t aAlignmentY,
|
||||
uint32_t aPriority,
|
||||
|
@ -2301,6 +2307,19 @@ nsLayoutUtils::GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncesto
|
|||
return ctm;
|
||||
}
|
||||
|
||||
gfxSize
|
||||
nsLayoutUtils::GetTransformToAncestorScale(nsIFrame* aFrame)
|
||||
{
|
||||
Matrix4x4 transform = GetTransformToAncestor(aFrame,
|
||||
nsLayoutUtils::GetDisplayRootFrame(aFrame));
|
||||
Matrix transform2D;
|
||||
if (transform.Is2D(&transform2D)) {
|
||||
return ThebesMatrix(transform2D).ScaleFactors(true);
|
||||
}
|
||||
return gfxSize(1, 1);
|
||||
}
|
||||
|
||||
|
||||
static nsIFrame*
|
||||
FindNearestCommonAncestorFrame(nsIFrame* aFrame1, nsIFrame* aFrame2)
|
||||
{
|
||||
|
@ -2772,7 +2791,15 @@ CalculateFrameMetricsForDisplayPort(nsIFrame* aScrollFrame,
|
|||
resolution = ParentLayerToLayerScale(presShell->GetXResolution(),
|
||||
presShell->GetYResolution());
|
||||
}
|
||||
LayoutDeviceToLayerScale cumulativeResolution(presShell->GetCumulativeResolution().width);
|
||||
// Note: unlike in ComputeFrameMetrics(), we don't know the full cumulative
|
||||
// resolution including FrameMetrics::mExtraResolution, because layout hasn't
|
||||
// chosen a resolution to paint at yet. However, the display port calculation
|
||||
// divides out mExtraResolution anyways, so we get the correct result by
|
||||
// setting the mCumulativeResolution to everything except the extra resolution
|
||||
// and leaving mExtraResolution at 1.
|
||||
LayoutDeviceToLayerScale cumulativeResolution(
|
||||
presShell->GetCumulativeResolution().width
|
||||
* nsLayoutUtils::GetTransformToAncestorScale(aScrollFrame).width);
|
||||
|
||||
metrics.mDevPixelsPerCSSPixel = deviceScale;
|
||||
metrics.mResolution = resolution;
|
||||
|
@ -2841,7 +2868,7 @@ nsLayoutUtils::GetOrMaybeCreateDisplayPort(nsDisplayListBuilder& aBuilder,
|
|||
// If we don't already have a displayport, calculate and set one.
|
||||
if (!haveDisplayPort) {
|
||||
FrameMetrics metrics = CalculateFrameMetricsForDisplayPort(aScrollFrame, scrollableFrame);
|
||||
LayerMargin displayportMargins = APZCTreeManager::CalculatePendingDisplayPort(
|
||||
ScreenMargin displayportMargins = APZCTreeManager::CalculatePendingDisplayPort(
|
||||
metrics, ScreenPoint(0.0f, 0.0f), 0.0);
|
||||
nsIPresShell* presShell = aScrollFrame->PresContext()->GetPresShell();
|
||||
gfx::IntSize alignment = gfxPlatform::GetPlatform()->UseTiling()
|
||||
|
@ -7006,10 +7033,11 @@ nsLayoutUtils::CalculateRootCompositionSize(nsIFrame* aFrame,
|
|||
if (aIsRootContentDocRootScrollFrame) {
|
||||
return ViewAs<LayerPixel>(aMetrics.mCompositionBounds.Size(),
|
||||
PixelCastJustification::ParentLayerToLayerForRootComposition)
|
||||
/ aMetrics.LayersPixelsPerCSSPixel();
|
||||
* LayerToScreenScale(1.0f)
|
||||
/ aMetrics.DisplayportPixelsPerCSSPixel();
|
||||
}
|
||||
nsPresContext* presContext = aFrame->PresContext();
|
||||
LayerSize rootCompositionSize;
|
||||
ScreenSize rootCompositionSize;
|
||||
nsPresContext* rootPresContext =
|
||||
presContext->GetToplevelContentDocumentPresContext();
|
||||
if (!rootPresContext) {
|
||||
|
@ -7023,12 +7051,13 @@ nsLayoutUtils::CalculateRootCompositionSize(nsIFrame* aFrame,
|
|||
nsIPresShell* rootPresShell = rootPresContext->PresShell();
|
||||
if (nsIFrame* rootFrame = rootPresShell->GetRootFrame()) {
|
||||
LayoutDeviceToLayerScale cumulativeResolution(
|
||||
rootPresShell->GetCumulativeResolution().width);
|
||||
rootPresShell->GetCumulativeResolution().width
|
||||
* nsLayoutUtils::GetTransformToAncestorScale(rootFrame).width);
|
||||
int32_t rootAUPerDevPixel = rootPresContext->AppUnitsPerDevPixel();
|
||||
LayerSize frameSize =
|
||||
(LayoutDeviceRect::FromAppUnits(rootFrame->GetRect(), rootAUPerDevPixel)
|
||||
* cumulativeResolution).Size();
|
||||
rootCompositionSize = frameSize;
|
||||
rootCompositionSize = frameSize * LayerToScreenScale(1.0f);
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
nsIWidget* widget = rootFrame->GetNearestWidget();
|
||||
#else
|
||||
|
@ -7038,7 +7067,7 @@ nsLayoutUtils::CalculateRootCompositionSize(nsIFrame* aFrame,
|
|||
if (widget) {
|
||||
nsIntRect widgetBounds;
|
||||
widget->GetBounds(widgetBounds);
|
||||
rootCompositionSize = LayerSize(ViewAs<LayerPixel>(widgetBounds.Size()));
|
||||
rootCompositionSize = ScreenSize(ViewAs<ScreenPixel>(widgetBounds.Size()));
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (frameSize.height < rootCompositionSize.height) {
|
||||
rootCompositionSize.height = frameSize.height;
|
||||
|
@ -7052,7 +7081,7 @@ nsLayoutUtils::CalculateRootCompositionSize(nsIFrame* aFrame,
|
|||
gfxSize res = rootPresContext->GetParentPresContext()->PresShell()->GetCumulativeResolution();
|
||||
scale = LayoutDeviceToLayerScale(res.width, res.height);
|
||||
}
|
||||
rootCompositionSize = contentSize * scale;
|
||||
rootCompositionSize = contentSize * scale * LayerToScreenScale(1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7060,7 +7089,7 @@ nsLayoutUtils::CalculateRootCompositionSize(nsIFrame* aFrame,
|
|||
nsIWidget* widget = aFrame->GetNearestWidget();
|
||||
nsIntRect widgetBounds;
|
||||
widget->GetBounds(widgetBounds);
|
||||
rootCompositionSize = LayerSize(ViewAs<LayerPixel>(widgetBounds.Size()));
|
||||
rootCompositionSize = ScreenSize(ViewAs<ScreenPixel>(widgetBounds.Size()));
|
||||
}
|
||||
|
||||
// Adjust composition size for the size of scroll bars.
|
||||
|
@ -7076,7 +7105,7 @@ nsLayoutUtils::CalculateRootCompositionSize(nsIFrame* aFrame,
|
|||
rootCompositionSize.height -= margins.TopBottom();
|
||||
}
|
||||
|
||||
return rootCompositionSize / aMetrics.LayersPixelsPerCSSPixel();
|
||||
return rootCompositionSize / aMetrics.DisplayportPixelsPerCSSPixel();
|
||||
}
|
||||
|
||||
/* static */ nsRect
|
||||
|
|
|
@ -95,7 +95,7 @@ struct DisplayPortPropertyData {
|
|||
};
|
||||
|
||||
struct DisplayPortMarginsPropertyData {
|
||||
DisplayPortMarginsPropertyData(const LayerMargin& aMargins,
|
||||
DisplayPortMarginsPropertyData(const ScreenMargin& aMargins,
|
||||
uint32_t aAlignmentX, uint32_t aAlignmentY,
|
||||
uint32_t aPriority)
|
||||
: mMargins(aMargins)
|
||||
|
@ -103,7 +103,7 @@ struct DisplayPortMarginsPropertyData {
|
|||
, mAlignmentY(aAlignmentY)
|
||||
, mPriority(aPriority)
|
||||
{}
|
||||
LayerMargin mMargins;
|
||||
ScreenMargin mMargins;
|
||||
uint32_t mAlignmentX;
|
||||
uint32_t mAlignmentY;
|
||||
uint32_t mPriority;
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
typedef FrameMetrics::ViewID ViewID;
|
||||
typedef mozilla::CSSPoint CSSPoint;
|
||||
typedef mozilla::CSSSize CSSSize;
|
||||
typedef mozilla::LayerMargin LayerMargin;
|
||||
typedef mozilla::ScreenMargin ScreenMargin;
|
||||
typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize;
|
||||
|
||||
/**
|
||||
|
@ -188,7 +188,7 @@ public:
|
|||
*/
|
||||
static void SetDisplayPortMargins(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell,
|
||||
const LayerMargin& aMargins,
|
||||
const ScreenMargin& aMargins,
|
||||
uint32_t aAlignmentX,
|
||||
uint32_t aAlignmentY,
|
||||
uint32_t aPriority = 0,
|
||||
|
@ -742,6 +742,12 @@ public:
|
|||
*/
|
||||
static Matrix4x4 GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor);
|
||||
|
||||
/**
|
||||
* Gets the scale factors of the transform for aFrame relative to the root
|
||||
* frame if this transform is 2D, or the identity scale factors otherwise.
|
||||
*/
|
||||
static gfxSize GetTransformToAncestorScale(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into
|
||||
* account all relevant transformations on the frames up to (but excluding)
|
||||
|
|
|
@ -1876,7 +1876,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter,
|
|||
// when scrolling.
|
||||
nsLayoutUtils::SetDisplayPortMargins(mOuter->GetContent(),
|
||||
mOuter->PresContext()->PresShell(),
|
||||
LayerMargin(),
|
||||
ScreenMargin(),
|
||||
gfxPrefs::LayersTileWidth(), gfxPrefs::LayersTileHeight(),
|
||||
0,
|
||||
nsLayoutUtils::RepaintMode::DoNotRepaint);
|
||||
|
|
Загрузка…
Ссылка в новой задаче