Bug 1271432 - Optimization to avoid recomputing the same Matrix over and over. r=tnikkel

MozReview-Commit-ID: 28lV5ZRswxu
This commit is contained in:
Kartikaya Gupta 2016-05-17 11:05:46 -04:00
Родитель 9fe9512858
Коммит 6637b49101
3 изменённых файлов: 50 добавлений и 17 удалений

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

@ -3281,30 +3281,35 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
containingPaintedLayerData->mMaybeHitRegion, rect);
containingPaintedLayerData->mMaybeHitRegion.SimplifyOutward(8);
}
Maybe<Matrix4x4> matrixCache;
nsLayoutUtils::TransformToAncestorAndCombineRegions(
data->mHitRegion,
mContainerReferenceFrame,
containingPaintedLayerData->mReferenceFrame,
&containingPaintedLayerData->mHitRegion,
&containingPaintedLayerData->mMaybeHitRegion);
&containingPaintedLayerData->mMaybeHitRegion,
&matrixCache);
nsLayoutUtils::TransformToAncestorAndCombineRegions(
data->mNoActionRegion,
mContainerReferenceFrame,
containingPaintedLayerData->mReferenceFrame,
&containingPaintedLayerData->mNoActionRegion,
&containingPaintedLayerData->mDispatchToContentHitRegion);
&containingPaintedLayerData->mDispatchToContentHitRegion,
&matrixCache);
nsLayoutUtils::TransformToAncestorAndCombineRegions(
data->mHorizontalPanRegion,
mContainerReferenceFrame,
containingPaintedLayerData->mReferenceFrame,
&containingPaintedLayerData->mHorizontalPanRegion,
&containingPaintedLayerData->mDispatchToContentHitRegion);
&containingPaintedLayerData->mDispatchToContentHitRegion,
&matrixCache);
nsLayoutUtils::TransformToAncestorAndCombineRegions(
data->mVerticalPanRegion,
mContainerReferenceFrame,
containingPaintedLayerData->mReferenceFrame,
&containingPaintedLayerData->mVerticalPanRegion,
&containingPaintedLayerData->mDispatchToContentHitRegion);
&containingPaintedLayerData->mDispatchToContentHitRegion,
&matrixCache);
} else {
EventRegions regions;

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

@ -2848,13 +2848,26 @@ static Rect
TransformGfxRectToAncestor(nsIFrame *aFrame,
const Rect &aRect,
const nsIFrame *aAncestor,
bool* aPreservesAxisAlignedRectangles = nullptr)
bool* aPreservesAxisAlignedRectangles = nullptr,
Maybe<Matrix4x4>* aMatrixCache = nullptr)
{
Matrix4x4 ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestor);
if (aPreservesAxisAlignedRectangles) {
Matrix matrix2d;
*aPreservesAxisAlignedRectangles =
ctm.Is2D(&matrix2d) && matrix2d.PreservesAxisAlignedRectangles();
Matrix4x4 ctm;
if (aMatrixCache && *aMatrixCache) {
// We are given a matrix to use, so use it
ctm = aMatrixCache->value();
} else {
// Else, compute it
ctm = nsLayoutUtils::GetTransformToAncestor(aFrame, aAncestor);
if (aMatrixCache) {
// and put it in the cache, if provided
*aMatrixCache = Some(ctm);
}
// If we computed it, also fill out the axis-alignment flag
if (aPreservesAxisAlignedRectangles) {
Matrix matrix2d;
*aPreservesAxisAlignedRectangles =
ctm.Is2D(&matrix2d) && matrix2d.PreservesAxisAlignedRectangles();
}
}
Rect maxBounds = Rect(-std::numeric_limits<float>::max() * 0.5,
-std::numeric_limits<float>::max() * 0.5,
@ -2905,7 +2918,8 @@ nsRect
nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
const nsRect& aRect,
const nsIFrame* aAncestor,
bool* aPreservesAxisAlignedRectangles /* = nullptr */)
bool* aPreservesAxisAlignedRectangles /* = nullptr */,
Maybe<Matrix4x4>* aMatrixCache /* = nullptr */)
{
SVGTextFrame* text = GetContainingSVGTextFrame(aFrame);
@ -2914,7 +2928,7 @@ nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
if (text) {
result = ToRect(text->TransformFrameRectFromTextChild(aRect, aFrame));
result = TransformGfxRectToAncestor(text, result, aAncestor);
result = TransformGfxRectToAncestor(text, result, aAncestor, nullptr, aMatrixCache);
// TransformFrameRectFromTextChild could involve any kind of transform, we
// could drill down into it to get an answer out of it but we don't yet.
if (aPreservesAxisAlignedRectangles)
@ -2924,7 +2938,7 @@ nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
NSAppUnitsToFloatPixels(aRect.y, srcAppUnitsPerDevPixel),
NSAppUnitsToFloatPixels(aRect.width, srcAppUnitsPerDevPixel),
NSAppUnitsToFloatPixels(aRect.height, srcAppUnitsPerDevPixel));
result = TransformGfxRectToAncestor(aFrame, result, aAncestor, aPreservesAxisAlignedRectangles);
result = TransformGfxRectToAncestor(aFrame, result, aAncestor, aPreservesAxisAlignedRectangles, aMatrixCache);
}
float destAppUnitsPerDevPixel = aAncestor->PresContext()->AppUnitsPerDevPixel();
@ -9019,7 +9033,8 @@ nsLayoutUtils::TransformToAncestorAndCombineRegions(
nsIFrame* aFrame,
const nsIFrame* aAncestorFrame,
nsRegion* aPreciseTargetDest,
nsRegion* aImpreciseTargetDest)
nsRegion* aImpreciseTargetDest,
Maybe<Matrix4x4>* aMatrixCache)
{
if (aRegion.IsEmpty()) {
return;
@ -9028,7 +9043,7 @@ nsLayoutUtils::TransformToAncestorAndCombineRegions(
nsRegion transformedRegion;
for (nsRegion::RectIterator it = aRegion.RectIter(); !it.Done(); it.Next()) {
nsRect transformed = TransformFrameRectToAncestor(
aFrame, it.Get(), aAncestorFrame, &isPrecise);
aFrame, it.Get(), aAncestorFrame, &isPrecise, aMatrixCache);
transformedRegion.OrWith(transformed);
}
nsRegion* dest = isPrecise ? aPreciseTargetDest : aImpreciseTargetDest;

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

@ -833,11 +833,23 @@ public:
* aAncestor. Computes the bounding-box of the true quadrilateral.
* Pass non-null aPreservesAxisAlignedRectangles and it will be set to true if
* we only need to use a 2d transform that PreservesAxisAlignedRectangles().
*
* |aMatrixCache| allows for optimizations in recomputing the same matrix over
* and over. The argument can be one of the following values:
* nullptr (the default) - No optimization; the transform matrix is computed on
* every call to this function.
* non-null pointer to an empty Maybe<Matrix4x4> - Upon return, the Maybe is
* filled with the transform matrix that was computed. This can then be passed
* in to subsequent calls with the same source and destination frames to avoid
* recomputing the matrix.
* non-null pointer to a non-empty Matrix4x4 - The provided matrix will be used
* as the transform matrix and applied to the rect.
*/
static nsRect TransformFrameRectToAncestor(nsIFrame* aFrame,
const nsRect& aRect,
const nsIFrame* aAncestor,
bool* aPreservesAxisAlignedRectangles = nullptr);
bool* aPreservesAxisAlignedRectangles = nullptr,
mozilla::Maybe<Matrix4x4>* aMatrixCache = nullptr);
/**
@ -2562,7 +2574,8 @@ public:
nsIFrame* aFrame,
const nsIFrame* aAncestorFrame,
nsRegion* aPreciseTargetDest,
nsRegion* aImpreciseTargetDest);
nsRegion* aImpreciseTargetDest,
mozilla::Maybe<Matrix4x4>* aMatrixCache);
/**
* Populate aOutSize with the size of the content viewer corresponding