mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1163832 - Add an API to flush pending APZ repaint requests and dispatch a notification upon completion. r=botond
This commit is contained in:
parent
44a3bb1e74
commit
9ec5af61da
@ -24,6 +24,7 @@
|
||||
#include "nsIObjectLoadingContent.h"
|
||||
#include "nsFrame.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "mozilla/layers/APZCCallbackHelper.h"
|
||||
#include "ClientLayerManager.h"
|
||||
#include "nsQueryObject.h"
|
||||
#ifdef MOZ_FMP4
|
||||
@ -2455,6 +2456,35 @@ nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::FlushApzRepaints(bool* aOutResult)
|
||||
{
|
||||
nsIWidget* widget = GetWidget();
|
||||
if (!widget) {
|
||||
*aOutResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
// If APZ is not enabled, this function is a no-op. After bug 1162064 this
|
||||
// should be a widget->IsAsyncPanZoomEnabled() check.
|
||||
if (!gfxPrefs::AsyncPanZoomEnabled()) {
|
||||
*aOutResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
LayerManager* manager = widget->GetLayerManager();
|
||||
if (!manager) {
|
||||
*aOutResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
|
||||
if (!forwarder || !forwarder->HasShadowManager()) {
|
||||
*aOutResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
forwarder->GetShadowManager()->SendFlushApzRepaints();
|
||||
*aOutResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
|
||||
const nsAString& aProperty,
|
||||
|
@ -49,7 +49,7 @@ interface nsIJSRAIIHelper;
|
||||
interface nsIContentPermissionRequest;
|
||||
interface nsIObserver;
|
||||
|
||||
[scriptable, uuid(0ce789cc-3fb6-48b8-a58e-32deefc337b4)]
|
||||
[scriptable, uuid(663e4d9a-c963-4949-b68e-3a6f71c0414f)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -1428,6 +1428,16 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
*/
|
||||
void setAsyncScrollOffset(in nsIDOMNode aNode, in int32_t aX, in int32_t aY);
|
||||
|
||||
/**
|
||||
* Do a round-trip to the compositor to ensure any pending APZ repaint requests
|
||||
* get flushed to the main thread. If the function returns true, the flush was
|
||||
* triggered and an "apz-repaints-flushed" notification will be dispatched via
|
||||
* the observer service once the flush is complete. If the function returns
|
||||
* false, an error occurred or a flush is not needed, and the notification
|
||||
* will not fire. This is intended to be used by test code only!
|
||||
*/
|
||||
bool flushApzRepaints();
|
||||
|
||||
/**
|
||||
* Method for testing StyleAnimationValue::ComputeDistance.
|
||||
*
|
||||
|
@ -589,6 +589,7 @@ child:
|
||||
HandleSingleTap(CSSPoint aPoint, Modifiers aModifiers, ScrollableLayerGuid aGuid);
|
||||
HandleLongTap(CSSPoint point, Modifiers aModifiers, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
|
||||
NotifyAPZStateChange(ViewID aViewId, APZStateChange aChange, int aArg);
|
||||
NotifyFlushComplete();
|
||||
|
||||
|
||||
/**
|
||||
|
@ -2138,6 +2138,13 @@ TabChild::RecvNotifyAPZStateChange(const ViewID& aViewId,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvNotifyFlushComplete()
|
||||
{
|
||||
APZCCallbackHelper::NotifyFlushComplete();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvActivate()
|
||||
{
|
||||
|
@ -342,6 +342,7 @@ public:
|
||||
virtual bool RecvNotifyAPZStateChange(const ViewID& aViewId,
|
||||
const APZStateChange& aChange,
|
||||
const int& aArg) override;
|
||||
virtual bool RecvNotifyFlushComplete() override;
|
||||
virtual bool RecvActivate() override;
|
||||
virtual bool RecvDeactivate() override;
|
||||
virtual bool RecvMouseEvent(const nsString& aType,
|
||||
|
@ -1069,6 +1069,14 @@ TabParent::NotifyMouseScrollTestEvent(const ViewID& aScrollId, const nsString& a
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TabParent::NotifyFlushComplete()
|
||||
{
|
||||
if (!mIsDestroyed) {
|
||||
unused << SendNotifyFlushComplete();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TabParent::Activate()
|
||||
{
|
||||
|
@ -274,6 +274,7 @@ public:
|
||||
APZStateChange aChange,
|
||||
int aArg);
|
||||
void NotifyMouseScrollTestEvent(const ViewID& aScrollId, const nsString& aEvent);
|
||||
void NotifyFlushComplete();
|
||||
void Activate();
|
||||
void Deactivate();
|
||||
|
||||
|
@ -158,6 +158,11 @@ public:
|
||||
virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Notify content that the repaint requests have been flushed.
|
||||
*/
|
||||
virtual void NotifyFlushComplete() = 0;
|
||||
|
||||
GeckoContentController() {}
|
||||
virtual void Destroy() {}
|
||||
|
||||
|
@ -554,6 +554,19 @@ APZCTreeManager::UpdateHitTestingTree(TreeBuildingState& aState,
|
||||
return node;
|
||||
}
|
||||
|
||||
void
|
||||
APZCTreeManager::FlushApzRepaints(uint64_t aLayersId)
|
||||
{
|
||||
{ // scope lock
|
||||
MonitorAutoLock lock(mTreeLock);
|
||||
FlushPendingRepaintRecursively(mRootNode, aLayersId);
|
||||
}
|
||||
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(aLayersId);
|
||||
MOZ_ASSERT(state && state->mController);
|
||||
NS_DispatchToMainThread(NS_NewRunnableMethod(
|
||||
state->mController.get(), &GeckoContentController::NotifyFlushComplete));
|
||||
}
|
||||
|
||||
nsEventStatus
|
||||
APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
|
||||
ScrollableLayerGuid* aOutTargetGuid,
|
||||
@ -1071,6 +1084,23 @@ APZCTreeManager::FlushRepaintsRecursively(HitTestingTreeNode* aNode)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
APZCTreeManager::FlushPendingRepaintRecursively(HitTestingTreeNode* aNode, uint64_t aLayersId)
|
||||
{
|
||||
mTreeLock.AssertCurrentThreadOwns();
|
||||
|
||||
for (HitTestingTreeNode* node = aNode; node; node = node->GetPrevSibling()) {
|
||||
if (node->IsPrimaryHolder()) {
|
||||
AsyncPanZoomController* apzc = node->GetApzc();
|
||||
MOZ_ASSERT(apzc);
|
||||
if (apzc->GetGuid().mLayersId == aLayersId) {
|
||||
apzc->FlushRepaintIfPending();
|
||||
}
|
||||
}
|
||||
FlushPendingRepaintRecursively(node->GetLastChild(), aLayersId);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
APZCTreeManager::CancelAnimation(const ScrollableLayerGuid &aGuid)
|
||||
{
|
||||
|
@ -130,6 +130,13 @@ public:
|
||||
uint64_t aOriginatingLayersId,
|
||||
uint32_t aPaintSequenceNumber);
|
||||
|
||||
/**
|
||||
* Walk the tree of APZCs and flushes the repaint requests for all the APZCS
|
||||
* corresponding to the given layers id. Finally, sends a flush complete
|
||||
* notification to the GeckoContentController for the layers id.
|
||||
*/
|
||||
void FlushApzRepaints(uint64_t aLayersId);
|
||||
|
||||
/**
|
||||
* General handler for incoming input events. Manipulates the frame metrics
|
||||
* based on what type of input it is. For example, a PinchGestureEvent will
|
||||
@ -430,6 +437,7 @@ private:
|
||||
void UpdateZoomConstraintsRecursively(HitTestingTreeNode* aNode,
|
||||
const ZoomConstraints& aConstraints);
|
||||
void FlushRepaintsRecursively(HitTestingTreeNode* aNode);
|
||||
void FlushPendingRepaintRecursively(HitTestingTreeNode* aNode, uint64_t aLayersId);
|
||||
|
||||
already_AddRefed<HitTestingTreeNode> RecycleOrCreateNode(TreeBuildingState& aState,
|
||||
AsyncPanZoomController* aApzc);
|
||||
|
@ -2446,6 +2446,13 @@ void AsyncPanZoomController::FlushRepaintForNewInputBlock() {
|
||||
UpdateSharedCompositorFrameMetrics();
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::FlushRepaintIfPending() {
|
||||
// Just tell the paint throttler to send the pending repaint request if
|
||||
// there is one.
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
mPaintThrottler.TaskComplete(GetFrameTime());
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::SnapBackIfOverscrolled() {
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
// It's possible that we're already in the middle of an overscroll
|
||||
|
@ -183,6 +183,11 @@ public:
|
||||
*/
|
||||
void NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint);
|
||||
|
||||
/**
|
||||
* Flush any pending repaint request.
|
||||
*/
|
||||
void FlushRepaintIfPending();
|
||||
|
||||
/**
|
||||
* The platform implementation must set the compositor parent so that we can
|
||||
* request composites.
|
||||
|
@ -710,6 +710,15 @@ APZCCallbackHelper::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrol
|
||||
true, true);
|
||||
}
|
||||
|
||||
void
|
||||
APZCCallbackHelper::NotifyFlushComplete()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
MOZ_ASSERT(observerService);
|
||||
observerService->NotifyObservers(nullptr, "apz-repaints-flushed", nullptr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,6 +161,9 @@ public:
|
||||
|
||||
/* Notify content of a mouse scroll testing event. */
|
||||
static void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent);
|
||||
|
||||
/* Notify content that the repaint flush is complete. */
|
||||
static void NotifyFlushComplete();
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -213,3 +213,10 @@ ChromeProcessController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& a
|
||||
|
||||
APZCCallbackHelper::NotifyMozMouseScrollEvent(aScrollId, aEvent);
|
||||
}
|
||||
|
||||
void
|
||||
ChromeProcessController::NotifyFlushComplete()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
APZCCallbackHelper::NotifyFlushComplete();
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
int aArg) override;
|
||||
virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
|
||||
const nsString& aEvent) override;
|
||||
virtual void NotifyFlushComplete() override;
|
||||
private:
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
nsRefPtr<APZEventState> mAPZEventState;
|
||||
|
@ -1326,6 +1326,13 @@ CompositorParent::RecvRequestOverfill()
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
|
||||
{
|
||||
MOZ_ASSERT(mApzcTreeManager);
|
||||
mApzcTreeManager->FlushApzRepaints(aLayerTree->GetId());
|
||||
}
|
||||
|
||||
void
|
||||
CompositorParent::GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||
APZTestData* aOutData)
|
||||
@ -1734,6 +1741,7 @@ public:
|
||||
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) override;
|
||||
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
|
||||
override;
|
||||
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
|
||||
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||
APZTestData* aOutData) override;
|
||||
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
||||
@ -2146,6 +2154,21 @@ CrossProcessCompositorParent::ApplyAsyncProperties(
|
||||
state->mParent->ApplyAsyncProperties(aLayerTree);
|
||||
}
|
||||
|
||||
void
|
||||
CrossProcessCompositorParent::FlushApzRepaints(const LayerTransactionParent* aLayerTree)
|
||||
{
|
||||
uint64_t id = aLayerTree->GetId();
|
||||
MOZ_ASSERT(id != 0);
|
||||
const CompositorParent::LayerTreeState* state =
|
||||
CompositorParent::GetIndirectShadowTree(id);
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(state->mParent);
|
||||
state->mParent->FlushApzRepaints(aLayerTree);
|
||||
}
|
||||
|
||||
void
|
||||
CrossProcessCompositorParent::GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||
APZTestData* aOutData)
|
||||
|
@ -268,6 +268,7 @@ public:
|
||||
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) override;
|
||||
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
|
||||
override;
|
||||
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) override;
|
||||
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||
APZTestData* aOutData) override;
|
||||
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
||||
|
@ -783,6 +783,13 @@ LayerTransactionParent::RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aSc
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
LayerTransactionParent::RecvFlushApzRepaints()
|
||||
{
|
||||
mShadowLayersManager->FlushApzRepaints(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
LayerTransactionParent::RecvGetAPZTestData(APZTestData* aOutData)
|
||||
{
|
||||
|
@ -133,6 +133,7 @@ protected:
|
||||
override;
|
||||
virtual bool RecvSetAsyncScrollOffset(const FrameMetrics::ViewID& aId,
|
||||
const int32_t& aX, const int32_t& aY) override;
|
||||
virtual bool RecvFlushApzRepaints() override;
|
||||
virtual bool RecvGetAPZTestData(APZTestData* aOutData) override;
|
||||
virtual bool RecvRequestProperty(const nsString& aProperty, float* aValue) override;
|
||||
virtual bool RecvSetConfirmedTargetAPZC(const uint64_t& aBlockId,
|
||||
|
@ -89,6 +89,9 @@ parent:
|
||||
// Useful for testing rendering of async scrolling.
|
||||
sync SetAsyncScrollOffset(ViewID id, int32_t x, int32_t y);
|
||||
|
||||
// Flush any pending APZ repaints to the main thread.
|
||||
async FlushApzRepaints();
|
||||
|
||||
// Drop any front buffers that might be retained on the compositor
|
||||
// side.
|
||||
async ClearCachedResources();
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
const TimeStamp& aTime) { return true; }
|
||||
virtual void LeaveTestMode(LayerTransactionParent* aLayerTree) { }
|
||||
virtual void ApplyAsyncProperties(LayerTransactionParent* aLayerTree) = 0;
|
||||
virtual void FlushApzRepaints(const LayerTransactionParent* aLayerTree) = 0;
|
||||
virtual void GetAPZTestData(const LayerTransactionParent* aLayerTree,
|
||||
APZTestData* aOutData) { }
|
||||
virtual void SetConfirmedTargetAPZC(const LayerTransactionParent* aLayerTree,
|
||||
|
@ -70,6 +70,7 @@ public:
|
||||
MOCK_METHOD3(SendAsyncScrollDOMEvent, void(bool aIsRoot, const CSSRect &aContentRect, const CSSSize &aScrollableSize));
|
||||
MOCK_METHOD2(PostDelayedTask, void(Task* aTask, int aDelayMs));
|
||||
MOCK_METHOD3(NotifyAPZStateChange, void(const ScrollableLayerGuid& aGuid, APZStateChange aChange, int aArg));
|
||||
MOCK_METHOD0(NotifyFlushComplete, void());
|
||||
};
|
||||
|
||||
class MockContentControllerDelayed : public MockContentController {
|
||||
|
@ -270,6 +270,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void NotifyFlushComplete() override {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mRenderFrame) {
|
||||
TabParent* browser = TabParent::GetFrom(mRenderFrame->Manager());
|
||||
browser->NotifyFlushComplete();
|
||||
}
|
||||
}
|
||||
|
||||
// Methods used by RenderFrameParent to set fields stored here.
|
||||
|
||||
void SaveZoomConstraints(const ZoomConstraints& aConstraints)
|
||||
|
Loading…
Reference in New Issue
Block a user