RenderRootStateManager.cpp (8387B)
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/. */ 6 7 #include "mozilla/layers/RenderRootStateManager.h" 8 9 #include "mozilla/layers/WebRenderBridgeChild.h" 10 #include "mozilla/layers/WebRenderLayerManager.h" 11 12 namespace mozilla { 13 namespace layers { 14 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(); } 21 22 void RenderRootStateManager::Release() { mLayerManager->Release(); } 23 24 WebRenderBridgeChild* RenderRootStateManager::WrBridge() const { 25 return mLayerManager->WrBridge(); 26 } 27 28 WebRenderCommandBuilder& RenderRootStateManager::CommandBuilder() { 29 return mLayerManager->CommandBuilder(); 30 } 31 32 RenderRootStateManager::WebRenderUserDataRefTable* 33 RenderRootStateManager::GetWebRenderUserDataTable() { 34 return mLayerManager->GetWebRenderUserDataTable(); 35 } 36 37 wr::IpcResourceUpdateQueue& RenderRootStateManager::AsyncResourceUpdates() { 38 MOZ_ASSERT(NS_IsMainThread()); 39 40 if (!mAsyncResourceUpdates) { 41 mAsyncResourceUpdates.emplace(WrBridge()); 42 43 RefPtr<Runnable> task = NewRunnableMethod( 44 "RenderRootStateManager::FlushAsyncResourceUpdates", this, 45 &RenderRootStateManager::FlushAsyncResourceUpdates); 46 NS_DispatchToMainThread(task.forget()); 47 } 48 49 return mAsyncResourceUpdates.ref(); 50 } 51 52 void RenderRootStateManager::Destroy() { 53 ClearAsyncAnimations(); 54 55 if (WrBridge()) { 56 // Just clear ImageKeys, they are deleted during WebRenderAPI destruction. 57 DiscardLocalImages(); 58 // CompositorAnimations are cleared by WebRenderBridgeParent. 59 mDiscardedCompositorAnimationsIds.Clear(); 60 } 61 62 mActiveCompositorAnimationIds.clear(); 63 64 mDestroyed = true; 65 } 66 67 void RenderRootStateManager::FlushAsyncResourceUpdates() { 68 MOZ_ASSERT(NS_IsMainThread()); 69 70 if (!mAsyncResourceUpdates) { 71 return; 72 } 73 74 if (!IsDestroyed() && WrBridge()) { 75 WrBridge()->UpdateResources(mAsyncResourceUpdates.ref()); 76 } 77 78 mAsyncResourceUpdates.reset(); 79 } 80 81 void RenderRootStateManager::AddImageKeyForDiscard(wr::ImageKey key) { 82 mImageKeysToDelete.AppendElement(key); 83 } 84 85 void RenderRootStateManager::AddBlobImageKeyForDiscard(wr::BlobImageKey key) { 86 mBlobImageKeysToDelete.AppendElement(key); 87 } 88 89 void RenderRootStateManager::AddUnusedSnapshotImageKeyForDiscard( 90 wr::SnapshotImageKey key) { 91 mUnusedSnapshotImageKeysToDelete.AppendElement(key); 92 } 93 94 void RenderRootStateManager::AddSnapshotImageKeyForDiscard( 95 wr::SnapshotImageKey key) { 96 mSnapshotImageKeysToDelete.AppendElement(key); 97 } 98 99 void RenderRootStateManager::DiscardImagesInTransaction( 100 wr::IpcResourceUpdateQueue& aResources) { 101 for (const auto& key : mImageKeysToDelete) { 102 aResources.DeleteImage(key); 103 } 104 for (const auto& key : mBlobImageKeysToDelete) { 105 aResources.DeleteBlobImage(key); 106 } 107 for (const auto& key : mSnapshotImageKeysToDelete) { 108 aResources.DeleteSnapshotImage(key); 109 } 110 mImageKeysToDelete.Clear(); 111 mBlobImageKeysToDelete.Clear(); 112 mSnapshotImageKeysToDelete.Clear(); 113 114 DiscardUnusedImagesInTransaction(aResources); 115 } 116 117 void RenderRootStateManager::DiscardUnusedImagesInTransaction( 118 wr::IpcResourceUpdateQueue& aResources) { 119 for (const auto& key : mUnusedSnapshotImageKeysToDelete) { 120 aResources.DeleteSnapshotImage(key); 121 } 122 mUnusedSnapshotImageKeysToDelete.Clear(); 123 } 124 125 void RenderRootStateManager::DiscardLocalImages() { 126 // Removes images but doesn't tell the parent side about them 127 // This is useful in empty / failed transactions where we created 128 // image keys but didn't tell the parent about them yet. 129 mImageKeysToDelete.Clear(); 130 mBlobImageKeysToDelete.Clear(); 131 mSnapshotImageKeysToDelete.Clear(); 132 } 133 134 void RenderRootStateManager::ClearCachedResources() { 135 mActiveCompositorAnimationIds.clear(); 136 mDiscardedCompositorAnimationsIds.Clear(); 137 } 138 139 void RenderRootStateManager::AddActiveCompositorAnimationId(uint64_t aId) { 140 // In layers-free mode we track the active compositor animation ids on the 141 // client side so that we don't try to discard the same animation id multiple 142 // times. We could just ignore the multiple-discard on the parent side, but 143 // checking on the content side reduces IPC traffic. 144 mActiveCompositorAnimationIds.insert(aId); 145 } 146 147 void RenderRootStateManager::AddCompositorAnimationsIdForDiscard(uint64_t aId) { 148 if (mActiveCompositorAnimationIds.erase(aId)) { 149 // For layers-free ensure we don't try to discard an animation id that 150 // wasn't active. We also remove it from mActiveCompositorAnimationIds so we 151 // don't discard it again unless it gets re-activated. 152 mDiscardedCompositorAnimationsIds.AppendElement(aId); 153 } 154 } 155 156 void RenderRootStateManager::DiscardCompositorAnimations() { 157 if (WrBridge()->IPCOpen() && !mDiscardedCompositorAnimationsIds.IsEmpty()) { 158 WrBridge()->SendDeleteCompositorAnimations( 159 mDiscardedCompositorAnimationsIds); 160 } 161 mDiscardedCompositorAnimationsIds.Clear(); 162 } 163 164 void RenderRootStateManager::RegisterAsyncAnimation( 165 const wr::ImageKey& aKey, SharedSurfacesAnimation* aAnimation) { 166 mAsyncAnimations.insert(std::make_pair(wr::AsUint64(aKey), aAnimation)); 167 } 168 169 void RenderRootStateManager::DeregisterAsyncAnimation( 170 const wr::ImageKey& aKey) { 171 mAsyncAnimations.erase(wr::AsUint64(aKey)); 172 } 173 174 void RenderRootStateManager::ClearAsyncAnimations() { 175 for (const auto& i : mAsyncAnimations) { 176 i.second->Invalidate(this); 177 } 178 mAsyncAnimations.clear(); 179 } 180 181 void RenderRootStateManager::WrReleasedImages( 182 const nsTArray<wr::ExternalImageKeyPair>& aPairs) { 183 // A SharedSurfaceAnimation object's lifetime is tied to its owning 184 // ImageContainer. When the ImageContainer is released, 185 // SharedSurfaceAnimation::Destroy is called which should ensure it is removed 186 // from the layer manager. Whenever the namespace for the 187 // WebRenderLayerManager itself is invalidated (e.g. we changed windows, or 188 // were destroyed ourselves), we callback into the SharedSurfaceAnimation 189 // object to remove its image key for us and any bound surfaces. If, for any 190 // reason, we somehow missed an WrReleasedImages call before the animation 191 // was bound to the layer manager, it will free those associated surfaces on 192 // the next ReleasePreviousFrame call. 193 for (const auto& pair : aPairs) { 194 auto i = mAsyncAnimations.find(wr::AsUint64(pair.key)); 195 if (i != mAsyncAnimations.end()) { 196 i->second->ReleasePreviousFrame(this, pair.id); 197 } 198 } 199 } 200 201 void RenderRootStateManager::AddWebRenderParentCommand( 202 const WebRenderParentCommand& aCmd) { 203 WrBridge()->AddWebRenderParentCommand(aCmd); 204 } 205 void RenderRootStateManager::UpdateResources( 206 wr::IpcResourceUpdateQueue& aResources) { 207 WrBridge()->UpdateResources(aResources); 208 } 209 void RenderRootStateManager::AddPipelineIdForCompositable( 210 const wr::PipelineId& aPipelineId, const CompositableHandle& aHandle, 211 CompositableHandleOwner aOwner) { 212 WrBridge()->AddPipelineIdForCompositable(aPipelineId, aHandle, aOwner); 213 } 214 void RenderRootStateManager::RemovePipelineIdForCompositable( 215 const wr::PipelineId& aPipelineId) { 216 WrBridge()->RemovePipelineIdForCompositable(aPipelineId); 217 } 218 /// Release TextureClient that is bounded to ImageKey. 219 /// It is used for recycling TextureClient. 220 void RenderRootStateManager::ReleaseTextureOfImage(const wr::ImageKey& aKey) { 221 WrBridge()->ReleaseTextureOfImage(aKey); 222 } 223 224 Maybe<wr::FontInstanceKey> RenderRootStateManager::GetFontKeyForScaledFont( 225 gfx::ScaledFont* aScaledFont, wr::IpcResourceUpdateQueue& aResources) { 226 return WrBridge()->GetFontKeyForScaledFont(aScaledFont, aResources); 227 } 228 229 Maybe<wr::FontKey> RenderRootStateManager::GetFontKeyForUnscaledFont( 230 gfx::UnscaledFont* aUnscaledFont, wr::IpcResourceUpdateQueue& aResources) { 231 return WrBridge()->GetFontKeyForUnscaledFont(aUnscaledFont, aResources); 232 } 233 234 } // namespace layers 235 } // namespace mozilla