Bug 1449982 - Clean up WrEpoch usage. r?nical
I don't know why we keep using plain uint32_t and uint64_t values when
we have better types that we can use. This makes the code use and store
wr::Epoch natively instead of raw uint32_t values that are wrapped
on-demand.
MozReview-Commit-ID: HUVcHYSxBTi
--- a/gfx/layers/wr/AsyncImagePipelineManager.cpp
+++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp
@@ -25,17 +25,17 @@ AsyncImagePipelineManager::AsyncImagePip
, mFilter(wr::ImageRendering::Auto)
, mMixBlendMode(wr::MixBlendMode::Normal)
{}
AsyncImagePipelineManager::AsyncImagePipelineManager(already_AddRefed<wr::WebRenderAPI>&& aApi)
: mApi(aApi)
, mIdNamespace(mApi->GetNamespace())
, mResourceId(0)
- , mAsyncImageEpoch(0)
+ , mAsyncImageEpoch{0}
, mWillGenerateFrame(false)
, mDestroyed(false)
{
MOZ_COUNT_CTOR(AsyncImagePipelineManager);
}
AsyncImagePipelineManager::~AsyncImagePipelineManager()
{
@@ -124,23 +124,23 @@ AsyncImagePipelineManager::RemoveAsyncIm
{
if (mDestroyed) {
return;
}
uint64_t id = wr::AsUint64(aPipelineId);
if (auto entry = mAsyncImagePipelines.Lookup(id)) {
AsyncImagePipeline* holder = entry.Data();
- ++mAsyncImageEpoch; // Update webrender epoch
- aTxn.ClearDisplayList(wr::NewEpoch(mAsyncImageEpoch), aPipelineId);
+ wr::Epoch epoch = GetNextImageEpoch();
+ aTxn.ClearDisplayList(epoch, aPipelineId);
for (wr::ImageKey key : holder->mKeys) {
aTxn.DeleteImage(key);
}
entry.Remove();
- RemovePipeline(aPipelineId, wr::NewEpoch(mAsyncImageEpoch));
+ RemovePipeline(aPipelineId, epoch);
}
}
void
AsyncImagePipelineManager::UpdateAsyncImagePipeline(const wr::PipelineId& aPipelineId,
const LayoutDeviceRect& aScBounds,
const gfx::Matrix4x4& aScTransform,
const gfx::MaybeIntSize& aScaleToSize,
@@ -266,18 +266,17 @@ AsyncImagePipelineManager::UpdateWithout
void
AsyncImagePipelineManager::ApplyAsyncImages()
{
if (mDestroyed || mAsyncImagePipelines.Count() == 0) {
return;
}
- ++mAsyncImageEpoch; // Update webrender epoch
- wr::Epoch epoch = wr::NewEpoch(mAsyncImageEpoch);
+ wr::Epoch epoch = GetNextImageEpoch();
// TODO: We can improve upon this by using two transactions: one for everything that
// doesn't change the display list (in other words does not cause the scene to be
// re-built), and one for the rest. This way, if an async pipeline needs to re-build
// its display list, other async pipelines can still be rendered while the scene is
// building.
wr::TransactionBuilder txn;
@@ -411,10 +410,17 @@ AsyncImagePipelineManager::PipelineRemov
// Remove Pipeline
entry.Remove();
}
// If mDestroyedEpoch contains nothing it means we reused the same pipeline id (probably because
// we moved the tab to another window). In this case we need to keep the holder.
}
}
+wr::Epoch
+AsyncImagePipelineManager::GetNextImageEpoch()
+{
+ mAsyncImageEpoch.mHandle++;
+ return mAsyncImageEpoch;
+}
+
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/AsyncImagePipelineManager.h
+++ b/gfx/layers/wr/AsyncImagePipelineManager.h
@@ -92,16 +92,17 @@ public:
aNotifications->AppendElements(Move(mImageCompositeNotifications));
}
void SetWillGenerateFrame();
bool GetAndResetWillGenerateFrame();
private:
+ wr::Epoch GetNextImageEpoch();
uint32_t GetNextResourceId() { return ++mResourceId; }
wr::IdNamespace GetNamespace() { return mIdNamespace; }
wr::ImageKey GenerateImageKey()
{
wr::ImageKey key;
key.mNamespace = GetNamespace();
key.mHandle = GetNextResourceId();
return key;
@@ -166,17 +167,17 @@ private:
TextureHost::ResourceUpdateOp);
RefPtr<wr::WebRenderAPI> mApi;
wr::IdNamespace mIdNamespace;
uint32_t mResourceId;
nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> mPipelineTexturesHolders;
nsClassHashtable<nsUint64HashKey, AsyncImagePipeline> mAsyncImagePipelines;
- uint32_t mAsyncImageEpoch;
+ wr::Epoch mAsyncImageEpoch;
bool mWillGenerateFrame;
bool mDestroyed;
// Render time for the current composition.
TimeStamp mCompositionTime;
// When nonnull, during rendering, some compositable indicated that it will
// change its rendering at this time. In order not to miss it, we composite
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -168,17 +168,17 @@ WebRenderBridgeParent::WebRenderBridgePa
, mPipelineId(aPipelineId)
, mWidget(aWidget)
, mApi(aApi)
, mAsyncImageManager(aImageMgr)
, mCompositorScheduler(aScheduler)
, mAnimStorage(aAnimStorage)
, mChildLayerObserverEpoch(0)
, mParentLayerObserverEpoch(0)
- , mWrEpoch(0)
+ , mWrEpoch{0}
, mIdNamespace(aApi->GetNamespace())
, mPaused(false)
, mDestroyed(false)
, mForceRendering(false)
, mReceivedDisplayList(false)
{
MOZ_ASSERT(mAsyncImageManager);
MOZ_ASSERT(mAnimStorage);
@@ -189,17 +189,17 @@ WebRenderBridgeParent::WebRenderBridgePa
}
}
WebRenderBridgeParent::WebRenderBridgeParent(const wr::PipelineId& aPipelineId)
: mCompositorBridge(nullptr)
, mPipelineId(aPipelineId)
, mChildLayerObserverEpoch(0)
, mParentLayerObserverEpoch(0)
- , mWrEpoch(0)
+ , mWrEpoch{0}
, mIdNamespace{0}
, mPaused(false)
, mDestroyed(true)
, mForceRendering(false)
, mReceivedDisplayList(false)
{
}
@@ -583,17 +583,17 @@ WebRenderBridgeParent::RecvSetDisplayLis
AUTO_PROFILER_TRACING("Paint", "SetDisplayList");
UpdateFwdTransactionId(aFwdTransactionId);
// This ensures that destroy operations are always processed. It is not safe
// to early-return from RecvDPEnd without doing so.
AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
- uint32_t wrEpoch = GetNextWrEpoch();
+ wr::Epoch wrEpoch = GetNextWrEpoch();
mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
ProcessWebRenderParentCommands(aCommands);
wr::TransactionBuilder txn;
if (!UpdateResources(aResourceUpdates, aSmallShmems, aLargeShmems, txn)) {
return IPC_FAIL(this, "Failed to deserialize resource updates");
@@ -608,17 +608,17 @@ WebRenderBridgeParent::RecvSetDisplayLis
// In that case do not send the commands to webrender.
if (mIdNamespace == aIdNamespace) {
if (mWidget) {
LayoutDeviceIntSize widgetSize = mWidget->GetClientSize();
LayoutDeviceIntRect docRect(LayoutDeviceIntPoint(), widgetSize);
txn.SetWindowParameters(widgetSize, docRect);
}
gfx::Color clearColor(0.f, 0.f, 0.f, 0.f);
- txn.SetDisplayList(clearColor, wr::NewEpoch(wrEpoch), LayerSize(aSize.width, aSize.height),
+ txn.SetDisplayList(clearColor, wrEpoch, LayerSize(aSize.width, aSize.height),
mPipelineId, aContentSize,
dlDesc, dlData);
mApi->SendTransaction(txn);
ScheduleGenerateFrame();
if (ShouldParentObserveEpoch()) {
@@ -673,27 +673,27 @@ WebRenderBridgeParent::RecvEmptyTransact
ScheduleGenerateFrame();
}
mScrollData.SetFocusTarget(aFocusTarget);
UpdateAPZ(false);
if (!aCommands.IsEmpty()) {
wr::TransactionBuilder txn;
- uint32_t wrEpoch = GetNextWrEpoch();
- txn.UpdateEpoch(mPipelineId, wr::NewEpoch(wrEpoch));
+ wr::Epoch wrEpoch = GetNextWrEpoch();
+ txn.UpdateEpoch(mPipelineId, wrEpoch);
mApi->SendTransaction(txn);
HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
} else {
bool sendDidComposite = false;
if (mPendingTransactionIds.empty()) {
sendDidComposite = true;
}
- HoldPendingTransactionId(mWrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
+ HoldPendingTransactionId(WrEpoch(), aTransactionId, aTxnStartTime, aFwdTime);
// If WebRenderBridgeParent does not have pending DidComposites,
// send DidComposite now.
if (sendDidComposite) {
TimeStamp now = TimeStamp::Now();
mCompositorBridge->DidComposite(GetLayersId(), now, now);
}
}
@@ -940,17 +940,17 @@ WebRenderBridgeParent::RecvClearCachedRe
{
if (mDestroyed) {
return IPC_OK();
}
mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), false);
// Clear resources
wr::TransactionBuilder txn;
- txn.ClearDisplayList(wr::NewEpoch(GetNextWrEpoch()), mPipelineId);
+ txn.ClearDisplayList(GetNextWrEpoch(), mPipelineId);
mApi->SendTransaction(txn);
// Schedule generate frame to clean up Pipeline
ScheduleGenerateFrame();
// Remove animations.
for (std::unordered_set<uint64_t>::iterator iter = mActiveAnimations.begin(); iter != mActiveAnimations.end(); iter++) {
mAnimStorage->ClearById(*iter);
}
mActiveAnimations.clear();
@@ -1236,23 +1236,23 @@ WebRenderBridgeParent::CompositeToTarget
}
txn.GenerateFrame();
mApi->SendTransaction(txn);
}
void
-WebRenderBridgeParent::HoldPendingTransactionId(uint32_t aWrEpoch,
+WebRenderBridgeParent::HoldPendingTransactionId(const wr::Epoch& aWrEpoch,
uint64_t aTransactionId,
const TimeStamp& aTxnStartTime,
const TimeStamp& aFwdTime)
{
MOZ_ASSERT(aTransactionId > LastPendingTransactionId());
- mPendingTransactionIds.push(PendingTransactionId(wr::NewEpoch(aWrEpoch), aTransactionId, aTxnStartTime, aFwdTime));
+ mPendingTransactionIds.push(PendingTransactionId(aWrEpoch, aTransactionId, aTxnStartTime, aFwdTime));
}
uint64_t
WebRenderBridgeParent::LastPendingTransactionId()
{
uint64_t id = 0;
if (!mPendingTransactionIds.empty()) {
id = mPendingTransactionIds.back().mId;
@@ -1366,20 +1366,20 @@ WebRenderBridgeParent::Resume()
void
WebRenderBridgeParent::ClearResources()
{
if (!mApi) {
return;
}
- uint32_t wrEpoch = GetNextWrEpoch();
+ wr::Epoch wrEpoch = GetNextWrEpoch();
wr::TransactionBuilder txn;
- txn.ClearDisplayList(wr::NewEpoch(wrEpoch), mPipelineId);
+ txn.ClearDisplayList(wrEpoch, mPipelineId);
mReceivedDisplayList = false;
// Schedule generate frame to clean up Pipeline
ScheduleGenerateFrame();
// WrFontKeys and WrImageKeys are deleted during WebRenderAPI destruction.
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
iter.Data()->ClearWrBridge();
}
@@ -1387,17 +1387,17 @@ WebRenderBridgeParent::ClearResources()
for (auto iter = mAsyncCompositables.Iter(); !iter.Done(); iter.Next()) {
wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
RefPtr<WebRenderImageHost> host = iter.Data();
host->ClearWrBridge();
mAsyncImageManager->RemoveAsyncImagePipeline(pipelineId, txn);
}
mAsyncCompositables.Clear();
- mAsyncImageManager->RemovePipeline(mPipelineId, wr::NewEpoch(wrEpoch));
+ mAsyncImageManager->RemovePipeline(mPipelineId, wrEpoch);
txn.RemovePipeline(mPipelineId);
mApi->SendTransaction(txn);
for (std::unordered_set<uint64_t>::iterator iter = mActiveAnimations.begin(); iter != mActiveAnimations.end(); iter++) {
mAnimStorage->ClearById(*iter);
}
mActiveAnimations.clear();
@@ -1494,21 +1494,22 @@ WebRenderBridgeParent::GetTextureFactory
mApi->GetMaxTextureSize(),
mApi->GetUseANGLE(),
false,
false,
false,
mApi->GetSyncHandle());
}
-uint32_t
+wr::Epoch
WebRenderBridgeParent::GetNextWrEpoch()
{
- MOZ_RELEASE_ASSERT(mWrEpoch != UINT32_MAX);
- return ++mWrEpoch;
+ MOZ_RELEASE_ASSERT(mWrEpoch.mHandle != UINT32_MAX);
+ mWrEpoch.mHandle++;
+ return mWrEpoch;
}
void
WebRenderBridgeParent::ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo>* aNotifications)
{
MOZ_ASSERT(mWidget);
if (mDestroyed) {
return;
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -54,17 +54,17 @@ public:
RefPtr<wr::WebRenderAPI>&& aApi,
RefPtr<AsyncImagePipelineManager>&& aImageMgr,
RefPtr<CompositorAnimationStorage>&& aAnimStorage);
static WebRenderBridgeParent* CreateDestroyed(const wr::PipelineId& aPipelineId);
wr::PipelineId PipelineId() { return mPipelineId; }
already_AddRefed<wr::WebRenderAPI> GetWebRenderAPI() { return do_AddRef(mApi); }
- wr::Epoch WrEpoch() { return wr::NewEpoch(mWrEpoch); }
+ wr::Epoch WrEpoch() const { return mWrEpoch; }
AsyncImagePipelineManager* AsyncImageManager() { return mAsyncImageManager; }
CompositorVsyncScheduler* CompositorScheduler() { return mCompositorScheduler.get(); }
mozilla::ipc::IPCResult RecvNewCompositable(const CompositableHandle& aHandle,
const TextureInfo& aInfo) override;
mozilla::ipc::IPCResult RecvReleaseCompositable(const CompositableHandle& aHandle) override;
mozilla::ipc::IPCResult RecvCreate(const gfx::IntSize& aSize) override;
@@ -148,17 +148,17 @@ public:
// CompositableParentManager
bool IsSameProcess() const override;
base::ProcessId GetChildProcessId() override;
void NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) override;
void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
void SendPendingAsyncMessages() override;
void SetAboutToSendAsyncMessages() override;
- void HoldPendingTransactionId(uint32_t aWrEpoch,
+ void HoldPendingTransactionId(const wr::Epoch& aWrEpoch,
uint64_t aTransactionId,
const TimeStamp& aTxnStartTime,
const TimeStamp& aFwdTime);
uint64_t LastPendingTransactionId();
uint64_t FlushPendingTransactionIds();
uint64_t FlushTransactionIdsForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime);
TextureFactoryIdentifier GetTextureFactoryIdentifier();
@@ -221,21 +221,21 @@ private:
// Have APZ push the async scroll state to WR. Returns true if an APZ
// animation is in effect and we need to schedule another composition.
// If scrollbars need their transforms updated, the provided aTransformArray
// is populated with the property update details.
bool PushAPZStateToWR(wr::TransactionBuilder& aTxn,
nsTArray<wr::WrTransformProperty>& aTransformArray);
- uint32_t GetNextWrEpoch();
+ wr::Epoch GetNextWrEpoch();
private:
struct PendingTransactionId {
- PendingTransactionId(wr::Epoch aEpoch, uint64_t aId, const TimeStamp& aTxnStartTime, const TimeStamp& aFwdTime)
+ PendingTransactionId(const wr::Epoch& aEpoch, uint64_t aId, const TimeStamp& aTxnStartTime, const TimeStamp& aFwdTime)
: mEpoch(aEpoch)
, mId(aId)
, mTxnStartTime(aTxnStartTime)
, mFwdTime(aFwdTime)
{}
wr::Epoch mEpoch;
uint64_t mId;
TimeStamp mTxnStartTime;
@@ -259,17 +259,17 @@ private:
// These fields keep track of the latest layer observer epoch values in the child and the
// parent. mChildLayerObserverEpoch is the latest epoch value received from the child.
// mParentLayerObserverEpoch is the latest epoch value that we have told TabParent about
// (via ObserveLayerUpdate).
uint64_t mChildLayerObserverEpoch;
uint64_t mParentLayerObserverEpoch;
std::queue<PendingTransactionId> mPendingTransactionIds;
- uint32_t mWrEpoch;
+ wr::Epoch mWrEpoch;
wr::IdNamespace mIdNamespace;
bool mPaused;
bool mDestroyed;
bool mForceRendering;
bool mReceivedDisplayList;
// Can only be accessed on the compositor thread.
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -42,22 +42,16 @@ typedef mozilla::Maybe<mozilla::wr::WrIm
typedef Maybe<ExternalImageId> MaybeExternalImageId;
typedef Maybe<FontInstanceOptions> MaybeFontInstanceOptions;
typedef Maybe<FontInstancePlatformOptions> MaybeFontInstancePlatformOptions;
/* Generate a brand new window id and return it. */
WindowId NewWindowId();
-inline Epoch NewEpoch(uint32_t aEpoch) {
- Epoch e;
- e.mHandle = aEpoch;
- return e;
-}
-
inline DebugFlags NewDebugFlags(uint32_t aFlags) {
DebugFlags flags;
flags.mBits = aFlags;
return flags;
}
inline Maybe<wr::ImageFormat>
SurfaceFormatToImageFormat(gfx::SurfaceFormat aFormat) {