1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/layers/RenderRootStateManager.h"
9 #include "mozilla/layers/WebRenderBridgeChild.h"
10 #include "mozilla/layers/WebRenderLayerManager.h"
15 // RenderRootStateManager shares its ref count with the WebRenderLayerManager
16 // that created it. You can think of the two classes as being one unit, except
17 // there are multiple RenderRootStateManagers per WebRenderLayerManager. Since
18 // we need to reference the WebRenderLayerManager and it needs to reference us,
19 // this avoids us needing to involve the cycle collector.
20 void RenderRootStateManager::AddRef() { mLayerManager
->AddRef(); }
22 void RenderRootStateManager::Release() { mLayerManager
->Release(); }
24 WebRenderBridgeChild
* RenderRootStateManager::WrBridge() const {
25 return mLayerManager
->WrBridge();
28 WebRenderCommandBuilder
& RenderRootStateManager::CommandBuilder() {
29 return mLayerManager
->CommandBuilder();
32 RenderRootStateManager::WebRenderUserDataRefTable
*
33 RenderRootStateManager::GetWebRenderUserDataTable() {
34 return mLayerManager
->GetWebRenderUserDataTable();
37 wr::IpcResourceUpdateQueue
& RenderRootStateManager::AsyncResourceUpdates() {
38 MOZ_ASSERT(NS_IsMainThread());
39 MOZ_ASSERT(XRE_IsParentProcess() || mRenderRoot
== wr::RenderRoot::Default
);
41 if (!mAsyncResourceUpdates
) {
42 mAsyncResourceUpdates
.emplace(WrBridge(), mRenderRoot
);
44 RefPtr
<Runnable
> task
= NewRunnableMethod(
45 "RenderRootStateManager::FlushAsyncResourceUpdates", this,
46 &RenderRootStateManager::FlushAsyncResourceUpdates
);
47 NS_DispatchToMainThread(task
.forget());
50 return mAsyncResourceUpdates
.ref();
53 void RenderRootStateManager::Destroy() {
54 ClearAsyncAnimations();
57 // Just clear ImageKeys, they are deleted during WebRenderAPI destruction.
59 // CompositorAnimations are cleared by WebRenderBridgeParent.
60 mDiscardedCompositorAnimationsIds
.Clear();
63 mActiveCompositorAnimationIds
.clear();
68 void RenderRootStateManager::FlushAsyncResourceUpdates() {
69 MOZ_ASSERT(NS_IsMainThread());
71 if (!mAsyncResourceUpdates
) {
75 if (!IsDestroyed() && WrBridge()) {
76 WrBridge()->UpdateResources(mAsyncResourceUpdates
.ref(), mRenderRoot
);
79 mAsyncResourceUpdates
.reset();
82 void RenderRootStateManager::AddImageKeyForDiscard(wr::ImageKey key
) {
83 mImageKeysToDelete
.AppendElement(key
);
86 void RenderRootStateManager::AddBlobImageKeyForDiscard(wr::BlobImageKey key
) {
87 mBlobImageKeysToDelete
.AppendElement(key
);
90 void RenderRootStateManager::DiscardImagesInTransaction(
91 wr::IpcResourceUpdateQueue
& aResources
) {
92 for (const auto& key
: mImageKeysToDelete
) {
93 aResources
.DeleteImage(key
);
95 for (const auto& key
: mBlobImageKeysToDelete
) {
96 aResources
.DeleteBlobImage(key
);
98 mImageKeysToDelete
.Clear();
99 mBlobImageKeysToDelete
.Clear();
102 void RenderRootStateManager::DiscardLocalImages() {
103 // Removes images but doesn't tell the parent side about them
104 // This is useful in empty / failed transactions where we created
105 // image keys but didn't tell the parent about them yet.
106 mImageKeysToDelete
.Clear();
107 mBlobImageKeysToDelete
.Clear();
110 void RenderRootStateManager::ClearCachedResources() {
111 mActiveCompositorAnimationIds
.clear();
112 mDiscardedCompositorAnimationsIds
.Clear();
115 void RenderRootStateManager::AddActiveCompositorAnimationId(uint64_t aId
) {
116 // In layers-free mode we track the active compositor animation ids on the
117 // client side so that we don't try to discard the same animation id multiple
118 // times. We could just ignore the multiple-discard on the parent side, but
119 // checking on the content side reduces IPC traffic.
120 mActiveCompositorAnimationIds
.insert(aId
);
123 void RenderRootStateManager::AddCompositorAnimationsIdForDiscard(uint64_t aId
) {
124 if (mActiveCompositorAnimationIds
.erase(aId
)) {
125 // For layers-free ensure we don't try to discard an animation id that
126 // wasn't active. We also remove it from mActiveCompositorAnimationIds so we
127 // don't discard it again unless it gets re-activated.
128 mDiscardedCompositorAnimationsIds
.AppendElement(aId
);
132 void RenderRootStateManager::DiscardCompositorAnimations() {
133 if (WrBridge()->IPCOpen() && !mDiscardedCompositorAnimationsIds
.IsEmpty()) {
134 WrBridge()->SendDeleteCompositorAnimations(
135 mDiscardedCompositorAnimationsIds
);
137 mDiscardedCompositorAnimationsIds
.Clear();
140 void RenderRootStateManager::RegisterAsyncAnimation(
141 const wr::ImageKey
& aKey
, SharedSurfacesAnimation
* aAnimation
) {
142 mAsyncAnimations
.insert(std::make_pair(wr::AsUint64(aKey
), aAnimation
));
145 void RenderRootStateManager::DeregisterAsyncAnimation(
146 const wr::ImageKey
& aKey
) {
147 mAsyncAnimations
.erase(wr::AsUint64(aKey
));
150 void RenderRootStateManager::ClearAsyncAnimations() {
151 for (const auto& i
: mAsyncAnimations
) {
152 i
.second
->Invalidate(this);
154 mAsyncAnimations
.clear();
157 void RenderRootStateManager::WrReleasedImages(
158 const nsTArray
<wr::ExternalImageKeyPair
>& aPairs
) {
159 // A SharedSurfaceAnimation object's lifetime is tied to its owning
160 // ImageContainer. When the ImageContainer is released,
161 // SharedSurfaceAnimation::Destroy is called which should ensure it is removed
162 // from the layer manager. Whenever the namespace for the
163 // WebRenderLayerManager itself is invalidated (e.g. we changed windows, or
164 // were destroyed ourselves), we callback into the SharedSurfaceAnimation
165 // object to remove its image key for us and any bound surfaces. If, for any
166 // reason, we somehow missed an WrReleasedImages call before the animation
167 // was bound to the layer manager, it will free those associated surfaces on
168 // the next ReleasePreviousFrame call.
169 for (const auto& pair
: aPairs
) {
170 auto i
= mAsyncAnimations
.find(wr::AsUint64(pair
.key
));
171 if (i
!= mAsyncAnimations
.end()) {
172 i
->second
->ReleasePreviousFrame(this, pair
.id
);
177 void RenderRootStateManager::AddWebRenderParentCommand(
178 const WebRenderParentCommand
& aCmd
) {
179 WrBridge()->AddWebRenderParentCommand(aCmd
, mRenderRoot
);
181 void RenderRootStateManager::UpdateResources(
182 wr::IpcResourceUpdateQueue
& aResources
) {
183 WrBridge()->UpdateResources(aResources
, mRenderRoot
);
185 void RenderRootStateManager::AddPipelineIdForAsyncCompositable(
186 const wr::PipelineId
& aPipelineId
, const CompositableHandle
& aHandle
) {
187 WrBridge()->AddPipelineIdForAsyncCompositable(aPipelineId
, aHandle
,
190 void RenderRootStateManager::AddPipelineIdForCompositable(
191 const wr::PipelineId
& aPipelineId
, const CompositableHandle
& aHandle
) {
192 WrBridge()->AddPipelineIdForCompositable(aPipelineId
, aHandle
, mRenderRoot
);
194 void RenderRootStateManager::RemovePipelineIdForCompositable(
195 const wr::PipelineId
& aPipelineId
) {
196 WrBridge()->RemovePipelineIdForCompositable(aPipelineId
, mRenderRoot
);
198 /// Release TextureClient that is bounded to ImageKey.
199 /// It is used for recycling TextureClient.
200 void RenderRootStateManager::ReleaseTextureOfImage(const wr::ImageKey
& aKey
) {
201 WrBridge()->ReleaseTextureOfImage(aKey
, mRenderRoot
);
204 Maybe
<wr::FontInstanceKey
> RenderRootStateManager::GetFontKeyForScaledFont(
205 gfx::ScaledFont
* aScaledFont
, wr::IpcResourceUpdateQueue
* aResources
) {
206 return WrBridge()->GetFontKeyForScaledFont(aScaledFont
, mRenderRoot
,
210 Maybe
<wr::FontKey
> RenderRootStateManager::GetFontKeyForUnscaledFont(
211 gfx::UnscaledFont
* aUnscaledFont
, wr::IpcResourceUpdateQueue
* aResources
) {
212 return WrBridge()->GetFontKeyForUnscaledFont(aUnscaledFont
, mRenderRoot
,
216 } // namespace layers
217 } // namespace mozilla