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:
Botond Ballo 2014-10-24 15:49:38 -04:00
Родитель d6f9c2f3a4
Коммит 57adf459d4
14 изменённых файлов: 154 добавлений и 88 удалений

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

@ -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);