Bug 1465616 - Temporarily apply async test attributes when compositing. r=botond,kats

Includes a new RAII class: AutoApplyAsyncTestAttributes, which, for the
duration of its lifetime, applies mTestAsyncScrollOffset and mTestAsyncZoom to
the APZC's FrameMetrics. We need this to ensure that the
AsyncPanZoomController::GetCurrentAsync* methods consider test scroll and zoom
attributes when doing their respective computations.

MozReview-Commit-ID: 9owJcdIegNH

--HG--
extra : rebase_source : 35273faf10b8db13e3b5485278262f93d4adc579
This commit is contained in:
Kashav Madan 2018-07-20 17:37:36 -04:00
Родитель e3060a3711
Коммит 2a9fbaf66d
8 изменённых файлов: 124 добавлений и 18 удалений

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

@ -11,6 +11,7 @@
#include "base/platform_thread.h" // for PlatformThreadId
#include "mozilla/layers/AsyncCompositionManager.h" // for AsyncTransform
#include "mozilla/layers/APZUtils.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/StaticPtr.h"
#include "nsTArray.h"
@ -90,6 +91,13 @@ public:
void MarkAsyncTransformAppliedToContent(const LayerMetricsWrapper& aLayer);
bool HasUnusedAsyncTransform(const LayerMetricsWrapper& aLayer);
/**
* Return a new AutoApplyAsyncTestAttributes instance. This should be called
* whenever we need to apply async attributes for test purposes (namely
* reftest-async-scroll-{x,y} and reftest-async-zoom).
*/
UniquePtr<AutoApplyAsyncTestAttributes> ApplyAsyncTestAttributes(const LayerMetricsWrapper& aLayer);
/**
* This can be used to assert that the current thread is the
* sampler thread (which samples the async transform).

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

@ -601,6 +601,11 @@ APZCTreeManager::SampleForWebRender(wr::TransactionWrapper& aTxn,
bool activeAnimations = false;
for (const auto& mapping : mApzcMap) {
AsyncPanZoomController* apzc = mapping.second;
// Apply any additional async scrolling for testing purposes (used for
// reftest-async-scroll and reftest-async-zoom).
auto _ = MakeUnique<AutoApplyAsyncTestAttributes>(apzc);
ParentLayerPoint layerTranslation = apzc->GetCurrentAsyncTransform(
AsyncPanZoomController::eForCompositing).mTranslation;
@ -3046,6 +3051,9 @@ APZCTreeManager::ComputeTransformForNode(const HitTestingTreeNode* aNode) const
{
mTreeLock.AssertCurrentThreadIn();
if (AsyncPanZoomController* apzc = aNode->GetApzc()) {
// Apply any additional async scrolling for testing purposes (used for
// reftest-async-scroll and reftest-async-zoom).
auto _ = MakeUnique<AutoApplyAsyncTestAttributes>(apzc);
// If the node represents scrollable content, apply the async transform
// from its APZC.
return aNode->GetTransform() *
@ -3135,6 +3143,10 @@ APZCTreeManager::ComputeTransformForScrollThumb(
MOZ_RELEASE_ASSERT(aApzc);
// Apply any additional async scrolling for testing purposes (used for
// reftest-async-scroll and reftest-async-zoom).
auto _ = MakeUnique<AutoApplyAsyncTestAttributes>(aApzc);
AsyncTransformComponentMatrix asyncTransform =
aApzc->GetCurrentAsyncTransform(AsyncPanZoomController::eForCompositing);

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

@ -10,6 +10,7 @@
#include "AsyncPanZoomController.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/layers/APZThreadUtils.h"
#include "mozilla/layers/APZUtils.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/LayerMetricsWrapper.h"
#include "mozilla/layers/SynchronousTask.h"
@ -222,6 +223,16 @@ APZSampler::HasUnusedAsyncTransform(const LayerMetricsWrapper& aLayer)
&& !AsyncTransformComponentMatrix(apzc->GetCurrentAsyncTransform(AsyncPanZoomController::eForCompositing)).IsIdentity();
}
UniquePtr<AutoApplyAsyncTestAttributes>
APZSampler::ApplyAsyncTestAttributes(const LayerMetricsWrapper& aLayer)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
AssertOnSamplerThread();
MOZ_ASSERT(aLayer.GetApzc());
return MakeUnique<AutoApplyAsyncTestAttributes>(aLayer.GetApzc());
}
void
APZSampler::AssertOnSamplerThread() const
{

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

@ -10,6 +10,19 @@
namespace mozilla {
namespace layers {
AutoApplyAsyncTestAttributes::AutoApplyAsyncTestAttributes(AsyncPanZoomController* aApzc)
: mApzc(aApzc)
, mPrevFrameMetrics(aApzc->Metrics())
{
mApzc->ApplyAsyncTestAttributes();
}
AutoApplyAsyncTestAttributes::~AutoApplyAsyncTestAttributes()
{
mApzc->UnapplyAsyncTestAttributes(mPrevFrameMetrics);
}
namespace apz {
/*static*/ void

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

@ -20,6 +20,8 @@
namespace mozilla {
namespace layers {
class AsyncPanZoomController;
enum CancelAnimationFlags : uint32_t {
Default = 0x0, /* Cancel all animations */
ExcludeOverscroll = 0x1, /* Don't clear overscroll */
@ -98,6 +100,19 @@ struct TargetConfirmationFlags {
bool mRequiresTargetConfirmation : 1;
};
/**
* An RAII class to temporarily apply async test attributes to the provided
* AsyncPanZoomController.
*/
class AutoApplyAsyncTestAttributes {
public:
explicit AutoApplyAsyncTestAttributes(AsyncPanZoomController*);
~AutoApplyAsyncTestAttributes();
private:
AsyncPanZoomController* mApzc;
FrameMetrics mPrevFrameMetrics;
};
namespace apz {
/**

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

@ -3799,8 +3799,7 @@ AsyncPanZoomController::GetCurrentAsyncScrollOffset(AsyncTransformConsumer aMode
return mLastContentPaintMetrics.GetScrollOffset() * mLastContentPaintMetrics.GetZoom();
}
return (GetEffectiveScrollOffset(aMode) + mTestAsyncScrollOffset)
* GetEffectiveZoom(aMode) * mTestAsyncZoom.scale;
return GetEffectiveScrollOffset(aMode) * GetEffectiveZoom(aMode);
}
CSSPoint
@ -3811,7 +3810,7 @@ AsyncPanZoomController::GetCurrentAsyncScrollOffsetInCssPixels(AsyncTransformCon
return mLastContentPaintMetrics.GetScrollOffset();
}
return GetEffectiveScrollOffset(aMode) + mTestAsyncScrollOffset;
return GetEffectiveScrollOffset(aMode);
}
AsyncTransform
@ -3828,8 +3827,7 @@ AsyncPanZoomController::GetCurrentAsyncTransform(AsyncTransformConsumer aMode) c
lastPaintScrollOffset = mLastContentPaintMetrics.GetScrollOffset();
}
CSSPoint currentScrollOffset = GetEffectiveScrollOffset(aMode) +
mTestAsyncScrollOffset;
CSSPoint currentScrollOffset = GetEffectiveScrollOffset(aMode);
// If checkerboarding has been disallowed, clamp the scroll position to stay
// within rendered content.
@ -3850,15 +3848,19 @@ AsyncPanZoomController::GetCurrentAsyncTransform(AsyncTransformConsumer aMode) c
}
CSSToParentLayerScale2D effectiveZoom = GetEffectiveZoom(aMode);
ParentLayerPoint translation = (currentScrollOffset - lastPaintScrollOffset)
* effectiveZoom * mTestAsyncZoom.scale;
ParentLayerPoint translation =
(currentScrollOffset - lastPaintScrollOffset) * effectiveZoom;
LayerToParentLayerScale compositedAsyncZoom =
(effectiveZoom / Metrics().LayersPixelsPerCSSPixel()).ToScaleFactor();
return AsyncTransform(
LayerToParentLayerScale(compositedAsyncZoom.scale * mTestAsyncZoom.scale),
-translation);
(effectiveZoom / Metrics().LayersPixelsPerCSSPixel()).ToScaleFactor();
return AsyncTransform(compositedAsyncZoom, -translation);
}
AsyncTransformComponentMatrix
AsyncPanZoomController::GetCurrentAsyncTransformWithOverscroll(AsyncTransformConsumer aMode) const
{
return AsyncTransformComponentMatrix(GetCurrentAsyncTransform(aMode))
* GetOverscrollTransform(aMode);
}
CSSRect
@ -3902,11 +3904,29 @@ AsyncPanZoomController::SampleCompositedAsyncTransform()
return false;
}
AsyncTransformComponentMatrix
AsyncPanZoomController::GetCurrentAsyncTransformWithOverscroll(AsyncTransformConsumer aMode) const
{
return AsyncTransformComponentMatrix(GetCurrentAsyncTransform(aMode))
* GetOverscrollTransform(aMode);
bool
AsyncPanZoomController::ApplyAsyncTestAttributes() {
RecursiveMutexAutoLock lock(mRecursiveMutex);
if (mTestAsyncScrollOffset == CSSPoint() &&
mTestAsyncZoom == LayerToParentLayerScale()) {
return false;
}
Metrics().ZoomBy(mTestAsyncZoom.scale);
ScrollBy(mTestAsyncScrollOffset);
SampleCompositedAsyncTransform();
return true;
}
bool
AsyncPanZoomController::UnapplyAsyncTestAttributes(const FrameMetrics& aPrevFrameMetrics) {
RecursiveMutexAutoLock lock(mRecursiveMutex);
if (mTestAsyncScrollOffset == CSSPoint() &&
mTestAsyncZoom == LayerToParentLayerScale()) {
return false;
}
Metrics() = aPrevFrameMetrics;
SampleCompositedAsyncTransform();
return true;
}
Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {

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

@ -1086,6 +1086,28 @@ private:
CSSPoint GetEffectiveScrollOffset(AsyncTransformConsumer aMode) const;
CSSToParentLayerScale2D GetEffectiveZoom(AsyncTransformConsumer aMode) const;
private:
friend class AutoApplyAsyncTestAttributes;
/**
* Applies |mTestAsyncScrollOffset| and |mTestAsyncZoom| to this
* AsyncPanZoomController. Calls |SampleCompositedAsyncTransform| to ensure
* that the GetCurrentAsync* functions consider the test offset and zoom in
* their computations.
*
* Returns false if neither test value is set, and true otherwise.
*/
bool ApplyAsyncTestAttributes();
/**
* Sets this AsyncPanZoomController's FrameMetrics to |aPrevFrameMetrics| and
* calls |SampleCompositedAsyncTransform| to unapply any test values applied
* by |ApplyAsyncTestAttributes|.
*
* Returns false if neither test value is set, and true otherwise.
*/
bool UnapplyAsyncTestAttributes(const FrameMetrics& aPrevFrameMetrics);
/* ===================================================================
* The functions and members in this section are used to manage
* the state that tracks what this APZC is doing with the input events.

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

@ -977,6 +977,11 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer,
if (!wrapper.GetApzc()) {
continue;
}
// Apply any additional async scrolling for testing purposes (used
// for reftest-async-scroll and reftest-async-zoom).
auto _ = sampler->ApplyAsyncTestAttributes(wrapper);
const FrameMetrics& metrics = wrapper.Metrics();
MOZ_ASSERT(metrics.IsScrollable());