зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1547351
) for assertion failures on a CLOSED TREE
Backed out changeset 77ef8e8bc669 (bug1547351
) Backed out changeset b594f8e47025 (bug1547351
) Backed out changeset 6e5d426cd313 (bug1547351
)
This commit is contained in:
Родитель
9196c76343
Коммит
6665820f48
|
@ -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|.
|
||||
|
|
Загрузка…
Ссылка в новой задаче