Backed out 3 changesets (bug 1547351) for assertion failures on a CLOSED TREE

Backed out changeset 77ef8e8bc669 (bug 1547351)
Backed out changeset b594f8e47025 (bug 1547351)
Backed out changeset 6e5d426cd313 (bug 1547351)
This commit is contained in:
Andreea Pavel 2019-07-15 17:47:40 +03:00
Родитель 9196c76343
Коммит 6665820f48
17 изменённых файлов: 241 добавлений и 635 удалений

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

@ -293,6 +293,7 @@ class BasePopup {
if (this.extension.remote) {
browser.setAttribute("remote", "true");
browser.setAttribute("remoteType", E10SUtils.EXTENSION_REMOTE_TYPE);
browser.setAttribute("renderroot", "content");
}
// We only need flex sizing for the sake of the slide-in sub-views of the

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

@ -12,7 +12,6 @@
#include "Units.h" // for CSSRect, CSSPixel, etc
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
#include "mozilla/HashFunctions.h" // for HashGeneric
#include "mozilla/HashTable.h" // for HashMap
#include "mozilla/Maybe.h"
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/Rect.h" // for RoundedIn
@ -1100,7 +1099,7 @@ struct ScrollMetadata {
// Please add new fields above this comment.
};
typedef HashMap<ScrollableLayerGuid::ViewID, ScrollUpdateInfo>
typedef std::map<ScrollableLayerGuid::ViewID, ScrollUpdateInfo>
ScrollUpdatesMap;
} // namespace layers

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

@ -2240,8 +2240,7 @@ bool LayerManager::SetPendingScrollUpdateForNextTransaction(
wr::RenderRoot renderRoot = (GetBackendType() == LayersBackend::LAYERS_WR)
? aRenderRoot
: wr::RenderRoot::Default;
bool ok = mPendingScrollUpdates[renderRoot].put(aScrollId, aUpdateInfo);
MOZ_RELEASE_ASSERT(ok);
mPendingScrollUpdates[renderRoot][aScrollId] = aUpdateInfo;
return true;
}
@ -2250,8 +2249,11 @@ Maybe<ScrollUpdateInfo> LayerManager::GetPendingScrollInfoUpdate(
// This never gets called for WebRenderLayerManager, so we assume that all
// pending scroll info updates are stored under the default RenderRoot.
MOZ_ASSERT(GetBackendType() != LayersBackend::LAYERS_WR);
auto p = mPendingScrollUpdates[wr::RenderRoot::Default].lookup(aScrollId);
return p ? Some(p->value()) : Nothing();
auto it = mPendingScrollUpdates[wr::RenderRoot::Default].find(aScrollId);
if (it != mPendingScrollUpdates[wr::RenderRoot::Default].end()) {
return Some(it->second);
}
return Nothing();
}
std::unordered_set<ScrollableLayerGuid::ViewID>
@ -2259,8 +2261,8 @@ LayerManager::ClearPendingScrollInfoUpdate() {
std::unordered_set<ScrollableLayerGuid::ViewID> scrollIds;
for (auto renderRoot : wr::kRenderRoots) {
auto& updates = mPendingScrollUpdates[renderRoot];
for (auto it = updates.iter(); !it.done(); it.next()) {
scrollIds.insert(it.get().key());
for (const auto& update : updates) {
scrollIds.insert(update.first);
}
updates.clear();
}

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

@ -204,24 +204,22 @@ void APZUpdater::UpdateScrollDataAndTreeState(
}
self->mEpochData[aOriginatingWrRootId].mRequired = aEpoch;
}));
RunOnUpdaterThread(
UpdaterQueueSelector(aOriginatingWrRootId),
NS_NewRunnableFunction(
"APZUpdater::UpdateHitTestingTree",
[=, aScrollData = std::move(aScrollData)]() mutable {
auto isFirstPaint = aScrollData.IsFirstPaint();
auto paintSequenceNumber = aScrollData.GetPaintSequenceNumber();
self->mScrollData[aOriginatingWrRootId] = std::move(aScrollData);
auto root = self->mScrollData.find(aRootLayerTreeId);
if (root == self->mScrollData.end()) {
return;
}
self->mApz->UpdateHitTestingTree(
WebRenderScrollDataWrapper(*self, aRootLayerTreeId,
&(root->second)),
isFirstPaint, aOriginatingWrRootId, paintSequenceNumber);
}));
RunOnUpdaterThread(UpdaterQueueSelector(aOriginatingWrRootId),
NS_NewRunnableFunction(
"APZUpdater::UpdateHitTestingTree",
[=, aScrollData = std::move(aScrollData)]() {
self->mScrollData[aOriginatingWrRootId] =
aScrollData;
auto root = self->mScrollData.find(aRootLayerTreeId);
if (root == self->mScrollData.end()) {
return;
}
self->mApz->UpdateHitTestingTree(
WebRenderScrollDataWrapper(
*self, aRootLayerTreeId, &(root->second)),
aScrollData.IsFirstPaint(), aOriginatingWrRootId,
aScrollData.GetPaintSequenceNumber());
}));
}
void APZUpdater::UpdateScrollOffsets(WRRootId aRootLayerTreeId,

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

@ -49,13 +49,14 @@ parent:
async DeleteCompositorAnimations(uint64_t[] aIds);
async SetDisplayList(RenderRootDisplayListData[] displayLists,
OpDestroy[] toDestroy, uint64_t fwdTransactionId, TransactionId transactionId,
bool containsSVGGroup,
IdNamespace aIdNamespace, bool containsSVGGroup,
VsyncId vsyncId, TimeStamp vsyncStartTime,
TimeStamp refreshStartTime, TimeStamp txnStartTime, nsCString txnURL, TimeStamp fwdTime,
CompositionPayload[] payloads);
async EmptyTransaction(FocusTarget focusTarget,
async EmptyTransaction(FocusTarget focusTarget, uint32_t aPaintSequenceNumber,
RenderRootUpdates[] renderRootUpdates,
OpDestroy[] toDestroy, uint64_t fwdTransactionId, TransactionId transactionId,
IdNamespace aIdNamespace,
VsyncId vsyncId, TimeStamp vsyncStartTime,
TimeStamp refreshStartTime, TimeStamp txnStartTime,
nsCString txnURL, TimeStamp fwdTime,

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

@ -14,13 +14,11 @@ namespace ipc {
void IPDLParamTraits<mozilla::layers::RenderRootDisplayListData>::Write(
IPC::Message* aMsg, IProtocol* aActor, paramType&& aParam) {
WriteIPDLParam(aMsg, aActor, aParam.mRenderRoot);
WriteIPDLParam(aMsg, aActor, aParam.mIdNamespace);
WriteIPDLParam(aMsg, aActor, aParam.mRect);
WriteIPDLParam(aMsg, aActor, aParam.mCommands);
WriteIPDLParam(aMsg, aActor, aParam.mContentSize);
WriteIPDLParam(aMsg, aActor, std::move(aParam.mDL));
WriteIPDLParam(aMsg, aActor, aParam.mDLDesc);
WriteIPDLParam(aMsg, aActor, aParam.mRemotePipelineIds);
WriteIPDLParam(aMsg, aActor, aParam.mResourceUpdates);
WriteIPDLParam(aMsg, aActor, aParam.mSmallShmems);
WriteIPDLParam(aMsg, aActor, std::move(aParam.mLargeShmems));
@ -31,13 +29,11 @@ bool IPDLParamTraits<mozilla::layers::RenderRootDisplayListData>::Read(
const IPC::Message* aMsg, PickleIterator* aIter, IProtocol* aActor,
paramType* aResult) {
if (ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRenderRoot) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mIdNamespace) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRect) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mCommands) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mContentSize) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDL) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mDLDesc) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRemotePipelineIds) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mResourceUpdates) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSmallShmems) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLargeShmems) &&
@ -55,7 +51,6 @@ void IPDLParamTraits<mozilla::layers::RenderRootUpdates>::Write(
WriteIPDLParam(aMsg, aActor, aParam.mSmallShmems);
WriteIPDLParam(aMsg, aActor, std::move(aParam.mLargeShmems));
WriteIPDLParam(aMsg, aActor, aParam.mScrollUpdates);
WriteIPDLParam(aMsg, aActor, aParam.mPaintSequenceNumber);
}
bool IPDLParamTraits<mozilla::layers::RenderRootUpdates>::Read(
@ -66,8 +61,7 @@ bool IPDLParamTraits<mozilla::layers::RenderRootUpdates>::Read(
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mResourceUpdates) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSmallShmems) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLargeShmems) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mScrollUpdates) &&
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mPaintSequenceNumber)) {
ReadIPDLParam(aMsg, aIter, aActor, &aResult->mScrollUpdates)) {
return true;
}
return false;

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

@ -11,7 +11,6 @@
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/layers/WebRenderMessages.h"
#include "mozilla/layers/WebRenderScrollData.h"
#include "mozilla/Variant.h"
namespace mozilla {
@ -19,13 +18,11 @@ namespace layers {
struct RenderRootDisplayListData {
wr::RenderRoot mRenderRoot;
wr::IdNamespace mIdNamespace;
LayoutDeviceRect mRect;
nsTArray<WebRenderParentCommand> mCommands;
wr::LayoutSize mContentSize;
Maybe<mozilla::ipc::ByteBuf> mDL;
wr::BuiltDisplayListDescriptor mDLDesc;
nsTArray<wr::PipelineId> mRemotePipelineIds;
nsTArray<OpUpdateResource> mResourceUpdates;
nsTArray<RefCountedShmem> mSmallShmems;
nsTArray<mozilla::ipc::Shmem> mLargeShmems;
@ -39,19 +36,8 @@ struct RenderRootUpdates {
nsTArray<RefCountedShmem> mSmallShmems;
nsTArray<mozilla::ipc::Shmem> mLargeShmems;
ScrollUpdatesMap mScrollUpdates;
uint32_t mPaintSequenceNumber;
};
struct ResourceUpdates {
nsTArray<OpUpdateResource> mResourceUpdates;
nsTArray<RefCountedShmem> mSmallShmems;
nsTArray<mozilla::ipc::Shmem> mLargeShmems;
};
typedef Variant<RenderRootDisplayListData, RenderRootUpdates, ResourceUpdates,
FocusTarget>
RenderRootDeferredData;
} // namespace layers
namespace ipc {

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

@ -122,7 +122,6 @@ void WebRenderBridgeChild::EndTransaction(
(XRE_IsParentProcess() &&
StaticPrefs::gfx_webrender_split_render_roots()));
renderRoot.mCommands = std::move(mParentCommands[renderRoot.mRenderRoot]);
renderRoot.mIdNamespace = mIdNamespace;
}
nsTArray<CompositionPayload> payloads;
@ -130,10 +129,11 @@ void WebRenderBridgeChild::EndTransaction(
mManager->TakeCompositionPayloads(payloads);
}
this->SendSetDisplayList(
std::move(aRenderRoots), mDestroyedActors, GetFwdTransactionId(),
aTransactionId, aContainsSVGGroup, aVsyncId, aVsyncStartTime,
aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime, payloads);
this->SendSetDisplayList(std::move(aRenderRoots), mDestroyedActors,
GetFwdTransactionId(), aTransactionId, mIdNamespace,
aContainsSVGGroup, aVsyncId, aVsyncStartTime,
aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime,
payloads);
// With multiple render roots, we may not have sent all of our
// mParentCommands, so go ahead and go through our mParentCommands and ensure
@ -146,8 +146,8 @@ void WebRenderBridgeChild::EndTransaction(
void WebRenderBridgeChild::EndEmptyTransaction(
const FocusTarget& aFocusTarget,
nsTArray<RenderRootUpdates>& aRenderRootUpdates,
TransactionId aTransactionId, const mozilla::VsyncId& aVsyncId,
const mozilla::TimeStamp& aVsyncStartTime,
uint32_t aPaintSequenceNumber, TransactionId aTransactionId,
const mozilla::VsyncId& aVsyncId, const mozilla::TimeStamp& aVsyncStartTime,
const mozilla::TimeStamp& aRefreshStartTime,
const mozilla::TimeStamp& aTxnStartTime, const nsCString& aTxnURL) {
MOZ_ASSERT(!mDestroyed);
@ -168,9 +168,10 @@ void WebRenderBridgeChild::EndEmptyTransaction(
}
this->SendEmptyTransaction(
aFocusTarget, std::move(aRenderRootUpdates), mDestroyedActors,
GetFwdTransactionId(), aTransactionId, aVsyncId, aVsyncStartTime,
aRefreshStartTime, aTxnStartTime, aTxnURL, fwdTime, payloads);
aFocusTarget, aPaintSequenceNumber, std::move(aRenderRootUpdates),
mDestroyedActors, GetFwdTransactionId(), aTransactionId, mIdNamespace,
aVsyncId, aVsyncStartTime, aRefreshStartTime, aTxnStartTime, aTxnURL,
fwdTime, payloads);
// With multiple render roots, we may not have sent all of our
// mParentCommands, so go ahead and go through our mParentCommands and ensure

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

@ -82,6 +82,7 @@ class WebRenderBridgeChild final : public PWebRenderBridgeChild,
const nsCString& aTxtURL);
void EndEmptyTransaction(const FocusTarget& aFocusTarget,
nsTArray<RenderRootUpdates>& aRenderRootUpdates,
uint32_t aPaintSequenceNumber,
TransactionId aTransactionId,
const mozilla::VsyncId& aVsyncId,
const mozilla::TimeStamp& aVsyncStartTime,

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

@ -306,6 +306,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(
mWrEpoch{0},
mIdNamespace(aApis[0]->GetNamespace()),
mRenderRootRectMutex("WebRenderBridgeParent::mRenderRootRectMutex"),
mRenderRoot(wr::RenderRoot::Default),
mPaused(false),
mDestroyed(false),
mReceivedDisplayList(false),
@ -319,9 +320,9 @@ WebRenderBridgeParent::WebRenderBridgeParent(
mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
}
if (IsRootWebRenderBridgeParent() ||
!StaticPrefs::gfx_webrender_split_render_roots()) {
mRenderRoot = Some(wr::RenderRoot::Default);
if (!IsRootWebRenderBridgeParent() &&
StaticPrefs::gfx_webrender_split_render_roots()) {
mRenderRoot = wr::RenderRoot::Content;
}
for (auto& api : aApis) {
@ -338,204 +339,19 @@ WebRenderBridgeParent::WebRenderBridgeParent(const wr::PipelineId& aPipelineId)
mWrEpoch{0},
mIdNamespace{0},
mRenderRootRectMutex("WebRenderBridgeParent::mRenderRootRectMutex"),
mRenderRoot(wr::RenderRoot::Default),
mPaused(false),
mDestroyed(true),
mReceivedDisplayList(false),
mIsFirstPaint(false),
mSkippedComposite(false) {}
WebRenderBridgeParent::~WebRenderBridgeParent() {
if (RefPtr<WebRenderBridgeParent> root = GetRootWebRenderBridgeParent()) {
root->RemoveDeferredPipeline(mPipelineId);
}
}
bool WebRenderBridgeParent::RenderRootIsValid(wr::RenderRoot aRenderRoot) {
if (StaticPrefs::gfx_webrender_split_render_roots() &&
IsRootWebRenderBridgeParent()) {
return aRenderRoot <= wr::kHighestRenderRoot;
} else {
return aRenderRoot == wr::RenderRoot::Default;
}
}
void WebRenderBridgeParent::RemoveDeferredPipeline(wr::PipelineId aPipelineId) {
MOZ_ASSERT(IsRootWebRenderBridgeParent());
mPipelineRenderRoots.remove(wr::AsUint64(aPipelineId));
if (auto p = mPipelineDeferredUpdates.lookup(wr::AsUint64(aPipelineId))) {
RefPtr<WebRenderBridgeParent> self = this;
for (auto& variant : p->value()) {
variant.match(
[=](RenderRootDisplayListData& x) {
wr::IpcResourceUpdateQueue::ReleaseShmems(self, x.mSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(self, x.mLargeShmems);
},
[=](RenderRootUpdates& x) {
wr::IpcResourceUpdateQueue::ReleaseShmems(self, x.mSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(self, x.mLargeShmems);
},
[=](ResourceUpdates& x) {
wr::IpcResourceUpdateQueue::ReleaseShmems(self, x.mSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(self, x.mLargeShmems);
},
[=](FocusTarget& x) {});
}
mPipelineDeferredUpdates.remove(p);
}
}
/* static */
WebRenderBridgeParent* WebRenderBridgeParent::CreateDestroyed(
const wr::PipelineId& aPipelineId) {
return new WebRenderBridgeParent(aPipelineId);
}
void WebRenderBridgeParent::PushDeferredPipelineData(
RenderRootDeferredData&& aDeferredData) {
MOZ_ASSERT(!IsRootWebRenderBridgeParent());
if (RefPtr<WebRenderBridgeParent> root = GetRootWebRenderBridgeParent()) {
uint64_t key = wr::AsUint64(mPipelineId);
auto p = root->mPipelineDeferredUpdates.lookupForAdd(key);
if (!p) {
bool added = root->mPipelineDeferredUpdates.add(
p, key, nsTArray<RenderRootDeferredData>());
if (NS_WARN_IF(!added)) {
return;
}
}
p->value().AppendElement(std::move(aDeferredData));
}
}
bool WebRenderBridgeParent::HandleDeferredPipelineData(
nsTArray<RenderRootDeferredData>& aDeferredData,
const TimeStamp& aTxnStartTime) {
MOZ_ASSERT(!IsRootWebRenderBridgeParent());
for (auto& entry : aDeferredData) {
bool success = entry.match(
[&](RenderRootDisplayListData& data) {
// We ensure this with RenderRootIsValid before calling
// PushDeferredPipelineData:
MOZ_ASSERT(data.mRenderRoot == wr::RenderRoot::Default);
wr::Epoch wrEpoch = GetNextWrEpoch();
bool validTransaction = data.mIdNamespace == mIdNamespace;
if (!ProcessRenderRootDisplayListData(data,
wrEpoch,
aTxnStartTime,
validTransaction,
false)){
return false;
}
wr::IpcResourceUpdateQueue::ReleaseShmems(this, data.mSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, data.mLargeShmems);
return true;
},
[&](RenderRootUpdates& data) {
// We ensure this with RenderRootIsValid before calling
// PushDeferredPipelineData:
MOZ_ASSERT(data.mRenderRoot == wr::RenderRoot::Default);
bool scheduleComposite;
if (!ProcessEmptyTransactionUpdates(data, &scheduleComposite)) {
return false;
}
if (scheduleComposite) {
ScheduleGenerateFrame(Nothing());
}
wr::IpcResourceUpdateQueue::ReleaseShmems(this, data.mSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, data.mLargeShmems);
return true;
},
[&](ResourceUpdates& data) {
wr::TransactionBuilder txn;
txn.SetLowPriority(!IsRootWebRenderBridgeParent());
if (!UpdateResources(data.mResourceUpdates, data.mSmallShmems,
data.mLargeShmems, txn)) {
return false;
}
Api(wr::RenderRoot::Default)->SendTransaction(txn);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, data.mSmallShmems);
wr::IpcResourceUpdateQueue::ReleaseShmems(this, data.mLargeShmems);
return true;
},
[&](FocusTarget& data) {
UpdateAPZFocusState(data);
return true;
});
if (!success) {
return false;
}
}
aDeferredData.Clear();
return true;
}
bool WebRenderBridgeParent::MaybeHandleDeferredPipelineDataForPipeline(
wr::RenderRoot aRenderRoot, wr::PipelineId aPipelineId,
const TimeStamp& aTxnStartTime) {
MOZ_ASSERT(IsRootWebRenderBridgeParent());
uint64_t key = wr::AsUint64(aPipelineId);
auto p = mPipelineRenderRoots.lookupForAdd(key);
if (!p) {
if (!mPipelineRenderRoots.add(p, key, aRenderRoot)) {
return false;
}
CompositorBridgeParent::LayerTreeState* lts =
CompositorBridgeParent::GetIndirectShadowTree(
wr::AsLayersId(aPipelineId));
if (!lts) {
return true;
}
RefPtr<WebRenderBridgeParent> wrbp = lts->mWrBridge;
if (!wrbp) {
return true;
}
MOZ_ASSERT(wrbp->mRenderRoot.refOr(aRenderRoot) == aRenderRoot);
wrbp->mRenderRoot = Some(aRenderRoot);
if (auto p = mPipelineDeferredUpdates.lookup(key)) {
wrbp->HandleDeferredPipelineData(p->value(), aTxnStartTime);
mPipelineDeferredUpdates.remove(p);
for (auto iter = wrbp->mChildPipelines.iter(); !iter.done(); iter.next()) {
if (!MaybeHandleDeferredPipelineDataForPipeline(
aRenderRoot,
wr::AsPipelineId(iter.get()),
aTxnStartTime)) {
return false;
}
}
}
}
return true;
}
bool WebRenderBridgeParent::MaybeHandleDeferredPipelineData(
wr::RenderRoot aRenderRoot, const nsTArray<wr::PipelineId>& aPipelineIds,
const TimeStamp& aTxnStartTime) {
MOZ_ASSERT(IsRootWebRenderBridgeParent());
if (!StaticPrefs::gfx_webrender_split_render_roots()) {
return true;
}
for (wr::PipelineId pipelineId : aPipelineIds) {
if (!MaybeHandleDeferredPipelineDataForPipeline(aRenderRoot, pipelineId,
aTxnStartTime)) {
return false;
}
}
return true;
}
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvEnsureConnected(
TextureFactoryIdentifier* aTextureFactoryIdentifier,
MaybeIdNamespace* aMaybeIdNamespace) {
@ -550,17 +366,6 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvEnsureConnected(
*aTextureFactoryIdentifier = GetTextureFactoryIdentifier();
*aMaybeIdNamespace = Some(mIdNamespace);
if (!mRenderRoot) {
RefPtr<WebRenderBridgeParent> root = GetRootWebRenderBridgeParent();
if (!root) {
return IPC_FAIL(this, "Root WRBP is missing (shutting down?)");
}
auto p = root->mPipelineRenderRoots.lookup(wr::AsUint64(mPipelineId));
if (p) {
mRenderRoot.emplace(p->value());
}
}
return IPC_OK();
}
@ -931,18 +736,7 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvUpdateResources(
return IPC_OK();
}
if (!RenderRootIsValid(aRenderRoot)) {
return IPC_FAIL(this, "Received an invalid renderRoot");
}
if (!mRenderRoot) {
PushDeferredPipelineData(AsVariant(ResourceUpdates{
std::move(aResourceUpdates),
std::move(aSmallShmems),
std::move(aLargeShmems),
}));
return IPC_OK();
}
MOZ_RELEASE_ASSERT(aRenderRoot <= wr::kHighestRenderRoot);
wr::TransactionBuilder txn;
txn.SetLowPriority(!IsRootWebRenderBridgeParent());
@ -1038,18 +832,13 @@ WebRenderBridgeParent::GetRootWebRenderBridgeParent() const {
}
void WebRenderBridgeParent::UpdateAPZFocusState(const FocusTarget& aFocus) {
if (!mRenderRoot) {
PushDeferredPipelineData(AsVariant(aFocus));
return;
}
CompositorBridgeParent* cbp = GetRootCompositorBridgeParent();
if (!cbp) {
return;
}
LayersId rootLayersId = cbp->RootLayerTreeId();
if (RefPtr<APZUpdater> apz = cbp->GetAPZUpdater()) {
apz->UpdateFocusState(rootLayersId, WRRootId(GetLayersId(), *mRenderRoot),
apz->UpdateFocusState(rootLayersId, WRRootId(GetLayersId(), mRenderRoot),
aFocus);
}
}
@ -1173,57 +962,14 @@ bool WebRenderBridgeParent::SetDisplayList(
return true;
}
bool WebRenderBridgeParent::ProcessRenderRootDisplayListData(
RenderRootDisplayListData& aDisplayList,
wr::Epoch aWrEpoch,
const TimeStamp& aTxnStartTime,
bool aValidTransaction,
bool aObserveLayersUpdate) {
wr::TransactionBuilder txn;
Maybe<wr::AutoTransactionSender> sender;
// Note that this needs to happen before the display list transaction is
// sent to WebRender, so that the UpdateHitTestingTree call is guaranteed to
// be in the updater queue at the time that the scene swap completes.
if (aDisplayList.mScrollData) {
UpdateAPZScrollData(aWrEpoch, std::move(aDisplayList.mScrollData.ref()),
aDisplayList.mRenderRoot);
}
MOZ_ASSERT(aDisplayList.mRenderRoot == wr::RenderRoot::Default ||
IsRootWebRenderBridgeParent());
auto renderRoot = aDisplayList.mRenderRoot;
txn.SetLowPriority(!IsRootWebRenderBridgeParent());
if (aValidTransaction) {
MOZ_ASSERT(aDisplayList.mIdNamespace == mIdNamespace);
sender.emplace(Api(renderRoot), &txn);
}
if (NS_WARN_IF(!ProcessWebRenderParentCommands(aDisplayList.mCommands, txn,
renderRoot))) {
return false;
}
if (aDisplayList.mDL &&
!SetDisplayList(renderRoot, aDisplayList.mRect, aDisplayList.mContentSize,
std::move(aDisplayList.mDL.ref()), aDisplayList.mDLDesc,
aDisplayList.mResourceUpdates, aDisplayList.mSmallShmems,
aDisplayList.mLargeShmems, aTxnStartTime, txn, aWrEpoch,
aValidTransaction, aObserveLayersUpdate)) {
return false;
}
return true;
}
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
nsTArray<RenderRootDisplayListData>&& aDisplayLists,
nsTArray<OpDestroy>&& aToDestroy, const uint64_t& aFwdTransactionId,
const TransactionId& aTransactionId, const bool& aContainsSVGGroup,
const VsyncId& aVsyncId, const TimeStamp& aVsyncStartTime,
const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
const nsCString& aTxnURL, const TimeStamp& aFwdTime,
nsTArray<CompositionPayload>&& aPayloads) {
const TransactionId& aTransactionId, const wr::IdNamespace& aIdNamespace,
const bool& aContainsSVGGroup, const VsyncId& aVsyncId,
const TimeStamp& aVsyncStartTime, const TimeStamp& aRefreshStartTime,
const TimeStamp& aTxnStartTime, const nsCString& aTxnURL,
const TimeStamp& aFwdTime, nsTArray<CompositionPayload>&& aPayloads) {
if (mDestroyed) {
for (const auto& op : aToDestroy) {
DestroyActor(op);
@ -1232,13 +978,9 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
}
// Guard against malicious content processes
if (aDisplayLists.Length() == 0) {
return IPC_FAIL(this, "Must send at least one RenderRootDisplayListData.");
}
MOZ_RELEASE_ASSERT(aDisplayLists.Length() > 0);
for (auto& displayList : aDisplayLists) {
if (!RenderRootIsValid(displayList.mRenderRoot)) {
return IPC_FAIL(this, "Received an invalid renderRoot");
}
MOZ_RELEASE_ASSERT(displayList.mRenderRoot <= wr::kHighestRenderRoot);
}
if (!IsRootWebRenderBridgeParent()) {
@ -1258,6 +1000,7 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
mReceivedDisplayList = true;
bool observeLayersUpdate = ShouldParentObserveEpoch();
// The IsFirstPaint() flag should be the same for all the non-empty
// scrolldata across all the renderroot display lists in a given
@ -1273,7 +1016,7 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
mIsFirstPaint = true;
}
} else {
auto& firstNonEmpty = aDisplayLists[*firstScrollDataIndex].mScrollData;
auto firstNonEmpty = aDisplayLists[*firstScrollDataIndex].mScrollData;
// Ensure the flag is the same on all of them.
MOZ_RELEASE_ASSERT(scrollData->IsFirstPaint() ==
firstNonEmpty->IsFirstPaint());
@ -1281,52 +1024,47 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
}
}
if (!mRenderRoot) {
// Only non-root WRBPs will ever have an unresolved mRenderRoot
MOZ_ASSERT(!IsRootWebRenderBridgeParent());
if (aDisplayLists.Length() != 1) {
return IPC_FAIL(this, "Well-behaved content processes must only send a DL for a single renderRoot");
}
PushDeferredPipelineData(AsVariant(std::move(aDisplayLists[0])));
aDisplayLists.Clear();
}
// 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
// destination.
// Also note that this needs to happen before the display list transaction is
// 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) {
if (IsRootWebRenderBridgeParent()) {
if (!MaybeHandleDeferredPipelineData(
displayList.mRenderRoot,
displayList.mRemotePipelineIds,
aTxnStartTime)) {
return IPC_FAIL(this, "Failed processing deferred pipeline data");
}
} else {
RefPtr<WebRenderBridgeParent> root = GetRootWebRenderBridgeParent();
if (!root) {
return IPC_FAIL(this, "Root WRBP is missing (shutting down?)");
}
for (auto pipelineId : displayList.mRemotePipelineIds) {
auto id = wr::AsUint64(pipelineId);
if (!root->mPipelineRenderRoots.put(id, *mRenderRoot) ||
!mChildPipelines.put(id)) {
return IPC_FAIL(this, "Failed to add child pipeline id.");
}
}
if (displayList.mScrollData) {
UpdateAPZScrollData(wrEpoch, std::move(displayList.mScrollData.ref()),
displayList.mRenderRoot);
}
}
bool validTransaction = aDisplayLists.Length() > 0 &&
aDisplayLists[0].mIdNamespace == mIdNamespace;
bool observeLayersUpdate = ShouldParentObserveEpoch();
bool validTransaction = aIdNamespace == mIdNamespace;
wr::RenderRootArray<wr::TransactionBuilder> txns;
wr::RenderRootArray<Maybe<wr::AutoTransactionSender>> senders;
for (auto& displayList : aDisplayLists) {
if (!ProcessRenderRootDisplayListData(
displayList,
wrEpoch,
aTxnStartTime,
validTransaction,
observeLayersUpdate)) {
return IPC_FAIL(this, "Failed to process RenderRootDisplayListData.");
MOZ_ASSERT(displayList.mRenderRoot == wr::RenderRoot::Default ||
IsRootWebRenderBridgeParent());
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");
}
}
@ -1364,79 +1102,15 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
return IPC_OK();
}
bool WebRenderBridgeParent::ProcessEmptyTransactionUpdates(
RenderRootUpdates& aUpdates, bool* aScheduleComposite) {
*aScheduleComposite = false;
wr::TransactionBuilder txn;
txn.SetLowPriority(!IsRootWebRenderBridgeParent());
MOZ_ASSERT(aUpdates.mRenderRoot == wr::RenderRoot::Default ||
IsRootWebRenderBridgeParent());
if (!aUpdates.mScrollUpdates.empty()) {
UpdateAPZScrollOffsets(std::move(aUpdates.mScrollUpdates),
aUpdates.mPaintSequenceNumber, aUpdates.mRenderRoot);
}
// Update WrEpoch for UpdateResources() and ProcessWebRenderParentCommands().
// WrEpoch is used to manage ExternalImages lifetimes in
// AsyncImagePipelineManager.
Unused << GetNextWrEpoch();
if (!UpdateResources(aUpdates.mResourceUpdates, aUpdates.mSmallShmems,
aUpdates.mLargeShmems, txn)) {
return false;
}
if (!aUpdates.mCommands.IsEmpty()) {
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
if (!ProcessWebRenderParentCommands(aUpdates.mCommands, txn,
aUpdates.mRenderRoot)) {
return false;
}
}
if (ShouldParentObserveEpoch()) {
txn.Notify(
wr::Checkpoint::SceneBuilt,
MakeUnique<ScheduleObserveLayersUpdate>(
mCompositorBridge, GetLayersId(), mChildLayersObserverEpoch, true));
}
// Even when txn.IsResourceUpdatesEmpty() is true, there could be resource
// updates. It is handled by WebRenderTextureHostWrapper. In this case
// txn.IsRenderedFrameInvalidated() becomes true.
if (!txn.IsResourceUpdatesEmpty() || txn.IsRenderedFrameInvalidated()) {
// There are resource updates, then we update Epoch of transaction.
txn.UpdateEpoch(mPipelineId, mWrEpoch);
*aScheduleComposite = true;
} else {
// If TransactionBuilder does not have resource updates nor display list,
// ScheduleGenerateFrame is not triggered via SceneBuilder and there is no
// need to update WrEpoch.
// Then we want to rollback WrEpoch. See Bug 1490117.
RollbackWrEpoch();
}
if (!txn.IsEmpty()) {
Api(aUpdates.mRenderRoot)->SendTransaction(txn);
}
if (*aScheduleComposite) {
mAsyncImageManager->SetWillGenerateFrame(aUpdates.mRenderRoot);
}
return true;
}
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvEmptyTransaction(
const FocusTarget& aFocusTarget,
const FocusTarget& aFocusTarget, const uint32_t& aPaintSequenceNumber,
nsTArray<RenderRootUpdates>&& aRenderRootUpdates,
nsTArray<OpDestroy>&& aToDestroy, const uint64_t& aFwdTransactionId,
const TransactionId& aTransactionId, const VsyncId& aVsyncId,
const TimeStamp& aVsyncStartTime, const TimeStamp& aRefreshStartTime,
const TimeStamp& aTxnStartTime, const nsCString& aTxnURL,
const TimeStamp& aFwdTime, nsTArray<CompositionPayload>&& aPayloads) {
const TransactionId& aTransactionId, const wr::IdNamespace& aIdNamespace,
const VsyncId& aVsyncId, const TimeStamp& aVsyncStartTime,
const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
const nsCString& aTxnURL, const TimeStamp& aFwdTime,
nsTArray<CompositionPayload>&& aPayloads) {
if (mDestroyed) {
for (const auto& op : aToDestroy) {
DestroyActor(op);
@ -1446,9 +1120,7 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvEmptyTransaction(
// Guard against malicious content processes
for (auto& update : aRenderRootUpdates) {
if (!RenderRootIsValid(update.mRenderRoot)) {
return IPC_FAIL(this, "Received an invalid renderRoot");
}
MOZ_RELEASE_ASSERT(update.mRenderRoot <= wr::kHighestRenderRoot);
}
if (!IsRootWebRenderBridgeParent()) {
@ -1463,29 +1135,89 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvEmptyTransaction(
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(
this, &aToDestroy);
if (!mRenderRoot && aRenderRootUpdates.Length() > 0) {
// Only non-root WRBPs will ever have an unresolved mRenderRoot
MOZ_ASSERT(!IsRootWebRenderBridgeParent());
if (aRenderRootUpdates.Length() != 1) {
return IPC_FAIL(this, "Well-behaved content processes must only send a DL for a single renderRoot");
}
PushDeferredPipelineData(AsVariant(std::move(aRenderRootUpdates[0])));
aRenderRootUpdates.Clear();
}
wr::RenderRootArray<bool> scheduleComposite;
UpdateAPZFocusState(aFocusTarget);
bool scheduleAnyComposite = false;
wr::RenderRootArray<Maybe<wr::TransactionBuilder>> txns;
for (auto& update : aRenderRootUpdates) {
MOZ_ASSERT(update.mRenderRoot == wr::RenderRoot::Default ||
IsRootWebRenderBridgeParent());
bool scheduleComposite = false;
if (!ProcessEmptyTransactionUpdates(update, &scheduleComposite)) {
return IPC_FAIL(this, "Failed to process empty transaction update.");
if (!update.mScrollUpdates.empty()) {
UpdateAPZScrollOffsets(std::move(update.mScrollUpdates),
aPaintSequenceNumber, update.mRenderRoot);
}
txns[update.mRenderRoot].emplace();
txns[update.mRenderRoot]->SetLowPriority(!IsRootWebRenderBridgeParent());
}
// Update WrEpoch for UpdateResources() and ProcessWebRenderParentCommands().
// WrEpoch is used to manage ExternalImages lifetimes in
// AsyncImagePipelineManager.
Unused << GetNextWrEpoch();
for (auto& update : aRenderRootUpdates) {
if (!UpdateResources(update.mResourceUpdates, update.mSmallShmems,
update.mLargeShmems, *txns[update.mRenderRoot])) {
return IPC_FAIL(this, "Failed to deserialize resource updates");
}
}
bool compositionTimeSet = false;
for (auto& update : aRenderRootUpdates) {
if (!update.mCommands.IsEmpty()) {
if (!compositionTimeSet) {
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
compositionTimeSet = true;
}
if (!ProcessWebRenderParentCommands(update.mCommands,
*txns[update.mRenderRoot],
update.mRenderRoot)) {
return IPC_FAIL(this, "Invalid parent command found");
}
}
if (ShouldParentObserveEpoch()) {
txns[update.mRenderRoot]->Notify(wr::Checkpoint::SceneBuilt,
MakeUnique<ScheduleObserveLayersUpdate>(
mCompositorBridge, GetLayersId(),
mChildLayersObserverEpoch, true));
}
}
bool rollbackEpoch = true;
for (auto& update : aRenderRootUpdates) {
auto& txn = *txns[update.mRenderRoot];
// Even when txn.IsResourceUpdatesEmpty() is true, there could be resource
// updates. It is handled by WebRenderTextureHostWrapper. In this case
// txn.IsRenderedFrameInvalidated() becomes true.
if (!txn.IsResourceUpdatesEmpty() || txn.IsRenderedFrameInvalidated()) {
// There are resource updates, then we update Epoch of transaction.
txn.UpdateEpoch(mPipelineId, mWrEpoch);
scheduleComposite[update.mRenderRoot] = true;
rollbackEpoch = false;
}
}
if (rollbackEpoch) {
// If TransactionBuilder does not have resource updates nor display list,
// ScheduleGenerateFrame is not triggered via SceneBuilder and there is no
// need to update WrEpoch.
// Then we want to rollback WrEpoch. See Bug 1490117.
RollbackWrEpoch();
}
bool scheduleAnyComposite = false;
for (auto renderRoot : wr::kRenderRoots) {
if (txns[renderRoot] && !txns[renderRoot]->IsEmpty()) {
Api(renderRoot)->SendTransaction(*txns[renderRoot]);
}
if (scheduleComposite[renderRoot]) {
scheduleAnyComposite = true;
}
scheduleAnyComposite = scheduleAnyComposite || scheduleComposite;
}
// If we are going to kick off a new composite as a result of this
@ -1506,6 +1238,12 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvEmptyTransaction(
/* aIsFirstPaint */ false, std::move(aPayloads),
/* aUseForTelemetry */ scheduleAnyComposite);
for (auto renderRoot : wr::kRenderRoots) {
if (scheduleComposite[renderRoot]) {
mAsyncImageManager->SetWillGenerateFrame(renderRoot);
}
}
if (scheduleAnyComposite) {
ScheduleGenerateFrame(Nothing());
} else if (sendDidComposite) {
@ -1642,7 +1380,7 @@ void WebRenderBridgeParent::FlushSceneBuilds() {
// to block until all the inflight transactions have been processed. This
// flush message blocks until all previously sent scenes have been built
// and received by the render backend thread.
mApis[wr::RenderRoot::Default]->FlushSceneBuilder();
Api(wr::RenderRoot::Default)->FlushSceneBuilder();
// The post-swap hook for async-scene-building calls the
// ScheduleRenderOnCompositorThread function from the scene builder thread,
// which then triggers a call to ScheduleGenerateFrame() on the compositor
@ -1682,7 +1420,7 @@ void WebRenderBridgeParent::FlushFramePresentation() {
// this effectively blocks on the render backend and renderer threads,
// following the same codepath that WebRender takes to render and composite
// a frame.
mApis[wr::RenderRoot::Default]->WaitFlushed();
Api(wr::RenderRoot::Default)->WaitFlushed();
}
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvGetSnapshot(
@ -1737,9 +1475,9 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvGetSnapshot(
FlushSceneBuilds();
FlushFrameGeneration();
mApis[wr::RenderRoot::Default]->Readback(start, size,
bufferTexture->GetFormat(),
Range<uint8_t>(buffer, buffer_size));
Api(wr::RenderRoot::Default)
->Readback(start, size, bufferTexture->GetFormat(),
Range<uint8_t>(buffer, buffer_size));
return IPC_OK();
}
@ -1875,22 +1613,16 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvClearCachedResources() {
if (renderRoot == wr::RenderRoot::Default ||
(IsRootWebRenderBridgeParent() &&
StaticPrefs::gfx_webrender_split_render_roots())) {
if (mRenderRoot) {
// Clear resources
wr::TransactionBuilder txn;
txn.SetLowPriority(true);
txn.ClearDisplayList(GetNextWrEpoch(), mPipelineId);
txn.Notify(wr::Checkpoint::SceneBuilt,
MakeUnique<ScheduleObserveLayersUpdate>(
mCompositorBridge, GetLayersId(),
mChildLayersObserverEpoch, false));
Api(renderRoot)->SendTransaction(txn);
} else {
if (RefPtr<WebRenderBridgeParent> root =
GetRootWebRenderBridgeParent()) {
root->RemoveDeferredPipeline(mPipelineId);
}
}
// Clear resources
wr::TransactionBuilder txn;
txn.SetLowPriority(true);
txn.ClearDisplayList(GetNextWrEpoch(), mPipelineId);
txn.Notify(wr::Checkpoint::SceneBuilt,
MakeUnique<ScheduleObserveLayersUpdate>(
mCompositorBridge, GetLayersId(),
mChildLayersObserverEpoch, false));
Api(renderRoot)->SendTransaction(txn);
}
}
// Schedule generate frame to clean up Pipeline
@ -1980,7 +1712,7 @@ void WebRenderBridgeParent::ScheduleForcedGenerateFrame() {
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvCapture() {
if (!mDestroyed) {
mApis[wr::RenderRoot::Default]->Capture();
Api(wr::RenderRoot::Default)->Capture();
}
return IPC_OK();
}
@ -2068,7 +1800,7 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetAsyncScrollOffset(
return IPC_OK();
}
mCompositorBridge->SetTestAsyncScrollOffset(
WRRootId(GetLayersId(), *mRenderRoot), aScrollId, CSSPoint(aX, aY));
WRRootId(GetLayersId(), mRenderRoot), aScrollId, CSSPoint(aX, aY));
return IPC_OK();
}
@ -2077,7 +1809,7 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetAsyncZoom(
if (mDestroyed) {
return IPC_OK();
}
mCompositorBridge->SetTestAsyncZoom(WRRootId(GetLayersId(), *mRenderRoot),
mCompositorBridge->SetTestAsyncZoom(WRRootId(GetLayersId(), mRenderRoot),
aScrollId,
LayerToParentLayerScale(aZoom));
return IPC_OK();
@ -2087,13 +1819,13 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvFlushApzRepaints() {
if (mDestroyed) {
return IPC_OK();
}
mCompositorBridge->FlushApzRepaints(WRRootId(GetLayersId(), *mRenderRoot));
mCompositorBridge->FlushApzRepaints(WRRootId(GetLayersId(), mRenderRoot));
return IPC_OK();
}
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvGetAPZTestData(
APZTestData* aOutData) {
mCompositorBridge->GetAPZTestData(WRRootId(GetLayersId(), *mRenderRoot),
mCompositorBridge->GetAPZTestData(WRRootId(GetLayersId(), mRenderRoot),
aOutData);
return IPC_OK();
}
@ -2177,7 +1909,7 @@ void WebRenderBridgeParent::CompositeToTarget(VsyncId aId,
}
if (mSkippedComposite || wr::RenderThread::Get()->TooManyPendingFrames(
mApis[wr::RenderRoot::Default]->GetId())) {
Api(wr::RenderRoot::Default)->GetId())) {
// Render thread is busy, try next time.
mSkippedComposite = true;
mSkippedCompositeId = aId;
@ -2284,11 +2016,11 @@ void WebRenderBridgeParent::MaybeGenerateFrame(VsyncId aId,
SetAPZSampleTime();
wr::RenderThread::Get()->IncPendingFrameCount(
mApis[wr::RenderRoot::Default]->GetId(), aId, start, framesGenerated);
Api(wr::RenderRoot::Default)->GetId(), aId, start, framesGenerated);
#if defined(ENABLE_FRAME_LATENCY_LOG)
auto startTime = TimeStamp::Now();
mApis[wr::RenderRoot::Default]->SetFrameStartTime(startTime);
Api(wr::RenderRoot::Default)->SetFrameStartTime(startTime);
#endif
MOZ_ASSERT(framesGenerated > 0);
@ -2438,7 +2170,7 @@ TransactionId WebRenderBridgeParent::FlushTransactionIdsForEpoch(
transactionId.mSkippedComposites, transactionId.mTxnURL));
wr::RenderThread::Get()->NotifySlowFrame(
mApis[wr::RenderRoot::Default]->GetId());
Api(wr::RenderRoot::Default)->GetId());
}
}
@ -2528,7 +2260,7 @@ void WebRenderBridgeParent::Pause() {
return;
}
mApis[wr::RenderRoot::Default]->Pause();
Api(wr::RenderRoot::Default)->Pause();
#endif
mPaused = true;
}
@ -2540,7 +2272,7 @@ bool WebRenderBridgeParent::Resume() {
return false;
}
if (!mApis[wr::RenderRoot::Default]->Resume()) {
if (!Api(wr::RenderRoot::Default)->Resume()) {
return false;
}
#endif
@ -2678,10 +2410,10 @@ TextureFactoryIdentifier WebRenderBridgeParent::GetTextureFactoryIdentifier() {
return TextureFactoryIdentifier(
LayersBackend::LAYERS_WR, XRE_GetProcessType(),
mApis[wr::RenderRoot::Default]->GetMaxTextureSize(), false,
mApis[wr::RenderRoot::Default]->GetUseANGLE(),
mApis[wr::RenderRoot::Default]->GetUseDComp(), false, false, false,
mApis[wr::RenderRoot::Default]->GetSyncHandle());
Api(wr::RenderRoot::Default)->GetMaxTextureSize(), false,
Api(wr::RenderRoot::Default)->GetUseANGLE(),
Api(wr::RenderRoot::Default)->GetUseDComp(), false, false, false,
Api(wr::RenderRoot::Default)->GetSyncHandle());
}
wr::Epoch WebRenderBridgeParent::GetNextWrEpoch() {

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

@ -19,9 +19,7 @@
#include "mozilla/layers/PWebRenderBridgeParent.h"
#include "mozilla/layers/UiCompositorControllerParent.h"
#include "mozilla/layers/WebRenderCompositionRecorder.h"
#include "mozilla/HashTable.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/webrender/WebRenderTypes.h"
@ -124,20 +122,21 @@ class WebRenderBridgeParent final
mozilla::ipc::IPCResult RecvSetDisplayList(
nsTArray<RenderRootDisplayListData>&& aDisplayLists,
nsTArray<OpDestroy>&& aToDestroy, const uint64_t& aFwdTransactionId,
const TransactionId& aTransactionId, const bool& aContainsSVGGroup,
const VsyncId& aVsyncId, const TimeStamp& aVsyncStartTime,
const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
const nsCString& aTxnURL, const TimeStamp& aFwdTime,
nsTArray<CompositionPayload>&& aPayloads) override;
mozilla::ipc::IPCResult RecvEmptyTransaction(
const FocusTarget& aFocusTarget,
nsTArray<RenderRootUpdates>&& aRenderRootUpdates,
nsTArray<OpDestroy>&& aToDestroy, const uint64_t& aFwdTransactionId,
const TransactionId& aTransactionId, const VsyncId& aVsyncId,
const TransactionId& aTransactionId, const wr::IdNamespace& aIdNamespace,
const bool& aContainsSVGGroup, const VsyncId& aVsyncId,
const TimeStamp& aVsyncStartTime, const TimeStamp& aRefreshStartTime,
const TimeStamp& aTxnStartTime, const nsCString& aTxnURL,
const TimeStamp& aFwdTime,
nsTArray<CompositionPayload>&& aPayloads) override;
mozilla::ipc::IPCResult RecvEmptyTransaction(
const FocusTarget& aFocusTarget, const uint32_t& aPaintSequenceNumber,
nsTArray<RenderRootUpdates>&& aRenderRootUpdates,
nsTArray<OpDestroy>&& aToDestroy, const uint64_t& aFwdTransactionId,
const TransactionId& aTransactionId, const wr::IdNamespace& aIdNamespace,
const VsyncId& aVsyncId, const TimeStamp& aVsyncStartTime,
const TimeStamp& aRefreshStartTime, const TimeStamp& aTxnStartTime,
const nsCString& aTxnURL, const TimeStamp& aFwdTime,
nsTArray<CompositionPayload>&& aPayloads) override;
mozilla::ipc::IPCResult RecvSetFocusTarget(
const FocusTarget& aFocusTarget) override;
mozilla::ipc::IPCResult RecvParentCommands(
@ -270,29 +269,6 @@ class WebRenderBridgeParent final
*/
void ForceIsFirstPaint() { mIsFirstPaint = true; }
void PushDeferredPipelineData(RenderRootDeferredData&& aDeferredData);
/**
* If we attempt to process information for a particular pipeline before we
* can determine what RenderRoot it belongs to, then we defer that data until
* we can. This handles processing that deferred data.
*/
bool MaybeHandleDeferredPipelineData(
wr::RenderRoot aRenderRoot, const nsTArray<wr::PipelineId>& aPipelineIds,
const TimeStamp& aTxnStartTime);
/**
* See MaybeHandleDeferredPipelineData - this is the implementation of that for
* a single pipeline.
*/
bool MaybeHandleDeferredPipelineDataForPipeline(
wr::RenderRoot aRenderRoot, wr::PipelineId aPipelineId,
const TimeStamp& aTxnStartTime);
bool HandleDeferredPipelineData(
nsTArray<RenderRootDeferredData>& aDeferredData,
const TimeStamp& aTxnStartTime);
bool IsRootWebRenderBridgeParent() const;
LayersId GetLayersId() const;
WRRootId GetWRRootId() const;
@ -304,14 +280,14 @@ class WebRenderBridgeParent final
class ScheduleSharedSurfaceRelease;
explicit WebRenderBridgeParent(const wr::PipelineId& aPipelineId);
virtual ~WebRenderBridgeParent();
virtual ~WebRenderBridgeParent() = default;
wr::WebRenderAPI* Api(wr::RenderRoot aRenderRoot) {
if (IsRootWebRenderBridgeParent()) {
return mApis[aRenderRoot];
} else {
MOZ_ASSERT(aRenderRoot == wr::RenderRoot::Default);
return mApis[*mRenderRoot];
return mApis[mRenderRoot];
}
}
@ -326,25 +302,10 @@ class WebRenderBridgeParent final
return aRenderRoot;
} else {
MOZ_ASSERT(aRenderRoot == wr::RenderRoot::Default);
return *mRenderRoot;
return mRenderRoot;
}
}
// Returns whether a given render root is valid for this WRBP to receive as
// input from the WRBC.
bool RenderRootIsValid(wr::RenderRoot aRenderRoot);
void RemoveDeferredPipeline(wr::PipelineId aPipelineId);
bool ProcessEmptyTransactionUpdates(RenderRootUpdates& aUpdates,
bool* aScheduleComposite);
bool ProcessRenderRootDisplayListData(RenderRootDisplayListData& aDisplayList,
wr::Epoch aWrEpoch,
const TimeStamp& aTxnStartTime,
bool aValidTransaction,
bool aObserveLayersUpdate);
bool SetDisplayList(wr::RenderRoot aRenderRoot, const LayoutDeviceRect& aRect,
const wr::LayoutSize& aContentSize, ipc::ByteBuf&& aDL,
const wr::BuiltDisplayListDescriptor& aDLDesc,
@ -496,24 +457,6 @@ class WebRenderBridgeParent final
// need to be able to null these out in a thread-safe way from
// ClearResources, and there's no way to do that with an nsTArray.
wr::RenderRootArray<RefPtr<wr::WebRenderAPI>> mApis;
// This is a map from pipeline id to render root, that tracks the render
// roots of all subpipelines (including nested subpipelines, e.g. in the
// Fission case) attached to this WebRenderBridgeParent. This is only
// populated on the root WRBP. It is used to resolve the render root for the
// subpipelines, since they may not know where they are attached in the
// parent display list and therefore may not know their render root.
HashMap<uint64_t, wr::RenderRoot> mPipelineRenderRoots;
// This is a hashset of child pipelines for this WRBP. This allows us to
// iterate through all the children of a non-root WRBP and add them to
// the root's mPipelineRenderRoots, and potentially resolve any of their
// deferred updates.
HashSet<uint64_t> mChildPipelines;
// This is a map from pipeline id to a list of deferred data. This is only
// populated on the root WRBP. The data contained within is deferred because
// the sub-WRBP that received it did not know which renderroot it belonged
// to. Once that is resolved by the root WRBP getting the right display list
// update, the deferred data is processed.
HashMap<uint64_t, nsTArray<RenderRootDeferredData>> mPipelineDeferredUpdates;
RefPtr<AsyncImagePipelineManager> mAsyncImageManager;
RefPtr<CompositorVsyncScheduler> mCompositorScheduler;
RefPtr<CompositorAnimationStorage> mAnimStorage;
@ -548,7 +491,7 @@ class WebRenderBridgeParent final
Mutex mRenderRootRectMutex;
wr::NonDefaultRenderRootArray<ScreenRect> mRenderRootRects;
Maybe<wr::RenderRoot> mRenderRoot;
wr::RenderRoot mRenderRoot;
bool mPaused;
bool mDestroyed;
bool mReceivedDisplayList;

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

@ -255,22 +255,21 @@ bool WebRenderLayerManager::EndEmptyTransaction(EndTransactionFlags aFlags) {
WrBridge()->HasWebRenderParentCommands(renderRoot)) {
auto updates = renderRootUpdates.AppendElement();
updates->mRenderRoot = renderRoot;
updates->mPaintSequenceNumber = mPaintSequenceNumber;
if (stateManager.mAsyncResourceUpdates) {
stateManager.mAsyncResourceUpdates->Flush(updates->mResourceUpdates,
updates->mSmallShmems,
updates->mLargeShmems);
}
updates->mScrollUpdates = std::move(mPendingScrollUpdates[renderRoot]);
for (auto it = updates->mScrollUpdates.iter(); !it.done(); it.next()) {
nsLayoutUtils::NotifyPaintSkipTransaction(/*scroll id=*/it.get().key());
for (const auto& entry : updates->mScrollUpdates) {
nsLayoutUtils::NotifyPaintSkipTransaction(/*scroll id=*/entry.first);
}
}
}
Maybe<wr::IpcResourceUpdateQueue> nothing;
WrBridge()->EndEmptyTransaction(mFocusTarget, renderRootUpdates,
mLatestTransactionId,
mPaintSequenceNumber, mLatestTransactionId,
mTransactionIdAllocator->GetVsyncId(),
mTransactionIdAllocator->GetVsyncStart(),
refreshStart, mTransactionStart, mURL);

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

@ -158,14 +158,13 @@ WebRenderLayerManager* WebRenderScrollData::GetManager() const {
size_t WebRenderScrollData::AddMetadata(const ScrollMetadata& aMetadata) {
ScrollableLayerGuid::ViewID scrollId = aMetadata.GetMetrics().GetScrollId();
auto p = mScrollIdMap.lookupForAdd(scrollId);
if (!p) {
// It's a scrollId we hadn't seen before
bool ok = mScrollIdMap.add(p, scrollId, mScrollMetadatas.Length());
MOZ_RELEASE_ASSERT(ok);
auto insertResult = mScrollIdMap.insert(std::make_pair(scrollId, 0));
if (insertResult.second) {
// Insertion took place, therefore it's a scrollId we hadn't seen before
insertResult.first->second = mScrollMetadatas.Length();
mScrollMetadatas.AppendElement(aMetadata);
} // else we didn't insert, because it already existed
return p->value();
return insertResult.first->second;
}
size_t WebRenderScrollData::AddLayerData(
@ -194,8 +193,8 @@ const ScrollMetadata& WebRenderScrollData::GetScrollMetadata(
Maybe<size_t> WebRenderScrollData::HasMetadataFor(
const ScrollableLayerGuid::ViewID& aScrollId) const {
auto ptr = mScrollIdMap.lookup(aScrollId);
return (ptr ? Some(ptr->value()) : Nothing());
auto it = mScrollIdMap.find(aScrollId);
return (it == mScrollIdMap.end() ? Nothing() : Some(it->second));
}
void WebRenderScrollData::SetIsFirstPaint() { mIsFirstPaint = true; }
@ -213,11 +212,10 @@ uint32_t WebRenderScrollData::GetPaintSequenceNumber() const {
void WebRenderScrollData::ApplyUpdates(const ScrollUpdatesMap& aUpdates,
uint32_t aPaintSequenceNumber) {
for (auto it = aUpdates.iter(); !it.done(); it.next()) {
auto& entry = it.get();
if (Maybe<size_t> index = HasMetadataFor(entry.key())) {
for (const auto& update : aUpdates) {
if (Maybe<size_t> index = HasMetadataFor(update.first)) {
mScrollMetadatas[*index].GetMetrics().UpdatePendingScrollInfo(
entry.value());
update.second);
}
}
mPaintSequenceNumber = aPaintSequenceNumber;
@ -236,8 +234,7 @@ bool WebRenderScrollData::RepopulateMap() {
for (size_t i = 0; i < mScrollMetadatas.Length(); i++) {
ScrollableLayerGuid::ViewID scrollId =
mScrollMetadatas[i].GetMetrics().GetScrollId();
bool ok = mScrollIdMap.putNew(scrollId, i);
MOZ_RELEASE_ASSERT(ok);
mScrollIdMap.emplace(scrollId, i);
}
return true;
}

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

@ -21,7 +21,6 @@
#include "mozilla/layers/RenderRootBoundary.h"
#include "mozilla/layers/WebRenderMessageUtils.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/HashTable.h"
#include "mozilla/Maybe.h"
#include "nsTArrayForwardDeclare.h"
@ -224,7 +223,7 @@ class WebRenderScrollData final {
// valid on both the child and parent.
// The key into this map is the scrollId of a ScrollMetadata, and the value is
// an index into the mScrollMetadatas array.
HashMap<ScrollableLayerGuid::ViewID, size_t> mScrollIdMap;
std::map<ScrollableLayerGuid::ViewID, size_t> mScrollIdMap;
// A list of all the unique ScrollMetadata objects from the layer tree. Each
// ScrollMetadata in this list must have a unique scroll id.

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

@ -816,8 +816,6 @@ void DisplayListBuilder::Finalize(
&aOutTransaction.mDLDesc, &dl.inner);
aOutTransaction.mDL.emplace(dl.inner.data, dl.inner.length,
dl.inner.capacity);
aOutTransaction.mRemotePipelineIds =
std::move(SubBuilder(aOutTransaction.mRenderRoot).mRemotePipelineIds);
dl.inner.capacity = 0;
dl.inner.data = nullptr;
}
@ -1106,7 +1104,6 @@ void DisplayListBuilder::PushIFrame(const wr::LayoutRect& aBounds,
bool aIsBackfaceVisible,
PipelineId aPipeline,
bool aIgnoreMissingPipeline) {
mRemotePipelineIds.AppendElement(aPipeline);
wr_dp_push_iframe(mWrState, aBounds, MergeClipLeaf(aBounds),
aIsBackfaceVisible, &mCurrentSpaceAndClipChain, aPipeline,
aIgnoreMissingPipeline);

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

@ -638,7 +638,6 @@ class DisplayListBuilder final {
wr::PipelineId mPipelineId;
wr::LayoutSize mContentSize;
nsTArray<wr::PipelineId> mRemotePipelineIds;
RenderRoot mRenderRoot;
bool mSendSubBuilderDisplayList;

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

@ -16,7 +16,6 @@
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/EnumSet.h"
#include "mozilla/EnumTypeTraits.h"
#include "mozilla/HashTable.h"
#include "mozilla/Maybe.h"
#include "mozilla/net/WebSocketFrame.h"
#include "mozilla/TimeStamp.h"
@ -526,48 +525,6 @@ struct ParamTraits<nsTHashtable<nsUint64HashKey>> {
}
};
template <typename K, typename V>
struct ParamTraits<mozilla::HashMap<K, V>> {
typedef mozilla::HashMap<K, V> paramType;
static void Write(Message* aMsg, const paramType& aParam) {
uint32_t count = aParam.count();
WriteParam(aMsg, count);
for (auto it = aParam.iter(); !it.done(); it.next()) {
WriteParam(aMsg, it.get().key());
WriteParam(aMsg, it.get().value());
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
paramType* aResult) {
uint32_t count;
if (!ReadParam(aMsg, aIter, &count)) {
return false;
}
// It's ok that the writer can DoS us here, because that's not part of our
// IPC security model (there's plenty of ways to DoS with malicious IPC).
paramType table(count);
for (uint32_t i = 0; i < count; ++i) {
K key;
V value;
if (!ReadParam(aMsg, aIter, &key)) {
return false;
}
if (!ReadParam(aMsg, aIter, &value)) {
return false;
}
// Don't necessarily trust the writer, so don't putNew.
bool ok = table.put(key, value);
if (!ok) {
return false;
}
}
*aResult = std::move(table);
return true;
}
};
// Pickle::ReadBytes and ::WriteBytes take the length in ints, so we must
// ensure there is no overflow. This returns |false| if it would overflow.
// Otherwise, it returns |true| and places the byte length in |aByteLength|.