Bug 1479754 - Hook up the force-first-paint codepath with webrender r=kats

When a CompositorBridgeParent receives a force first paint message, it
sets the flag on the AsyncCompositionManager, which notifies the
widget code at the next composite via
UiCompositorControllerParent::NotifyFirstPaint().

With webrender, this is crashing as there is no
AsyncCompositionManager. And even if it weren't crashing, the widget
will never receive the first paint message, so it never uncovers its
content.

This change ensures the widget receives the first message when
webrender is enabled. CompositorBridgeParent will set the flag on its
WebRenderBridgeParent, which will set the flag on the next received
display list. When the WebRenderBridgeParent flushes the corresponding
transaction, it calls UiCompositorcontrollerParent::NotifyFirstPaint,
to ensure the widget code gets the message.

Differential Revision: https://phabricator.services.mozilla.com/D9250

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jamie Nicol 2018-10-19 13:48:04 +00:00
Родитель 02b1c3c4d5
Коммит 9498be51e6
3 изменённых файлов: 46 добавлений и 6 удалений

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

@ -467,7 +467,11 @@ CompositorBridgeParent::~CompositorBridgeParent()
void
CompositorBridgeParent::ForceIsFirstPaint()
{
mCompositionManager->ForceIsFirstPaint();
if (mWrBridge) {
mWrBridge->ForceIsFirstPaint();
} else {
mCompositionManager->ForceIsFirstPaint();
}
}
void
@ -2205,11 +2209,14 @@ CompositorBridgeParent::NotifyPipelineRendered(const wr::PipelineId& aPipelineId
return;
}
RefPtr<UiCompositorControllerParent> uiController =
UiCompositorControllerParent::GetFromRootLayerTreeId(mRootLayerTreeID);
if (mWrBridge->PipelineId() == aPipelineId) {
mWrBridge->RemoveEpochDataPriorTo(aEpoch);
if (!mPaused) {
TransactionId transactionId = mWrBridge->FlushTransactionIdsForEpoch(aEpoch, aCompositeEnd);
TransactionId transactionId = mWrBridge->FlushTransactionIdsForEpoch(aEpoch, aCompositeEnd, uiController);
Unused << SendDidComposite(LayersId{0}, transactionId, aCompositeStart, aCompositeEnd);
nsTArray<ImageCompositeNotificationInfo> notifications;
@ -2231,7 +2238,7 @@ CompositorBridgeParent::NotifyPipelineRendered(const wr::PipelineId& aPipelineId
if (!mPaused) {
CrossProcessCompositorBridgeParent* cpcp = lts->mCrossProcessParent;
TransactionId transactionId = lts->mWrBridge->FlushTransactionIdsForEpoch(aEpoch, aCompositeEnd);
TransactionId transactionId = lts->mWrBridge->FlushTransactionIdsForEpoch(aEpoch, aCompositeEnd, uiController);
Unused << cpcp->SendDidComposite(aLayersId, transactionId, aCompositeStart, aCompositeEnd);
}
}

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

@ -229,6 +229,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompos
, mPaused(false)
, mDestroyed(false)
, mReceivedDisplayList(false)
, mIsFirstPaint(true)
{
MOZ_ASSERT(mAsyncImageManager);
MOZ_ASSERT(mAnimStorage);
@ -249,6 +250,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(const wr::PipelineId& aPipelineId)
, mPaused(false)
, mDestroyed(true)
, mReceivedDisplayList(false)
, mIsFirstPaint(false)
{
}
@ -819,6 +821,10 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
mReceivedDisplayList = true;
if (aScrollData.IsFirstPaint()) {
mIsFirstPaint = true;
}
// aScrollData is moved into this function but that is not reflected by the
// function signature due to the way the IPDL generator works. We remove the
// const so that we can move this structure all the way to the desired
@ -864,7 +870,8 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
}
HoldPendingTransactionId(wrEpoch, aTransactionId, aContainsSVGGroup,
aRefreshStartTime, aTxnStartTime, aFwdTime);
aRefreshStartTime, aTxnStartTime, aFwdTime, mIsFirstPaint);
mIsFirstPaint = false;
if (!validTransaction) {
// Pretend we composited since someone is wating for this event,
@ -964,6 +971,7 @@ WebRenderBridgeParent::RecvEmptyTransaction(const FocusTarget& aFocusTarget,
aRefreshStartTime,
aTxnStartTime,
aFwdTime,
/* aIsFirstPaint */false,
/* aUseForTelemetry */scheduleComposite);
if (scheduleComposite) {
@ -1688,6 +1696,7 @@ WebRenderBridgeParent::HoldPendingTransactionId(const wr::Epoch& aWrEpoch,
const TimeStamp& aRefreshStartTime,
const TimeStamp& aTxnStartTime,
const TimeStamp& aFwdTime,
const bool aIsFirstPaint,
const bool aUseForTelemetry)
{
MOZ_ASSERT(aTransactionId > LastPendingTransactionId());
@ -1697,6 +1706,7 @@ WebRenderBridgeParent::HoldPendingTransactionId(const wr::Epoch& aWrEpoch,
aRefreshStartTime,
aTxnStartTime,
aFwdTime,
aIsFirstPaint,
aUseForTelemetry));
}
@ -1711,7 +1721,8 @@ WebRenderBridgeParent::LastPendingTransactionId()
}
TransactionId
WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime)
WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime,
UiCompositorControllerParent* aUiController)
{
TransactionId id{0};
while (!mPendingTransactionIds.empty()) {
@ -1741,6 +1752,11 @@ WebRenderBridgeParent::FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, cons
printf_stderr("From forwarding transaction to end of generate frame latencyMs %d this %p\n", latencyMs, this);
}
#endif
if (aUiController && transactionId.mIsFirstPaint) {
aUiController->NotifyFirstPaint();
}
id = transactionId.mId;
mPendingTransactionIds.pop();
}

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

@ -15,6 +15,7 @@
#include "mozilla/layers/CompositableTransactionParent.h"
#include "mozilla/layers/CompositorVsyncSchedulerOwner.h"
#include "mozilla/layers/PWebRenderBridgeParent.h"
#include "mozilla/layers/UiCompositorControllerParent.h"
#include "mozilla/Maybe.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/webrender/WebRenderAPI.h"
@ -159,9 +160,11 @@ public:
const TimeStamp& aRefreshStartTime,
const TimeStamp& aTxnStartTime,
const TimeStamp& aFwdTime,
const bool aIsFirstPaint,
const bool aUseForTelemetry = true);
TransactionId LastPendingTransactionId();
TransactionId FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime);
TransactionId FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime,
UiCompositorControllerParent* aUiController);
TextureFactoryIdentifier GetTextureFactoryIdentifier();
@ -203,6 +206,16 @@ public:
void RemoveEpochDataPriorTo(const wr::Epoch& aRenderedEpoch);
/**
* This sets the is-first-paint flag to true for the next received
* display list. This is intended to be called by the widget code when it
* loses its viewport information (or for whatever reason wants to refresh
* the viewport information). The message will sent back to the widget code
* via UiCompositorControllerParent::NotifyFirstPaint() when the corresponding
* transaction is flushed.
*/
void ForceIsFirstPaint() { mIsFirstPaint = true; }
private:
explicit WebRenderBridgeParent(const wr::PipelineId& aPipelineId);
virtual ~WebRenderBridgeParent();
@ -278,6 +291,7 @@ private:
const TimeStamp& aRefreshStartTime,
const TimeStamp& aTxnStartTime,
const TimeStamp& aFwdTime,
const bool aIsFirstPaint,
const bool aUseForTelemetry)
: mEpoch(aEpoch)
, mId(aId)
@ -285,6 +299,7 @@ private:
, mTxnStartTime(aTxnStartTime)
, mFwdTime(aFwdTime)
, mContainsSVGGroup(aContainsSVGGroup)
, mIsFirstPaint(aIsFirstPaint)
, mUseForTelemetry(aUseForTelemetry)
{}
wr::Epoch mEpoch;
@ -293,6 +308,7 @@ private:
TimeStamp mTxnStartTime;
TimeStamp mFwdTime;
bool mContainsSVGGroup;
bool mIsFirstPaint;
bool mUseForTelemetry;
};
@ -338,6 +354,7 @@ private:
bool mPaused;
bool mDestroyed;
bool mReceivedDisplayList;
bool mIsFirstPaint;
};
} // namespace layers