mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 935219 - Fix composition bounds calculation and APZC hit testing (again). r=kats,tn
--HG-- extra : amend_source : 06c6bb658dfead6907250831bbe73fae6c20b45c
This commit is contained in:
parent
4b19f5e6c6
commit
70dfe7ab91
@ -72,6 +72,7 @@
|
||||
#include "nsILoadContext.h"
|
||||
#include "ipc/nsGUIEventIPC.h"
|
||||
#include "mozilla/gfx/Matrix.h"
|
||||
#include "UnitTransforms.h"
|
||||
|
||||
#include "nsColorPickerProxy.h"
|
||||
|
||||
@ -316,7 +317,9 @@ TabChild::InitializeRootMetrics()
|
||||
// be keeping, as well as putting the scroll offset back to
|
||||
// the top-left of the page.
|
||||
mLastRootMetrics.mViewport = CSSRect(CSSPoint(), kDefaultViewportSize);
|
||||
mLastRootMetrics.mCompositionBounds = ScreenIntRect(ScreenIntPoint(), mInnerSize);
|
||||
mLastRootMetrics.mCompositionBounds = ParentLayerIntRect(
|
||||
ParentLayerIntPoint(),
|
||||
ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot));
|
||||
mLastRootMetrics.mZoom = mLastRootMetrics.CalculateIntrinsicScale();
|
||||
mLastRootMetrics.mDevPixelsPerCSSPixel = mWidget->GetDefaultScale();
|
||||
// We use ScreenToLayerScale(1) below in order to turn the
|
||||
@ -588,7 +591,9 @@ TabChild::HandlePossibleViewportChange()
|
||||
|
||||
FrameMetrics metrics(mLastRootMetrics);
|
||||
metrics.mViewport = CSSRect(CSSPoint(), viewport);
|
||||
metrics.mCompositionBounds = ScreenIntRect(ScreenIntPoint(), mInnerSize);
|
||||
metrics.mCompositionBounds = ParentLayerIntRect(
|
||||
ParentLayerIntPoint(),
|
||||
ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot));
|
||||
|
||||
// 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
|
||||
@ -631,7 +636,7 @@ TabChild::HandlePossibleViewportChange()
|
||||
metrics.mResolution = metrics.mCumulativeResolution / LayoutDeviceToParentLayerScale(1);
|
||||
utils->SetResolution(metrics.mResolution.scale, metrics.mResolution.scale);
|
||||
|
||||
CSSSize scrollPort = metrics.CalculateCompositedRectInCssPixels().Size();
|
||||
CSSSize scrollPort = CSSSize(metrics.CalculateCompositedRectInCssPixels().Size());
|
||||
utils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height);
|
||||
|
||||
// The call to GetPageSize forces a resize event to content, so we need to
|
||||
@ -1511,7 +1516,7 @@ TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
|
||||
FrameMetrics newMetrics = aFrameMetrics;
|
||||
APZCCallbackHelper::UpdateRootFrame(utils, newMetrics);
|
||||
|
||||
CSSRect cssCompositedRect = newMetrics.CalculateCompositedRectInCssPixels();
|
||||
CSSRect cssCompositedRect = CSSRect(newMetrics.CalculateCompositedRectInCssPixels());
|
||||
// The BrowserElementScrolling helper must know about these updated metrics
|
||||
// for other functions it performs, such as double tap handling.
|
||||
// Note, %f must not be used because it is locale specific!
|
||||
@ -1524,22 +1529,6 @@ TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
|
||||
data.AppendLiteral(", \"height\" : ");
|
||||
data.AppendFloat(newMetrics.mViewport.height);
|
||||
data.AppendLiteral(" }");
|
||||
data.AppendLiteral(", \"displayPort\" : ");
|
||||
data.AppendLiteral("{ \"x\" : ");
|
||||
data.AppendFloat(newMetrics.mDisplayPort.x);
|
||||
data.AppendLiteral(", \"y\" : ");
|
||||
data.AppendFloat(newMetrics.mDisplayPort.y);
|
||||
data.AppendLiteral(", \"width\" : ");
|
||||
data.AppendFloat(newMetrics.mDisplayPort.width);
|
||||
data.AppendLiteral(", \"height\" : ");
|
||||
data.AppendFloat(newMetrics.mDisplayPort.height);
|
||||
data.AppendLiteral(" }");
|
||||
data.AppendLiteral(", \"compositionBounds\" : ");
|
||||
data.AppendPrintf("{ \"x\" : %d", newMetrics.mCompositionBounds.x);
|
||||
data.AppendPrintf(", \"y\" : %d", newMetrics.mCompositionBounds.y);
|
||||
data.AppendPrintf(", \"width\" : %d", newMetrics.mCompositionBounds.width);
|
||||
data.AppendPrintf(", \"height\" : %d", newMetrics.mCompositionBounds.height);
|
||||
data.AppendLiteral(" }");
|
||||
data.AppendLiteral(", \"cssPageRect\" : ");
|
||||
data.AppendLiteral("{ \"x\" : ");
|
||||
data.AppendFloat(newMetrics.mScrollableRect.x);
|
||||
|
@ -622,6 +622,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
||||
WriteParam(aMsg, aParam.mUpdateScrollOffset);
|
||||
WriteParam(aMsg, aParam.mScrollGeneration);
|
||||
WriteParam(aMsg, aParam.mContentDescription);
|
||||
WriteParam(aMsg, aParam.mTransformScale);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
@ -643,7 +644,8 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
||||
ReadParam(aMsg, aIter, &aResult->mHasScrollgrab) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mUpdateScrollOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollGeneration) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mContentDescription));
|
||||
ReadParam(aMsg, aIter, &aResult->mContentDescription) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mTransformScale));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -19,18 +19,38 @@ template <typename T> struct ParamTraits;
|
||||
} // namespace IPC
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
// The layer coordinates of the parent layer. Like the layer coordinates
|
||||
// of the current layer (LayerPixel) but doesn't include the current layer's
|
||||
// resolution.
|
||||
// The layer coordinates of the parent layer.
|
||||
// This can be arrived at in two ways:
|
||||
// - Start with the CSS coordinates of the parent layer (note: NOT the
|
||||
// CSS coordinates of the current layer, that will give you the wrong
|
||||
// answer), multiply by the device scale and the resolutions of all
|
||||
// layers from the root down to and including the parent.
|
||||
// - Start with global screen coordinates and unapply all CSS and async
|
||||
// transforms from the root down to and including the parent.
|
||||
// It's helpful to look at https://wiki.mozilla.org/Platform/GFX/APZ#Coordinate_systems
|
||||
// to get a picture of how the various coordinate systems relate to each other.
|
||||
struct ParentLayerPixel {};
|
||||
|
||||
typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> LayoutDeviceToParentLayerScale;
|
||||
typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale;
|
||||
typedef gfx::PointTyped<ParentLayerPixel> ParentLayerPoint;
|
||||
typedef gfx::RectTyped<ParentLayerPixel> ParentLayerRect;
|
||||
typedef gfx::SizeTyped<ParentLayerPixel> ParentLayerSize;
|
||||
|
||||
typedef gfx::IntMarginTyped<ParentLayerPixel> ParentLayerIntMargin;
|
||||
typedef gfx::IntPointTyped<ParentLayerPixel> ParentLayerIntPoint;
|
||||
typedef gfx::IntRectTyped<ParentLayerPixel> ParentLayerIntRect;
|
||||
typedef gfx::IntSizeTyped<ParentLayerPixel> ParentLayerIntSize;
|
||||
|
||||
typedef gfx::ScaleFactor<CSSPixel, ParentLayerPixel> CSSToParentLayerScale;
|
||||
typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> LayoutDeviceToParentLayerScale;
|
||||
typedef gfx::ScaleFactor<ScreenPixel, ParentLayerPixel> ScreenToParentLayerScale;
|
||||
|
||||
typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale;
|
||||
typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel> ParentLayerToScreenScale;
|
||||
|
||||
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* The viewport and displayport metrics for the painted frame at the
|
||||
* time of a layer-tree transaction. These metrics are especially
|
||||
@ -57,6 +77,7 @@ public:
|
||||
, mResolution(1)
|
||||
, mCumulativeResolution(1)
|
||||
, mZoom(1)
|
||||
, mTransformScale(1)
|
||||
, mDevPixelsPerCSSPixel(1)
|
||||
, mPresShellId(-1)
|
||||
, mMayHaveTouchListeners(false)
|
||||
@ -135,7 +156,7 @@ public:
|
||||
CSSRect GetExpandedScrollableRect() const
|
||||
{
|
||||
CSSRect scrollableRect = mScrollableRect;
|
||||
CSSRect compBounds = CalculateCompositedRectInCssPixels();
|
||||
CSSRect compBounds = CSSRect(CalculateCompositedRectInCssPixels());
|
||||
if (scrollableRect.width < compBounds.width) {
|
||||
scrollableRect.x = std::max(0.f,
|
||||
scrollableRect.x - (compBounds.width - scrollableRect.width));
|
||||
@ -151,18 +172,26 @@ public:
|
||||
return scrollableRect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scale factor needed to fit the viewport
|
||||
* into its composition bounds.
|
||||
*/
|
||||
// Return the scale factor needed to fit the viewport
|
||||
// into its composition bounds.
|
||||
CSSToScreenScale CalculateIntrinsicScale() const
|
||||
{
|
||||
return CSSToScreenScale(float(mCompositionBounds.width) / float(mViewport.width));
|
||||
}
|
||||
|
||||
CSSRect CalculateCompositedRectInCssPixels() const
|
||||
// Return the scale factor for converting from CSS pixels (for this layer)
|
||||
// to layer pixels of our parent layer. Much as mZoom is used to interface
|
||||
// between inputs we get in screen pixels and quantities in CSS pixels,
|
||||
// this is used to interface between mCompositionBounds and quantities
|
||||
// in CSS pixels.
|
||||
CSSToParentLayerScale GetZoomToParent() const
|
||||
{
|
||||
return CSSRect(gfx::RoundedIn(mCompositionBounds / mZoom));
|
||||
return mZoom * mTransformScale;
|
||||
}
|
||||
|
||||
CSSIntRect CalculateCompositedRectInCssPixels() const
|
||||
{
|
||||
return gfx::RoundedIn(mCompositionBounds / GetZoomToParent());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -184,7 +213,7 @@ public:
|
||||
// This value is valid for nested scrollable layers as well, and is still
|
||||
// relative to the layer tree origin. This value is provided by Gecko at
|
||||
// layout/paint time.
|
||||
ScreenIntRect mCompositionBounds;
|
||||
ParentLayerIntRect mCompositionBounds;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// The following metrics are all in CSS pixels. They are not in any uniform
|
||||
@ -282,6 +311,17 @@ public:
|
||||
// diverge. This information is initialized in Gecko but updated in the APZC.
|
||||
CSSToScreenScale mZoom;
|
||||
|
||||
// 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.
|
||||
ScreenToParentLayerScale mTransformScale;
|
||||
|
||||
// The conversion factor between CSS pixels and device pixels for this frame.
|
||||
// This can vary based on a variety of things, such as reflowing-zoom. The
|
||||
// conversion factor for device pixels to layers pixels is just the
|
||||
|
@ -517,8 +517,8 @@ ClientLayerManager::GetBackendName(nsAString& aName)
|
||||
|
||||
bool
|
||||
ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
ScreenRect& aCompositionBounds,
|
||||
CSSToScreenScale& aZoom,
|
||||
ParentLayerRect& aCompositionBounds,
|
||||
CSSToParentLayerScale& aZoom,
|
||||
bool aDrawingCritical)
|
||||
{
|
||||
aZoom.scale = 1.0;
|
||||
|
@ -147,8 +147,8 @@ public:
|
||||
* true.
|
||||
*/
|
||||
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
ScreenRect& aCompositionBounds,
|
||||
CSSToScreenScale& aZoom,
|
||||
ParentLayerRect& aCompositionBounds,
|
||||
CSSToParentLayerScale& aZoom,
|
||||
bool aDrawingCritical);
|
||||
|
||||
bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "ClientTiledThebesLayer.h"
|
||||
#include "FrameMetrics.h" // for FrameMetrics
|
||||
#include "Units.h" // for ScreenIntRect, CSSPoint, etc
|
||||
#include "UnitTransforms.h" // for TransformTo
|
||||
#include "ClientLayerManager.h" // for ClientLayerManager, etc
|
||||
#include "gfx3DMatrix.h" // for gfx3DMatrix
|
||||
#include "gfxPlatform.h" // for gfxPlatform
|
||||
@ -52,11 +53,9 @@ ClientTiledThebesLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
}
|
||||
|
||||
static LayoutDeviceRect
|
||||
ApplyScreenToLayoutTransform(const gfx3DMatrix& aTransform, const ScreenRect& aScreenRect)
|
||||
ApplyParentLayerToLayoutTransform(const gfx3DMatrix& aTransform, const ParentLayerRect& aParentLayerRect)
|
||||
{
|
||||
gfxRect input(aScreenRect.x, aScreenRect.y, aScreenRect.width, aScreenRect.height);
|
||||
gfxRect output = aTransform.TransformBounds(input);
|
||||
return LayoutDeviceRect(output.x, output.y, output.width, output.height);
|
||||
return TransformTo<LayoutDevicePixel>(aTransform, aParentLayerRect);
|
||||
}
|
||||
|
||||
void
|
||||
@ -89,30 +88,32 @@ ClientTiledThebesLayer::BeginPaint()
|
||||
|
||||
const FrameMetrics& metrics = scrollParent->GetFrameMetrics();
|
||||
|
||||
// Calculate the transform required to convert screen space into transformed
|
||||
// layout device space.
|
||||
// Calculate the transform required to convert parent layer space into
|
||||
// transformed layout device space.
|
||||
gfx::Matrix4x4 effectiveTransform = GetEffectiveTransform();
|
||||
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
|
||||
if (parent->UseIntermediateSurface()) {
|
||||
effectiveTransform = effectiveTransform * parent->GetEffectiveTransform();
|
||||
}
|
||||
}
|
||||
gfx3DMatrix layoutToScreen;
|
||||
gfx::To3DMatrix(effectiveTransform, layoutToScreen);
|
||||
layoutToScreen.ScalePost(metrics.mCumulativeResolution.scale,
|
||||
metrics.mCumulativeResolution.scale,
|
||||
1.f);
|
||||
gfx3DMatrix layoutToParentLayer;
|
||||
gfx::To3DMatrix(effectiveTransform, layoutToParentLayer);
|
||||
layoutToParentLayer.ScalePost(metrics.GetParentResolution().scale,
|
||||
metrics.GetParentResolution().scale,
|
||||
1.f);
|
||||
|
||||
mPaintData.mTransformScreenToLayout = layoutToScreen.Inverse();
|
||||
mPaintData.mTransformParentLayerToLayout = layoutToParentLayer.Inverse();
|
||||
|
||||
// Compute the critical display port in layer space.
|
||||
mPaintData.mLayoutCriticalDisplayPort.SetEmpty();
|
||||
if (!metrics.mCriticalDisplayPort.IsEmpty()) {
|
||||
// Convert the display port to screen space first so that we can transform
|
||||
// it into layout device space.
|
||||
const ScreenRect& criticalDisplayPort = metrics.mCriticalDisplayPort * metrics.mZoom;
|
||||
const ParentLayerRect& criticalDisplayPort = metrics.mCriticalDisplayPort
|
||||
* metrics.mDevPixelsPerCSSPixel
|
||||
* metrics.GetParentResolution();
|
||||
LayoutDeviceRect transformedCriticalDisplayPort =
|
||||
ApplyScreenToLayoutTransform(mPaintData.mTransformScreenToLayout, criticalDisplayPort);
|
||||
ApplyParentLayerToLayoutTransform(mPaintData.mTransformParentLayerToLayout, criticalDisplayPort);
|
||||
mPaintData.mLayoutCriticalDisplayPort =
|
||||
LayoutDeviceIntRect::ToUntyped(RoundedOut(transformedCriticalDisplayPort));
|
||||
}
|
||||
@ -130,8 +131,8 @@ ClientTiledThebesLayer::BeginPaint()
|
||||
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
|
||||
mPaintData.mScrollOffset = metrics.mScrollOffset * metrics.mZoom;
|
||||
mPaintData.mCompositionBounds =
|
||||
ApplyScreenToLayoutTransform(mPaintData.mTransformScreenToLayout,
|
||||
ScreenRect(metrics.mCompositionBounds));
|
||||
ApplyParentLayerToLayoutTransform(mPaintData.mTransformParentLayerToLayout,
|
||||
ParentLayerRect(metrics.mCompositionBounds));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,8 +141,8 @@ SharedFrameMetricsHelper::UpdateFromCompositorFrameMetrics(
|
||||
ContainerLayer* aLayer,
|
||||
bool aHasPendingNewThebesContent,
|
||||
bool aLowPrecision,
|
||||
ScreenRect& aCompositionBounds,
|
||||
CSSToScreenScale& aZoom)
|
||||
ParentLayerRect& aCompositionBounds,
|
||||
CSSToParentLayerScale& aZoom)
|
||||
{
|
||||
MOZ_ASSERT(aLayer);
|
||||
|
||||
@ -162,8 +162,8 @@ SharedFrameMetricsHelper::UpdateFromCompositorFrameMetrics(
|
||||
return false;
|
||||
}
|
||||
|
||||
aCompositionBounds = ScreenRect(compositorMetrics.mCompositionBounds);
|
||||
aZoom = compositorMetrics.mZoom;
|
||||
aCompositionBounds = ParentLayerRect(compositorMetrics.mCompositionBounds);
|
||||
aZoom = compositorMetrics.GetZoomToParent();
|
||||
|
||||
// Reset the checkerboard risk flag when switching to low precision
|
||||
// rendering.
|
||||
@ -215,8 +215,8 @@ SharedFrameMetricsHelper::UpdateFromCompositorFrameMetrics(
|
||||
|
||||
void
|
||||
SharedFrameMetricsHelper::FindFallbackContentFrameMetrics(ContainerLayer* aLayer,
|
||||
ScreenRect& aCompositionBounds,
|
||||
CSSToScreenScale& aZoom) {
|
||||
ParentLayerRect& aCompositionBounds,
|
||||
CSSToParentLayerScale& aZoom) {
|
||||
if (!aLayer) {
|
||||
return;
|
||||
}
|
||||
@ -232,16 +232,16 @@ SharedFrameMetricsHelper::FindFallbackContentFrameMetrics(ContainerLayer* aLayer
|
||||
|
||||
MOZ_ASSERT(!contentMetrics->mCompositionBounds.IsEmpty());
|
||||
|
||||
aCompositionBounds = ScreenRect(contentMetrics->mCompositionBounds);
|
||||
aZoom = contentMetrics->mZoom;
|
||||
aCompositionBounds = ParentLayerRect(contentMetrics->mCompositionBounds);
|
||||
aZoom = contentMetrics->GetZoomToParent(); // TODO(botond): double-check this
|
||||
return;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedFrameMetricsHelper::AboutToCheckerboard(const FrameMetrics& aContentMetrics,
|
||||
const FrameMetrics& aCompositorMetrics)
|
||||
const FrameMetrics& aCompositorMetrics)
|
||||
{
|
||||
return !aContentMetrics.mDisplayPort.Contains(aCompositorMetrics.CalculateCompositedRectInCssPixels() - aCompositorMetrics.mScrollOffset);
|
||||
return !aContentMetrics.mDisplayPort.Contains(CSSRect(aCompositorMetrics.CalculateCompositedRectInCssPixels()) - aCompositorMetrics.mScrollOffset);
|
||||
}
|
||||
|
||||
ClientTiledLayerBuffer::ClientTiledLayerBuffer(ClientTiledThebesLayer* aThebesLayer,
|
||||
@ -843,8 +843,8 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
|
||||
}
|
||||
|
||||
static LayoutDeviceRect
|
||||
TransformCompositionBounds(const ScreenRect& aCompositionBounds,
|
||||
const CSSToScreenScale& aZoom,
|
||||
TransformCompositionBounds(const ParentLayerRect& aCompositionBounds,
|
||||
const CSSToParentLayerScale& aZoom,
|
||||
const ScreenPoint& aScrollOffset,
|
||||
const CSSToScreenScale& aResolution,
|
||||
const gfx3DMatrix& aTransformScreenToLayout)
|
||||
@ -895,8 +895,8 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval
|
||||
// Find out the current view transform to determine which tiles to draw
|
||||
// first, and see if we should just abort this paint. Aborting is usually
|
||||
// caused by there being an incoming, more relevant paint.
|
||||
ScreenRect compositionBounds;
|
||||
CSSToScreenScale zoom;
|
||||
ParentLayerRect compositionBounds;
|
||||
CSSToParentLayerScale zoom;
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
bool abortPaint = mManager->ProgressiveUpdateCallback(!staleRegion.Contains(aInvalidRegion),
|
||||
compositionBounds, zoom,
|
||||
@ -929,7 +929,7 @@ ClientTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& aInval
|
||||
// Transform the screen coordinates into transformed layout device coordinates.
|
||||
LayoutDeviceRect transformedCompositionBounds =
|
||||
TransformCompositionBounds(compositionBounds, zoom, aPaintData->mScrollOffset,
|
||||
aPaintData->mResolution, aPaintData->mTransformScreenToLayout);
|
||||
aPaintData->mResolution, aPaintData->mTransformParentLayerToLayout);
|
||||
|
||||
// Paint tiles that have stale content or that intersected with the screen
|
||||
// at the time of issuing the draw command in a single transaction first.
|
||||
|
@ -243,10 +243,10 @@ struct BasicTiledLayerPaintData {
|
||||
ScreenPoint mLastScrollOffset;
|
||||
|
||||
/*
|
||||
* The transform matrix to go from Screen units to transformed LayoutDevice
|
||||
* units.
|
||||
* The transform matrix to go from ParentLayer units to transformed
|
||||
* LayoutDevice units.
|
||||
*/
|
||||
gfx3DMatrix mTransformScreenToLayout;
|
||||
gfx3DMatrix mTransformParentLayerToLayout;
|
||||
|
||||
/*
|
||||
* The critical displayport of the content from the nearest ancestor layer
|
||||
@ -307,8 +307,8 @@ public:
|
||||
bool UpdateFromCompositorFrameMetrics(ContainerLayer* aLayer,
|
||||
bool aHasPendingNewThebesContent,
|
||||
bool aLowPrecision,
|
||||
ScreenRect& aCompositionBounds,
|
||||
CSSToScreenScale& aZoom);
|
||||
ParentLayerRect& aCompositionBounds,
|
||||
CSSToParentLayerScale& aZoom);
|
||||
|
||||
/**
|
||||
* When a shared FrameMetrics can not be found for a given layer,
|
||||
@ -316,8 +316,8 @@ public:
|
||||
* by traversing up the layer tree.
|
||||
*/
|
||||
void FindFallbackContentFrameMetrics(ContainerLayer* aLayer,
|
||||
ScreenRect& aCompositionBounds,
|
||||
CSSToScreenScale& aZoom);
|
||||
ParentLayerRect& aCompositionBounds,
|
||||
CSSToParentLayerScale& aZoom);
|
||||
/**
|
||||
* Determines if the compositor's upcoming composition bounds has fallen
|
||||
* outside of the contents display port. If it has then the compositor
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "nsDebug.h" // for NS_WARNING
|
||||
#include "nsPoint.h" // for nsIntPoint
|
||||
#include "nsThreadUtils.h" // for NS_IsMainThread
|
||||
#include "mozilla/gfx/Logging.h" // for gfx::TreeLog
|
||||
#include "UnitTransforms.h" // for ViewAs
|
||||
|
||||
#include <algorithm> // for std::stable_sort
|
||||
|
||||
@ -155,7 +157,8 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
|
||||
AsyncPanZoomController* apzc = nullptr;
|
||||
mApzcTreeLog << aLayer->Name() << '\t';
|
||||
if (container) {
|
||||
if (container->GetFrameMetrics().IsScrollable()) {
|
||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||
if (metrics.IsScrollable()) {
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(aLayersId);
|
||||
if (state && state->mController.get()) {
|
||||
// If we get here, aLayer is a scrollable container layer and somebody
|
||||
@ -168,7 +171,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
|
||||
// be possible because of DLBI heuristics) then we don't want to keep using
|
||||
// the same old APZC for the new content. Null it out so we run through the
|
||||
// code to find another one or create one.
|
||||
ScrollableLayerGuid guid(aLayersId, container->GetFrameMetrics());
|
||||
ScrollableLayerGuid guid(aLayersId, metrics);
|
||||
if (apzc && !apzc->Matches(guid)) {
|
||||
apzc = nullptr;
|
||||
}
|
||||
@ -210,19 +213,22 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
|
||||
}
|
||||
APZC_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, container->GetFrameMetrics().mScrollId);
|
||||
|
||||
apzc->NotifyLayersUpdated(container->GetFrameMetrics(),
|
||||
apzc->NotifyLayersUpdated(metrics,
|
||||
aIsFirstPaint && (aLayersId == aFirstPaintLayersId));
|
||||
|
||||
// Use the composition bounds as the hit test region.
|
||||
// Optionally, the GeckoContentController can provide a touch-sensitive
|
||||
// region that constrains all frames associated with the controller.
|
||||
// In this case we intersect the composition bounds with that region.
|
||||
ScreenRect visible(container->GetFrameMetrics().mCompositionBounds);
|
||||
ParentLayerRect visible(metrics.mCompositionBounds);
|
||||
CSSRect touchSensitiveRegion;
|
||||
if (state->mController->GetTouchSensitiveRegion(&touchSensitiveRegion)) {
|
||||
// Note: we assume here that touchSensitiveRegion is in the CSS pixels
|
||||
// of our parent layer, which makes this coordinate conversion
|
||||
// correct.
|
||||
visible = visible.Intersect(touchSensitiveRegion
|
||||
* container->GetFrameMetrics().LayersPixelsPerCSSPixel()
|
||||
* LayerToScreenScale(1.0));
|
||||
* metrics.mDevPixelsPerCSSPixel
|
||||
* metrics.GetParentResolution());
|
||||
}
|
||||
gfx3DMatrix transform;
|
||||
gfx::To3DMatrix(aLayer->GetTransform(), transform);
|
||||
@ -869,25 +875,21 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a
|
||||
// use standard matrix notation where the leftmost matrix in a multiplication is applied first.
|
||||
|
||||
// ancestorUntransform takes points from aApzc's parent APZC's layer coordinates
|
||||
// to aApzc's screen coordinates.
|
||||
// to aApzc's parent layer's layer coordinates.
|
||||
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L,
|
||||
// and RC.Inverse() * QC.Inverse() at recursion level for P.
|
||||
gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse();
|
||||
|
||||
// hitTestTransform takes points from aApzc's parent APZC's layer coordinates to
|
||||
// the hit test space (which is aApzc's transient coordinates).
|
||||
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse() at L,
|
||||
// and RC.Inverse() * QC.Inverse() * PC.Inverse() * PN.Inverse() at P.
|
||||
gfx3DMatrix hitTestTransform = ancestorUntransform
|
||||
* aApzc->GetCSSTransform().Inverse()
|
||||
* aApzc->GetNontransientAsyncTransform().Inverse();
|
||||
gfxPoint hitTestPointForThisLayer = hitTestTransform.ProjectPoint(aHitTestPoint);
|
||||
// Hit testing for this layer takes place in our parent layer coordinates,
|
||||
// since the composition bounds (used to initialize the visible rect against
|
||||
// which we hit test are in those coordinates).
|
||||
gfxPoint hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint);
|
||||
APZC_LOG("Untransformed %f %f to transient coordinates %f %f for hit-testing APZC %p\n",
|
||||
aHitTestPoint.x, aHitTestPoint.y,
|
||||
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
|
||||
|
||||
// childUntransform takes points from aApzc's parent APZC's layer coordinates
|
||||
// to aApzc's layer coordinates (which are aApzc's children's screen coordinates).
|
||||
// to aApzc's layer coordinates (which are aApzc's children's ParentLayer coordinates).
|
||||
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LA.Inverse() at L
|
||||
// and RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() at P.
|
||||
gfx3DMatrix childUntransform = ancestorUntransform
|
||||
@ -906,7 +908,7 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a
|
||||
return match;
|
||||
}
|
||||
}
|
||||
if (aApzc->VisibleRegionContains(ScreenPoint(hitTestPointForThisLayer.x, hitTestPointForThisLayer.y))) {
|
||||
if (aApzc->VisibleRegionContains(ViewAs<ParentLayerPixel>(hitTestPointForThisLayer))) {
|
||||
APZC_LOG("Successfully matched untransformed point %f %f to visible region for APZC %p\n",
|
||||
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
|
||||
return aApzc;
|
||||
|
@ -390,7 +390,7 @@ ContainerRender(ContainerT* aContainer,
|
||||
|
||||
if (aContainer->GetFrameMetrics().IsScrollable()) {
|
||||
const FrameMetrics& frame = aContainer->GetFrameMetrics();
|
||||
LayerRect layerBounds = ScreenRect(frame.mCompositionBounds) * ScreenToLayerScale(1.0);
|
||||
LayerRect layerBounds = ParentLayerRect(frame.mCompositionBounds) * ParentLayerToLayerScale(1.0);
|
||||
gfx::Rect rect(layerBounds.x, layerBounds.y, layerBounds.width, layerBounds.height);
|
||||
gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
|
||||
aManager->GetCompositor()->DrawDiagnostics(DIAGNOSTIC_CONTAINER,
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "InputData.h" // for MultiTouchInput, etc
|
||||
#include "LayerTransactionParent.h" // for LayerTransactionParent
|
||||
#include "Units.h" // for CSSRect, CSSPoint, etc
|
||||
#include "UnitTransforms.h" // for TransformTo
|
||||
#include "base/message_loop.h" // for MessageLoop
|
||||
#include "base/task.h" // for NewRunnableMethod, etc
|
||||
#include "base/tracked.h" // for FROM_HERE
|
||||
@ -44,6 +45,7 @@
|
||||
#include "mozilla/layers/TaskThrottler.h" // for TaskThrottler
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
#include "mozilla/unused.h" // for unused
|
||||
#include "mozilla/FloatingPoint.h" // for FuzzyEqualsMultiplicative
|
||||
#include "nsAlgorithm.h" // for clamped
|
||||
#include "nsAutoPtr.h" // for nsRefPtr
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
@ -797,7 +799,7 @@ nsEventStatus AsyncPanZoomController::OnScaleBegin(const PinchGestureInput& aEve
|
||||
}
|
||||
|
||||
SetState(PINCHING);
|
||||
mLastZoomFocus = aEvent.mFocusPoint - mFrameMetrics.mCompositionBounds.TopLeft();
|
||||
mLastZoomFocus = ToParentLayerCoords(aEvent.mFocusPoint) - mFrameMetrics.mCompositionBounds.TopLeft();
|
||||
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
@ -819,8 +821,8 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
|
||||
{
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
|
||||
CSSToScreenScale userZoom = mFrameMetrics.mZoom;
|
||||
ScreenPoint focusPoint = aEvent.mFocusPoint - mFrameMetrics.mCompositionBounds.TopLeft();
|
||||
CSSToParentLayerScale userZoom = mFrameMetrics.GetZoomToParent();
|
||||
ParentLayerPoint focusPoint = ToParentLayerCoords(aEvent.mFocusPoint) - mFrameMetrics.mCompositionBounds.TopLeft();
|
||||
CSSPoint cssFocusPoint = focusPoint / userZoom;
|
||||
|
||||
CSSPoint focusChange = (mLastZoomFocus - focusPoint) / userZoom;
|
||||
@ -839,8 +841,8 @@ nsEventStatus AsyncPanZoomController::OnScale(const PinchGestureInput& aEvent) {
|
||||
// either axis such that we don't overscroll the boundaries when zooming.
|
||||
CSSPoint neededDisplacement;
|
||||
|
||||
CSSToScreenScale realMinZoom = mZoomConstraints.mMinZoom;
|
||||
CSSToScreenScale realMaxZoom = mZoomConstraints.mMaxZoom;
|
||||
CSSToParentLayerScale realMinZoom = mZoomConstraints.mMinZoom * mFrameMetrics.mTransformScale;
|
||||
CSSToParentLayerScale realMaxZoom = mZoomConstraints.mMaxZoom * mFrameMetrics.mTransformScale;
|
||||
realMinZoom.scale = std::max(realMinZoom.scale,
|
||||
mFrameMetrics.mCompositionBounds.width / mFrameMetrics.mScrollableRect.width);
|
||||
realMinZoom.scale = std::max(realMinZoom.scale,
|
||||
@ -1345,7 +1347,7 @@ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||
const ScreenPoint& aVelocity,
|
||||
double aEstimatedPaintDuration)
|
||||
{
|
||||
CSSRect compositionBounds = aFrameMetrics.CalculateCompositedRectInCssPixels();
|
||||
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
|
||||
CSSPoint velocity = aVelocity / aFrameMetrics.mZoom;
|
||||
CSSPoint scrollOffset = aFrameMetrics.mScrollOffset;
|
||||
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
|
||||
@ -1528,7 +1530,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
|
||||
|
||||
LogRendertraceRect(GetGuid(), "viewport", "red",
|
||||
CSSRect(mFrameMetrics.mScrollOffset,
|
||||
ScreenSize(mFrameMetrics.mCompositionBounds.Size()) / mFrameMetrics.mZoom));
|
||||
ParentLayerSize(mFrameMetrics.mCompositionBounds.Size()) / mFrameMetrics.GetZoomToParent()));
|
||||
|
||||
mCurrentAsyncScrollOffset = mFrameMetrics.mScrollOffset;
|
||||
}
|
||||
@ -1578,7 +1580,7 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() {
|
||||
// within rendered content.
|
||||
if (!gAllowCheckerboarding &&
|
||||
!mLastContentPaintMetrics.mDisplayPort.IsEmpty()) {
|
||||
CSSRect compositedRect = mLastContentPaintMetrics.CalculateCompositedRectInCssPixels();
|
||||
CSSRect compositedRect(mLastContentPaintMetrics.CalculateCompositedRectInCssPixels());
|
||||
CSSPoint maxScrollOffset = lastPaintScrollOffset +
|
||||
CSSPoint(mLastContentPaintMetrics.mDisplayPort.XMost() - compositedRect.width,
|
||||
mLastContentPaintMetrics.mDisplayPort.YMost() - compositedRect.height);
|
||||
@ -1620,6 +1622,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
|
||||
mLastContentPaintMetrics = aLayerMetrics;
|
||||
UpdateTransformScale();
|
||||
|
||||
bool isDefault = mFrameMetrics.IsDefault();
|
||||
mFrameMetrics.mMayHaveTouchListeners = aLayerMetrics.mMayHaveTouchListeners;
|
||||
@ -1729,27 +1732,27 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
|
||||
{
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
|
||||
ScreenIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
|
||||
ParentLayerIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
|
||||
CSSRect cssPageRect = mFrameMetrics.mScrollableRect;
|
||||
CSSPoint scrollOffset = mFrameMetrics.mScrollOffset;
|
||||
CSSToScreenScale currentZoom = mFrameMetrics.mZoom;
|
||||
CSSToScreenScale targetZoom;
|
||||
CSSToParentLayerScale currentZoom = mFrameMetrics.GetZoomToParent();
|
||||
CSSToParentLayerScale targetZoom;
|
||||
|
||||
// The minimum zoom to prevent over-zoom-out.
|
||||
// If the zoom factor is lower than this (i.e. we are zoomed more into the page),
|
||||
// then the CSS content rect, in layers pixels, will be smaller than the
|
||||
// composition bounds. If this happens, we can't fill the target composited
|
||||
// area with this frame.
|
||||
CSSToScreenScale localMinZoom(std::max(mZoomConstraints.mMinZoom.scale,
|
||||
std::max(compositionBounds.width / cssPageRect.width,
|
||||
compositionBounds.height / cssPageRect.height)));
|
||||
CSSToScreenScale localMaxZoom = mZoomConstraints.mMaxZoom;
|
||||
CSSToParentLayerScale localMinZoom(std::max((mZoomConstraints.mMinZoom * mFrameMetrics.mTransformScale).scale,
|
||||
std::max(compositionBounds.width / cssPageRect.width,
|
||||
compositionBounds.height / cssPageRect.height)));
|
||||
CSSToParentLayerScale localMaxZoom = mZoomConstraints.mMaxZoom * mFrameMetrics.mTransformScale;
|
||||
|
||||
if (!aRect.IsEmpty()) {
|
||||
// Intersect the zoom-to-rect to the CSS rect to make sure it fits.
|
||||
aRect = aRect.Intersect(cssPageRect);
|
||||
targetZoom = CSSToScreenScale(std::min(compositionBounds.width / aRect.width,
|
||||
compositionBounds.height / aRect.height));
|
||||
targetZoom = CSSToParentLayerScale(std::min(compositionBounds.width / aRect.width,
|
||||
compositionBounds.height / aRect.height));
|
||||
}
|
||||
// 1. If the rect is empty, request received from browserElementScrolling.js
|
||||
// 2. currentZoom is equal to mZoomConstraints.mMaxZoom and user still double-tapping it
|
||||
@ -1758,27 +1761,27 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
|
||||
if (aRect.IsEmpty() ||
|
||||
(currentZoom == localMaxZoom && targetZoom >= localMaxZoom) ||
|
||||
(currentZoom == localMinZoom && targetZoom <= localMinZoom)) {
|
||||
CSSRect compositedRect = mFrameMetrics.CalculateCompositedRectInCssPixels();
|
||||
CSSRect compositedRect = CSSRect(mFrameMetrics.CalculateCompositedRectInCssPixels());
|
||||
float y = scrollOffset.y;
|
||||
float newHeight =
|
||||
cssPageRect.width * (compositedRect.height / compositedRect.width);
|
||||
float dh = compositedRect.height - newHeight;
|
||||
|
||||
aRect = CSSRect(0.0f,
|
||||
y + dh/2,
|
||||
cssPageRect.width,
|
||||
newHeight);
|
||||
y + dh/2,
|
||||
cssPageRect.width,
|
||||
newHeight);
|
||||
aRect = aRect.Intersect(cssPageRect);
|
||||
targetZoom = CSSToScreenScale(std::min(compositionBounds.width / aRect.width,
|
||||
compositionBounds.height / aRect.height));
|
||||
targetZoom = CSSToParentLayerScale(std::min(compositionBounds.width / aRect.width,
|
||||
compositionBounds.height / aRect.height));
|
||||
}
|
||||
|
||||
targetZoom.scale = clamped(targetZoom.scale, localMinZoom.scale, localMaxZoom.scale);
|
||||
FrameMetrics endZoomToMetrics = mFrameMetrics;
|
||||
endZoomToMetrics.mZoom = targetZoom;
|
||||
endZoomToMetrics.mZoom = targetZoom / mFrameMetrics.mTransformScale;
|
||||
|
||||
// Adjust the zoomToRect to a sensible position to prevent overscrolling.
|
||||
CSSRect rectAfterZoom = endZoomToMetrics.CalculateCompositedRectInCssPixels();
|
||||
CSSRect rectAfterZoom = CSSRect(endZoomToMetrics.CalculateCompositedRectInCssPixels());
|
||||
|
||||
// If either of these conditions are met, the page will be
|
||||
// overscrolled after zoomed
|
||||
@ -1988,7 +1991,7 @@ void AsyncPanZoomController::SendAsyncScrollEvent() {
|
||||
|
||||
isRoot = mFrameMetrics.mIsRoot;
|
||||
scrollableSize = mFrameMetrics.mScrollableRect.Size();
|
||||
contentRect = mFrameMetrics.CalculateCompositedRectInCssPixels();
|
||||
contentRect = CSSRect(mFrameMetrics.CalculateCompositedRectInCssPixels());
|
||||
contentRect.MoveTo(mCurrentAsyncScrollOffset);
|
||||
}
|
||||
|
||||
@ -2071,5 +2074,19 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() {
|
||||
}
|
||||
}
|
||||
|
||||
ParentLayerPoint AsyncPanZoomController::ToParentLayerCoords(const ScreenPoint& aPoint)
|
||||
{
|
||||
return TransformTo<ParentLayerPixel>(GetNontransientAsyncTransform() * GetCSSTransform(), aPoint);
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::UpdateTransformScale()
|
||||
{
|
||||
gfx3DMatrix nontransientTransforms = GetNontransientAsyncTransform() * GetCSSTransform();
|
||||
if (!FuzzyEqualsMultiplicative(nontransientTransforms.GetXScale(), nontransientTransforms.GetYScale())) {
|
||||
NS_WARNING("The x- and y-scales of the nontransient transforms should be equal");
|
||||
}
|
||||
mFrameMetrics.mTransformScale.scale = nontransientTransforms.GetXScale();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -615,6 +615,16 @@ private:
|
||||
|
||||
static AxisLockMode GetAxisLockMode();
|
||||
|
||||
// Convert a point from local screen coordinates to parent layer coordinates.
|
||||
// This is a common operation as inputs from the tree manager are in screen
|
||||
// coordinates but the composition bounds is in parent layer coordinates.
|
||||
ParentLayerPoint ToParentLayerCoords(const ScreenPoint& aPoint);
|
||||
|
||||
// Update mFrameMetrics.mTransformScale. This should be called whenever
|
||||
// our CSS transform or the non-transient part of our async transform
|
||||
// changes, as it corresponds to the scale portion of those transforms.
|
||||
void UpdateTransformScale();
|
||||
|
||||
uint64_t mLayersId;
|
||||
nsRefPtr<CompositorParent> mCompositorParent;
|
||||
PCompositorParent* mCrossProcessCompositorParent;
|
||||
@ -690,7 +700,7 @@ private:
|
||||
|
||||
// Stores the previous focus point if there is a pinch gesture happening. Used
|
||||
// to allow panning by moving multiple fingers (thus moving the focus point).
|
||||
ScreenPoint mLastZoomFocus;
|
||||
ParentLayerPoint mLastZoomFocus;
|
||||
|
||||
// Stores the state of panning and zooming this frame. This is protected by
|
||||
// |mMonitor|; that is, it should be held whenever this is updated.
|
||||
@ -790,11 +800,12 @@ private:
|
||||
* hit-testing to see which APZC instance should handle touch events.
|
||||
*/
|
||||
public:
|
||||
void SetLayerHitTestData(const ScreenRect& aRect, const gfx3DMatrix& aTransformToLayer,
|
||||
void SetLayerHitTestData(const ParentLayerRect& aRect, const gfx3DMatrix& aTransformToLayer,
|
||||
const gfx3DMatrix& aTransformForLayer) {
|
||||
mVisibleRect = aRect;
|
||||
mAncestorTransform = aTransformToLayer;
|
||||
mCSSTransform = aTransformForLayer;
|
||||
UpdateTransformScale();
|
||||
}
|
||||
|
||||
gfx3DMatrix GetAncestorTransform() const {
|
||||
@ -805,7 +816,7 @@ public:
|
||||
return mCSSTransform;
|
||||
}
|
||||
|
||||
bool VisibleRegionContains(const ScreenPoint& aPoint) const {
|
||||
bool VisibleRegionContains(const ParentLayerPoint& aPoint) const {
|
||||
return mVisibleRect.Contains(aPoint);
|
||||
}
|
||||
|
||||
@ -816,7 +827,7 @@ private:
|
||||
/* This is the visible region of the layer that this APZC corresponds to, in
|
||||
* that layer's screen pixels (the same coordinate system in which this APZC
|
||||
* receives events in ReceiveInputEvent()). */
|
||||
ScreenRect mVisibleRect;
|
||||
ParentLayerRect mVisibleRect;
|
||||
/* This is the cumulative CSS transform for all the layers between the parent
|
||||
* APZC and this one (not inclusive) */
|
||||
gfx3DMatrix mAncestorTransform;
|
||||
|
@ -269,7 +269,7 @@ float Axis::GetOrigin() {
|
||||
|
||||
float Axis::GetCompositionLength() {
|
||||
const FrameMetrics& metrics = mAsyncPanZoomController->GetFrameMetrics();
|
||||
CSSRect cssCompositedRect = metrics.CalculateCompositedRectInCssPixels();
|
||||
CSSRect cssCompositedRect = CSSRect(metrics.CalculateCompositedRectInCssPixels());
|
||||
return GetRectLength(cssCompositedRect);
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ float Axis::GetPageLength() {
|
||||
bool Axis::ScaleWillOverscrollBothSides(float aScale) {
|
||||
const FrameMetrics& metrics = mAsyncPanZoomController->GetFrameMetrics();
|
||||
|
||||
CSSToScreenScale scale(metrics.mZoom.scale * aScale);
|
||||
CSSToParentLayerScale scale(metrics.GetZoomToParent().scale * aScale);
|
||||
CSSRect cssCompositionBounds = metrics.mCompositionBounds / scale;
|
||||
|
||||
return GetRectLength(metrics.mScrollableRect) < GetRectLength(cssCompositionBounds);
|
||||
|
@ -156,7 +156,7 @@ FrameMetrics TestFrameMetrics() {
|
||||
FrameMetrics fm;
|
||||
|
||||
fm.mDisplayPort = CSSRect(0, 0, 10, 10);
|
||||
fm.mCompositionBounds = ScreenIntRect(0, 0, 10, 10);
|
||||
fm.mCompositionBounds = ParentLayerIntRect(0, 0, 10, 10);
|
||||
fm.mCriticalDisplayPort = CSSRect(0, 0, 10, 10);
|
||||
fm.mScrollableRect = CSSRect(0, 0, 100, 100);
|
||||
fm.mViewport = CSSRect(0, 0, 10, 10);
|
||||
@ -347,7 +347,7 @@ TEST(AsyncPanZoomController, Pinch) {
|
||||
|
||||
FrameMetrics fm;
|
||||
fm.mViewport = CSSRect(0, 0, 980, 480);
|
||||
fm.mCompositionBounds = ScreenIntRect(200, 200, 100, 200);
|
||||
fm.mCompositionBounds = ParentLayerIntRect(200, 200, 100, 200);
|
||||
fm.mScrollableRect = CSSRect(0, 0, 980, 1000);
|
||||
fm.mScrollOffset = CSSPoint(300, 300);
|
||||
fm.mZoom = CSSToScreenScale(2.0);
|
||||
@ -390,7 +390,7 @@ TEST(AsyncPanZoomController, PinchWithTouchActionNone) {
|
||||
|
||||
FrameMetrics fm;
|
||||
fm.mViewport = CSSRect(0, 0, 980, 480);
|
||||
fm.mCompositionBounds = ScreenIntRect(200, 200, 100, 200);
|
||||
fm.mCompositionBounds = ParentLayerIntRect(200, 200, 100, 200);
|
||||
fm.mScrollableRect = CSSRect(0, 0, 980, 1000);
|
||||
fm.mScrollOffset = CSSPoint(300, 300);
|
||||
fm.mZoom = CSSToScreenScale(2.0);
|
||||
@ -424,7 +424,7 @@ TEST(AsyncPanZoomController, Overzoom) {
|
||||
|
||||
FrameMetrics fm;
|
||||
fm.mViewport = CSSRect(0, 0, 100, 100);
|
||||
fm.mCompositionBounds = ScreenIntRect(0, 0, 100, 100);
|
||||
fm.mCompositionBounds = ParentLayerIntRect(0, 0, 100, 100);
|
||||
fm.mScrollableRect = CSSRect(0, 0, 125, 150);
|
||||
fm.mScrollOffset = CSSPoint(10, 0);
|
||||
fm.mZoom = CSSToScreenScale(1.0);
|
||||
@ -502,7 +502,7 @@ TEST(AsyncPanZoomController, ComplexTransform) {
|
||||
nsRefPtr<Layer> root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, lm, layers);
|
||||
|
||||
FrameMetrics metrics;
|
||||
metrics.mCompositionBounds = ScreenIntRect(0, 0, 24, 24);
|
||||
metrics.mCompositionBounds = ParentLayerIntRect(0, 0, 24, 24);
|
||||
metrics.mDisplayPort = CSSRect(-1, -1, 6, 6);
|
||||
metrics.mViewport = CSSRect(0, 0, 4, 4);
|
||||
metrics.mScrollOffset = CSSPoint(10, 10);
|
||||
@ -929,8 +929,8 @@ SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId,
|
||||
FrameMetrics metrics;
|
||||
metrics.mScrollId = aScrollId;
|
||||
nsIntRect layerBound = aLayer->GetVisibleRegion().GetBounds();
|
||||
metrics.mCompositionBounds = ScreenIntRect(layerBound.x, layerBound.y,
|
||||
layerBound.width, layerBound.height);
|
||||
metrics.mCompositionBounds = ParentLayerIntRect(layerBound.x, layerBound.y,
|
||||
layerBound.width, layerBound.height);
|
||||
metrics.mScrollableRect = aScrollableRect;
|
||||
metrics.mScrollOffset = CSSPoint(0, 0);
|
||||
container->SetFrameMetrics(metrics);
|
||||
|
77
layout/base/UnitTransforms.h
Normal file
77
layout/base/UnitTransforms.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZ_UNIT_TRANSFORMS_H_
|
||||
#define MOZ_UNIT_TRANSFORMS_H_
|
||||
|
||||
#include "Units.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Convenience functions for converting an entity from one strongly-typed
|
||||
// coordinate system to another without changing the values it stores (this
|
||||
// can be thought of as a cast).
|
||||
// To use these functions, you must provide a justification for each use!
|
||||
// Feel free to add more justifications to PixelCastJustification, along with
|
||||
// a comment that explains under what circumstances it is appropriate to use.
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(PixelCastJustification, uint8_t)
|
||||
// For the root layer, Screen Pixel = Parent Layer Pixel.
|
||||
ScreenToParentLayerForRoot
|
||||
MOZ_END_ENUM_CLASS(PixelCastJustification)
|
||||
|
||||
template <class TargetUnits, class SourceUnits>
|
||||
gfx::SizeTyped<TargetUnits> ViewAs(const gfx::SizeTyped<SourceUnits>& aSize, PixelCastJustification) {
|
||||
return gfx::SizeTyped<TargetUnits>(aSize.width, aSize.height);
|
||||
}
|
||||
template <class TargetUnits, class SourceUnits>
|
||||
gfx::IntSizeTyped<TargetUnits> ViewAs(const gfx::IntSizeTyped<SourceUnits>& aSize, PixelCastJustification) {
|
||||
return gfx::IntSizeTyped<TargetUnits>(aSize.width, aSize.height);
|
||||
}
|
||||
|
||||
// Convenience functions for casting untyped entities to typed entities.
|
||||
// Using these functions does not require a justification, but once we convert
|
||||
// all code to use strongly typed units they should not be needed any longer.
|
||||
template <class TargetUnits>
|
||||
gfx::PointTyped<TargetUnits> ViewAs(const gfxPoint& aPoint) {
|
||||
return gfx::PointTyped<TargetUnits>(aPoint.x, aPoint.y);
|
||||
}
|
||||
template <class TargetUnits>
|
||||
gfx::RectTyped<TargetUnits> ViewAs(const gfxRect& aRect) {
|
||||
return gfx::RectTyped<TargetUnits>(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
}
|
||||
|
||||
// Convenience functions for casting typed entities to untyped entities.
|
||||
// Using these functions does not require a justification, but once we convert
|
||||
// all code to use strongly typed units they should not be needed any longer.
|
||||
template <class SourceUnits>
|
||||
gfxPoint ViewAsUntyped(const gfx::PointTyped<SourceUnits>& aPoint) {
|
||||
return gfxPoint(aPoint.x, aPoint.y);
|
||||
}
|
||||
template <class SourceUnits>
|
||||
gfxRect ViewAsUntyped(const gfx::RectTyped<SourceUnits>& aRect) {
|
||||
return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
}
|
||||
|
||||
// Convenience functions for transforming an entity from one strongly-typed
|
||||
// coordinate system to another using the provided transformation matrix.
|
||||
template <typename TargetUnits, typename SourceUnits>
|
||||
static gfx::PointTyped<TargetUnits> TransformTo(const gfx3DMatrix& aTransform,
|
||||
const gfx::PointTyped<SourceUnits>& aPoint)
|
||||
{
|
||||
return ViewAs<TargetUnits>(aTransform.Transform(ViewAsUntyped(aPoint)));
|
||||
}
|
||||
template <typename TargetUnits, typename SourceUnits>
|
||||
static gfx::RectTyped<TargetUnits> TransformTo(const gfx3DMatrix& aTransform,
|
||||
const gfx::RectTyped<SourceUnits>& aRect)
|
||||
{
|
||||
return ViewAs<TargetUnits>(aTransform.TransformBounds(ViewAsUntyped(aRect)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -277,6 +277,6 @@ gfx::MarginTyped<dst> operator/(const gfx::MarginTyped<src>& aMargin, const gfx:
|
||||
aMargin.left / aScale.scale);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -56,6 +56,7 @@ EXPORTS += [
|
||||
'ScrollbarStyles.h',
|
||||
'StackArena.h',
|
||||
'Units.h',
|
||||
'UnitTransforms.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
|
@ -625,15 +625,6 @@ static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
|
||||
}
|
||||
}
|
||||
|
||||
static void AdjustForScrollBars(ScreenIntRect& aToAdjust, nsIScrollableFrame* aScrollableFrame) {
|
||||
if (aScrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
|
||||
nsMargin sizes = aScrollableFrame->GetActualScrollbarSizes();
|
||||
// Scrollbars are not subject to scaling, so CSS pixels = screen pixels for them.
|
||||
ScreenIntMargin boundMargins = RoundedToInt(CSSMargin::FromAppUnits(sizes) * CSSToScreenScale(1.0f));
|
||||
aToAdjust.Deflate(boundMargins);
|
||||
}
|
||||
}
|
||||
|
||||
static bool gPrintApzcTree = false;
|
||||
|
||||
static bool GetApzcTreePrintPref() {
|
||||
@ -759,33 +750,41 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
nsRect compositionBounds(frameForCompositionBoundsCalculation->GetOffsetToCrossDoc(aReferenceFrame),
|
||||
frameForCompositionBoundsCalculation->GetSize());
|
||||
metrics.mCompositionBounds = RoundedToInt(LayoutDeviceRect::FromAppUnits(compositionBounds, auPerDevPixel)
|
||||
* metrics.mCumulativeResolution
|
||||
* layerToScreenScale);
|
||||
* metrics.GetParentResolution());
|
||||
|
||||
// For the root scroll frame of the root content document, clamp the
|
||||
// composition bounds to the widget bounds. This is necessary because, if
|
||||
// the page is zoomed in, the frame's size might be larger than the widget
|
||||
// bounds, but we don't want the composition bounds to be.
|
||||
bool useWidgetBounds = false;
|
||||
// For the root scroll frame of the root content document, the above calculation
|
||||
// will yield the size of the viewport frame as the composition bounds, which
|
||||
// doesn't actually correspond to what is visible when
|
||||
// nsIDOMWindowUtils::setCSSViewport has been called to modify the visible area of
|
||||
// the prescontext that the viewport frame is reflowed into. In that case if our
|
||||
// document has a widget then the widget's bounds will correspond to what is
|
||||
// visible. If we don't have a widget the root view's bounds correspond to what
|
||||
// would be visible because they don't get modified by setCSSViewport.
|
||||
bool isRootContentDocRootScrollFrame = presContext->IsRootContentDocument()
|
||||
&& aScrollFrame == presShell->GetRootScrollFrame();
|
||||
if (isRootContentDocRootScrollFrame) {
|
||||
if (nsIWidget* widget = aForFrame->GetNearestWidget()) {
|
||||
nsIntRect bounds;
|
||||
widget->GetBounds(bounds);
|
||||
ScreenIntRect screenBounds = ScreenIntRect::FromUnknownRect(mozilla::gfx::IntRect(
|
||||
bounds.x, bounds.y, bounds.width, bounds.height));
|
||||
AdjustForScrollBars(screenBounds, scrollableFrame);
|
||||
metrics.mCompositionBounds = metrics.mCompositionBounds.ForceInside(screenBounds);
|
||||
useWidgetBounds = true;
|
||||
if (nsIFrame* rootFrame = presShell->GetRootFrame()) {
|
||||
if (nsView* view = rootFrame->GetView()) {
|
||||
nsIWidget* widget = view->GetWidget();
|
||||
if (widget) {
|
||||
nsIntRect bounds;
|
||||
widget->GetBounds(bounds);
|
||||
metrics.mCompositionBounds = ParentLayerIntRect::FromUnknownRect(mozilla::gfx::IntRect(
|
||||
bounds.x, bounds.y, bounds.width, bounds.height));
|
||||
} else {
|
||||
metrics.mCompositionBounds = RoundedToInt(LayoutDeviceRect::FromAppUnits(view->GetBounds(), auPerDevPixel)
|
||||
* metrics.GetParentResolution());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust composition bounds for the size of scroll bars.
|
||||
// If the widget bounds were used to clamp the composition bounds,
|
||||
// this adjustment was already made to the widget bounds.
|
||||
if (!useWidgetBounds) {
|
||||
AdjustForScrollBars(metrics.mCompositionBounds, scrollableFrame);
|
||||
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);
|
||||
}
|
||||
|
||||
if (GetApzcTreePrintPref()) {
|
||||
|
@ -1835,7 +1835,7 @@ AndroidBridge::IsContentDocumentDisplayed()
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidBridge::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, ScreenRect& aCompositionBounds, CSSToScreenScale& aZoom)
|
||||
AndroidBridge::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, ParentLayerRect& aCompositionBounds, CSSToParentLayerScale& aZoom)
|
||||
{
|
||||
GeckoLayerClient *client = mLayerClient;
|
||||
if (!client) {
|
||||
|
@ -202,7 +202,7 @@ public:
|
||||
void ContentDocumentChanged();
|
||||
bool IsContentDocumentDisplayed();
|
||||
|
||||
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, ScreenRect& aCompositionBounds, CSSToScreenScale& aZoom);
|
||||
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, ParentLayerRect& aCompositionBounds, CSSToParentLayerScale& aZoom);
|
||||
|
||||
void SetLayerClient(JNIEnv* env, jobject jobj);
|
||||
GeckoLayerClient* GetLayerClient() { return mLayerClient; }
|
||||
|
@ -91,7 +91,7 @@ MaybeAlignAndClampDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics,
|
||||
static void
|
||||
RecenterDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics)
|
||||
{
|
||||
CSSRect compositionBounds = aFrameMetrics.CalculateCompositedRectInCssPixels();
|
||||
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
|
||||
aFrameMetrics.mDisplayPort.x = (compositionBounds.width - aFrameMetrics.mDisplayPort.width) / 2;
|
||||
aFrameMetrics.mDisplayPort.y = (compositionBounds.height - aFrameMetrics.mDisplayPort.height) / 2;
|
||||
}
|
||||
@ -156,7 +156,7 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
|
||||
// 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.
|
||||
CSSSize scrollPort = aMetrics.CalculateCompositedRectInCssPixels().Size();
|
||||
CSSSize scrollPort = CSSSize(aMetrics.CalculateCompositedRectInCssPixels().Size());
|
||||
aUtils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height);
|
||||
|
||||
// Scroll the window to the desired spot
|
||||
@ -189,7 +189,7 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
|
||||
// Finally, we multiply by a ScreenToLayerScale of 1.0f because the goal here is to
|
||||
// take the async zoom calculated by the APZC and tell gecko about it (turning it into
|
||||
// a "sync" zoom) which will update the resolution at which the layer is painted.
|
||||
mozilla::layers::ParentLayerToLayerScale presShellResolution =
|
||||
ParentLayerToLayerScale presShellResolution =
|
||||
aMetrics.mZoom
|
||||
/ aMetrics.mDevPixelsPerCSSPixel
|
||||
/ aMetrics.GetParentResolution()
|
||||
|
Loading…
Reference in New Issue
Block a user