Bug 1228597 - Clean up code paths that (un)apply a pres shell resolution. r=tn,botond

A clear separation is introduced between paths that deal with a root
document resolution (at the process boundary in e10s setups) and paths
that deal with a non-root document resolution (elsewhere in Layout code).

This allows both code paths to run on all platforms.
This commit is contained in:
Kartikaya Gupta 2015-11-30 19:13:20 -05:00
parent 9a94f1ce0c
commit a2ba6213c3
7 changed files with 60 additions and 24 deletions

View File

@ -7672,7 +7672,8 @@ nsContentUtils::ToWidgetPoint(const CSSPoint& aPoint,
nsPresContext* aPresContext)
{
return LayoutDeviceIntPoint::FromAppUnitsRounded(
(CSSPoint::ToAppUnits(aPoint) + aOffset).ApplyResolution(aPresContext->PresShell()->GetCumulativeScaleResolution()),
(CSSPoint::ToAppUnits(aPoint) +
aOffset).ApplyResolution(aPresContext->PresShell()->GetCumulativeNonRootScaleResolution()),
aPresContext->AppUnitsPerDevPixel());
}

View File

@ -936,7 +936,7 @@ Event::GetScreenCoords(nsPresContext* aPresContext,
LayoutDevicePixel::ToAppUnits(aPoint, aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
if (aPresContext->PresShell()) {
pt = pt.RemoveResolution(aPresContext->PresShell()->GetCumulativeScaleResolution());
pt = pt.RemoveResolution(aPresContext->PresShell()->GetCumulativeNonRootScaleResolution());
}
pt += LayoutDevicePixel::ToAppUnits(guiEvent->widget->WidgetToScreenOffset(),

View File

@ -415,6 +415,28 @@ APZCCallbackHelper::GetRootContentDocumentPresShellForContent(nsIContent* aConte
return context->PresShell();
}
static nsIPresShell*
GetRootDocumentPresShell(nsIContent* aContent)
{
nsIDocument* doc = aContent->GetComposedDoc();
if (!doc) {
return nullptr;
}
nsIPresShell* shell = doc->GetShell();
if (!shell) {
return nullptr;
}
nsPresContext* context = shell->GetPresContext();
if (!context) {
return nullptr;
}
context = context->GetRootPresContext();
if (!context) {
return nullptr;
}
return context->PresShell();
}
CSSPoint
APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
const ScrollableLayerGuid& aGuid)
@ -423,7 +445,21 @@ APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
if (aGuid.mScrollId == FrameMetrics::NULL_SCROLL_ID) {
return input;
}
// Apply the callback-transform.
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aGuid.mScrollId);
if (!content) {
return input;
}
// First, scale inversely by the root content document's pres shell
// resolution to cancel the scale-to-resolution transform that the
// compositor adds to the layer with the pres shell resolution. The points
// sent to Gecko by APZ don't have this transform unapplied (unlike other
// compositor-side transforms) because APZ doesn't know about it.
if (nsIPresShell* shell = GetRootDocumentPresShell(content)) {
input = input / shell->GetResolution();
}
// Now apply the callback-transform.
// XXX: technically we need to walk all the way up the layer tree from the layer
// represented by |aGuid.mScrollId| up to the root of the layer tree and apply
// the input transforms at each level in turn. However, it is quite difficult
@ -434,19 +470,9 @@ APZCCallbackHelper::ApplyCallbackTransform(const CSSPoint& aInput,
// some things transformed improperly. In practice we should rarely hit scenarios
// where any of this matters, so I'm skipping it for now and just doing the single
// transform for the layer that the input hit.
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aGuid.mScrollId);
if (content) {
void* property = content->GetProperty(nsGkAtoms::apzCallbackTransform);
CSSPoint delta = property ? (*static_cast<CSSPoint*>(property)) : CSSPoint(0.0f, 0.0f);
// The delta is in root content document coordinate space while the
// aInput point is in root document coordinate space so convert the
// delta to root document space before adding it to the aInput point.
float resolution = 1.0f;
if (nsIPresShell* shell = GetRootContentDocumentPresShellForContent(content)) {
resolution = shell->GetResolution();
}
delta.x = delta.x * resolution;
delta.y = delta.y * resolution;
void* property = content->GetProperty(nsGkAtoms::apzCallbackTransform);
if (property) {
CSSPoint delta = (*static_cast<CSSPoint*>(property));
input += delta;
}
return input;

View File

@ -1416,7 +1416,12 @@ public:
virtual nsresult SetResolution(float aResolution) = 0;
float GetResolution() { return mResolution.valueOr(1.0); }
virtual float GetCumulativeResolution() = 0;
virtual float GetCumulativeScaleResolution() = 0;
/**
* Calculate the cumulative scale resolution from this document up to
* but not including the root document.
*/
virtual float GetCumulativeNonRootScaleResolution() = 0;
/**
* Was the current resolution set by the user or just default initialized?

View File

@ -2021,7 +2021,7 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(nsIWidget* aWidget,
nsPoint pt(presContext->DevPixelsToAppUnits(aPoint.x),
presContext->DevPixelsToAppUnits(aPoint.y));
pt = pt - view->ViewToWidgetOffset();
pt = pt.RemoveResolution(presContext->PresShell()->GetCumulativeScaleResolution());
pt = pt.RemoveResolution(presContext->PresShell()->GetCumulativeNonRootScaleResolution());
return pt;
}
}
@ -2060,7 +2060,7 @@ nsLayoutUtils::GetEventCoordinatesRelativeTo(nsIWidget* aWidget,
nsIPresShell* shell = aFrame->PresContext()->PresShell();
// XXX Bug 1224748 - Update nsLayoutUtils functions to correctly handle nsPresShell resolution
widgetToView = widgetToView.RemoveResolution(shell->GetCumulativeScaleResolution());
widgetToView = widgetToView.RemoveResolution(shell->GetCumulativeNonRootScaleResolution());
/* If we encountered a transform, we can't do simple arithmetic to figure
* out how to convert back to aFrame's coordinates and must use the CTM.
@ -2808,7 +2808,8 @@ nsLayoutUtils::TranslateViewToWidget(nsPresContext* aPresContext,
return LayoutDeviceIntPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
}
nsPoint pt = (aPt + viewOffset).ApplyResolution(aPresContext->PresShell()->GetCumulativeScaleResolution());
nsPoint pt = (aPt +
viewOffset).ApplyResolution(aPresContext->PresShell()->GetCumulativeNonRootScaleResolution());
LayoutDeviceIntPoint relativeToViewWidget(aPresContext->AppUnitsToDevPixels(pt.x),
aPresContext->AppUnitsToDevPixels(pt.y));
return relativeToViewWidget + WidgetToWidgetOffset(viewWidget, aWidget);

View File

@ -5330,13 +5330,16 @@ float PresShell::GetCumulativeResolution()
return resolution;
}
float PresShell::GetCumulativeScaleResolution()
float PresShell::GetCumulativeNonRootScaleResolution()
{
float resolution = 1.0;
nsIPresShell* currentShell = this;
while (currentShell) {
resolution *= currentShell->ScaleToResolution() ? currentShell->GetResolution() : 1.0f;
nsPresContext* parentCtx = currentShell->GetPresContext()->GetParentPresContext();
nsPresContext* currentCtx = currentShell->GetPresContext();
if (currentCtx != currentCtx->GetRootPresContext()) {
resolution *= currentShell->ScaleToResolution() ? currentShell->GetResolution() : 1.0f;
}
nsPresContext* parentCtx = currentCtx->GetParentPresContext();
if (parentCtx) {
currentShell = parentCtx->PresShell();
} else {

View File

@ -218,7 +218,7 @@ public:
}
virtual bool ScaleToResolution() const override;
virtual float GetCumulativeResolution() override;
virtual float GetCumulativeScaleResolution() override;
virtual float GetCumulativeNonRootScaleResolution() override;
//nsIViewObserver interface