Bug 1441308 - Always send parent commands when sending mDestroyedActors r=kats,sotaro

If we try to send them separately as we were before, we can run into
cases where we try to destroy the actors and then send the OpRemoveTexture,
which crashes.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Doug Thayer 2019-03-22 18:29:04 +00:00
Родитель 3f608fab0a
Коммит a794a12c8c
6 изменённых файлов: 61 добавлений и 46 удалений

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

@ -21,12 +21,12 @@ struct RenderRootDisplayListData {
gfx::IntRect mRect;
nsTArray<WebRenderParentCommand> mCommands;
wr::LayoutSize mContentSize;
mozilla::ipc::ByteBuf mDL;
Maybe<mozilla::ipc::ByteBuf> mDL;
wr::BuiltDisplayListDescriptor mDLDesc;
nsTArray<OpUpdateResource> mResourceUpdates;
nsTArray<RefCountedShmem> mSmallShmems;
nsTArray<mozilla::ipc::Shmem> mLargeShmems;
WebRenderScrollData mScrollData;
Maybe<WebRenderScrollData> mScrollData;
};
struct RenderRootUpdates {
@ -65,5 +65,4 @@ struct IPDLParamTraits<mozilla::layers::RenderRootUpdates> {
} // namespace ipc
} // namespace mozilla
#endif /* GFX_RENDERROOTTYPES_H */

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

@ -66,6 +66,9 @@ class WebRenderBridgeChild final : public PWebRenderBridgeChild,
void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd,
wr::RenderRoot aRenderRoot);
bool HasWebRenderParentCommands(wr::RenderRoot aRenderRoot) {
return !mParentCommands[aRenderRoot].IsEmpty();
}
void UpdateResources(wr::IpcResourceUpdateQueue& aResources,
wr::RenderRoot aRenderRoot);

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

@ -896,25 +896,13 @@ void WebRenderBridgeParent::SetAPZSampleTime() {
bool WebRenderBridgeParent::SetDisplayList(
wr::RenderRoot aRenderRoot, const gfx::IntRect& aRect,
const nsTArray<WebRenderParentCommand>& aCommands,
const wr::LayoutSize& aContentSize, ipc::ByteBuf&& aDL,
const wr::BuiltDisplayListDescriptor& aDLDesc,
const nsTArray<OpUpdateResource>& aResourceUpdates,
const nsTArray<RefCountedShmem>& aSmallShmems,
const nsTArray<ipc::Shmem>& aLargeShmems, const TimeStamp& aTxnStartTime,
wr::TransactionBuilder& aTxn, Maybe<wr::AutoTransactionSender>& aTxnSender,
wr::Epoch aWrEpoch, bool aValidTransaction, bool aObserveLayersUpdate) {
wr::WebRenderAPI* api = Api(aRenderRoot);
aTxn.SetLowPriority(!IsRootWebRenderBridgeParent());
if (aValidTransaction) {
aTxnSender.emplace(api, &aTxn);
}
if (NS_WARN_IF(
!ProcessWebRenderParentCommands(aCommands, aTxn, aRenderRoot))) {
return false;
}
wr::TransactionBuilder& aTxn, wr::Epoch aWrEpoch, bool aValidTransaction,
bool aObserveLayersUpdate) {
if (NS_WARN_IF(!UpdateResources(aResourceUpdates, aSmallShmems, aLargeShmems,
aTxn))) {
return false;
@ -954,7 +942,7 @@ bool WebRenderBridgeParent::SetDisplayList(
MakeUnique<SceneBuiltNotification>(this, aWrEpoch, aTxnStartTime));
}
api->SendTransaction(aTxn);
Api(aRenderRoot)->SendTransaction(aTxn);
// We will schedule generating a frame after the scene
// build is done, so we don't need to do it here.
@ -1006,16 +994,26 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
mReceivedDisplayList = true;
bool observeLayersUpdate = ShouldParentObserveEpoch();
// The IsFirstPaint() flag should be the same for all the scrolldata across
// all the renderroot display lists in a given transaction. We assert this
// below. So we can read the flag from any one of them.
if (aDisplayLists[0].mScrollData.IsFirstPaint()) {
mIsFirstPaint = true;
}
// The IsFirstPaint() flag should be the same for all the non-empty
// scrolldata across all the renderroot display lists in a given
// transaction. We assert this below. So we can read the flag from any one
// of them.
Maybe<size_t> firstScrollDataIndex;
for (size_t i = 1; i < aDisplayLists.Length(); i++) {
// Ensure the flag is the same on all of them.
MOZ_RELEASE_ASSERT(aDisplayLists[i].mScrollData.IsFirstPaint() ==
aDisplayLists[0].mScrollData.IsFirstPaint());
auto& scrollData = aDisplayLists[i].mScrollData;
if (scrollData) {
if (firstScrollDataIndex.isNothing()) {
firstScrollDataIndex = Some(i);
if (scrollData && scrollData->IsFirstPaint()) {
mIsFirstPaint = true;
}
} else {
auto firstNonEmpty = aDisplayLists[*firstScrollDataIndex].mScrollData;
// Ensure the flag is the same on all of them.
MOZ_RELEASE_ASSERT(scrollData->IsFirstPaint() ==
firstNonEmpty->IsFirstPaint());
}
}
}
// aScrollData is moved into this function but that is not reflected by the
@ -1026,8 +1024,10 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
// sent to WebRender, so that the UpdateHitTestingTree call is guaranteed to
// be in the updater queue at the time that the scene swap completes.
for (auto& displayList : aDisplayLists) {
UpdateAPZScrollData(wrEpoch, std::move(displayList.mScrollData),
displayList.mRenderRoot);
if (displayList.mScrollData) {
UpdateAPZScrollData(wrEpoch, std::move(displayList.mScrollData.ref()),
displayList.mRenderRoot);
}
}
bool validTransaction = aIdNamespace == mIdNamespace;
@ -1037,13 +1037,25 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
for (auto& displayList : aDisplayLists) {
MOZ_ASSERT(displayList.mRenderRoot == wr::RenderRoot::Default ||
IsRootWebRenderBridgeParent());
if (!SetDisplayList(
displayList.mRenderRoot, displayList.mRect, displayList.mCommands,
displayList.mContentSize, std::move(displayList.mDL),
displayList.mDLDesc, displayList.mResourceUpdates,
displayList.mSmallShmems, displayList.mLargeShmems, aTxnStartTime,
txns[displayList.mRenderRoot], senders[displayList.mRenderRoot],
wrEpoch, validTransaction, observeLayersUpdate)) {
auto renderRoot = displayList.mRenderRoot;
auto& txn = txns[renderRoot];
txn.SetLowPriority(!IsRootWebRenderBridgeParent());
if (validTransaction) {
senders[renderRoot].emplace(Api(renderRoot), &txn);
}
if (NS_WARN_IF(!ProcessWebRenderParentCommands(displayList.mCommands, txn,
renderRoot))) {
return IPC_FAIL(this, "Invalid parent command found");
}
if (displayList.mDL &&
!SetDisplayList(renderRoot, displayList.mRect, displayList.mContentSize,
std::move(displayList.mDL.ref()), displayList.mDLDesc,
displayList.mResourceUpdates, displayList.mSmallShmems,
displayList.mLargeShmems, aTxnStartTime, txn, wrEpoch,
validTransaction, observeLayersUpdate)) {
return IPC_FAIL(this, "Failed call to SetDisplayList");
}
}

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

@ -296,17 +296,14 @@ class WebRenderBridgeParent final
}
bool SetDisplayList(wr::RenderRoot aRenderRoot, const gfx::IntRect& aRect,
const nsTArray<WebRenderParentCommand>& aCommands,
const wr::LayoutSize& aContentSize, ipc::ByteBuf&& aDL,
const wr::BuiltDisplayListDescriptor& aDLDesc,
const nsTArray<OpUpdateResource>& aResourceUpdates,
const nsTArray<RefCountedShmem>& aSmallShmems,
const nsTArray<ipc::Shmem>& aLargeShmems,
const TimeStamp& aTxnStartTime,
wr::TransactionBuilder& aTxn,
Maybe<wr::AutoTransactionSender>& aTxnSender,
wr::Epoch aWrEpoch, bool aValidTransaction,
bool aObserveLayersUpdate);
wr::TransactionBuilder& aTxn, wr::Epoch aWrEpoch,
bool aValidTransaction, bool aObserveLayersUpdate);
void UpdateAPZFocusState(const FocusTarget& aFocus);
void UpdateAPZScrollData(const wr::Epoch& aEpoch, WebRenderScrollData&& aData,

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

@ -238,7 +238,8 @@ bool WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags) {
for (auto& stateManager : mStateManagers) {
auto renderRoot = stateManager.GetRenderRoot();
if (stateManager.mAsyncResourceUpdates ||
!mPendingScrollUpdates[renderRoot].empty()) {
!mPendingScrollUpdates[renderRoot].empty() ||
WrBridge()->HasWebRenderParentCommands(renderRoot)) {
auto updates = renderRootUpdates.AppendElement();
updates->mRenderRoot = renderRoot;
if (stateManager.mAsyncResourceUpdates) {
@ -418,12 +419,15 @@ void WebRenderLayerManager::EndTransactionWithoutLayer(
auto renderRootDL = renderRootDLs.AppendElement();
renderRootDL->mRenderRoot = renderRoot;
builder.Finalize(*renderRootDL);
mLastDisplayListSizes[renderRoot] = renderRootDL->mDL.mCapacity;
mLastDisplayListSizes[renderRoot] = renderRootDL->mDL->mCapacity;
resourceUpdates.SubQueue(renderRoot)
.Flush(renderRootDL->mResourceUpdates, renderRootDL->mSmallShmems,
renderRootDL->mLargeShmems);
renderRootDL->mRect = RoundedToInt(rects[renderRoot]).ToUnknownRect();
renderRootDL->mScrollData = std::move(mScrollDatas[renderRoot]);
renderRootDL->mScrollData.emplace(std::move(mScrollDatas[renderRoot]));
} else if (WrBridge()->HasWebRenderParentCommands(renderRoot)) {
auto renderRootDL = renderRootDLs.AppendElement();
renderRootDL->mRenderRoot = renderRoot;
}
}

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

@ -730,8 +730,8 @@ void DisplayListBuilder::Finalize(
wr_api_finalize_builder(SubBuilder(aOutTransaction.mRenderRoot).mWrState,
&aOutTransaction.mContentSize,
&aOutTransaction.mDLDesc, &dl.inner);
aOutTransaction.mDL =
ipc::ByteBuf(dl.inner.data, dl.inner.length, dl.inner.capacity);
aOutTransaction.mDL.emplace(dl.inner.data, dl.inner.length,
dl.inner.capacity);
dl.inner.capacity = 0;
dl.inner.data = nullptr;
}