CompositeProcessD3D11FencesHolderMap.cpp (5820B)
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 "CompositeProcessD3D11FencesHolderMap.h" 8 9 #include "mozilla/layers/FenceD3D11.h" 10 #include "nsXULAppAPI.h" 11 12 namespace mozilla { 13 14 namespace layers { 15 16 StaticAutoPtr<CompositeProcessD3D11FencesHolderMap> 17 CompositeProcessD3D11FencesHolderMap::sInstance; 18 19 /* static */ 20 void CompositeProcessD3D11FencesHolderMap::Init() { 21 MOZ_ASSERT(XRE_IsGPUProcess() || XRE_IsParentProcess()); 22 sInstance = new CompositeProcessD3D11FencesHolderMap(); 23 } 24 25 /* static */ 26 void CompositeProcessD3D11FencesHolderMap::Shutdown() { 27 MOZ_ASSERT(XRE_IsGPUProcess() || XRE_IsParentProcess()); 28 sInstance = nullptr; 29 } 30 31 CompositeProcessD3D11FencesHolderMap::CompositeProcessD3D11FencesHolderMap() 32 : mMonitor("CompositeProcessD3D11FencesHolderMap::mMonitor") {} 33 34 CompositeProcessD3D11FencesHolderMap::~CompositeProcessD3D11FencesHolderMap() {} 35 36 void CompositeProcessD3D11FencesHolderMap::Register( 37 CompositeProcessFencesHolderId aHolderId) { 38 MOZ_ASSERT(aHolderId.IsValid()); 39 40 MonitorAutoLock lock(mMonitor); 41 42 DebugOnly<bool> inserted = 43 mFencesHolderById.emplace(aHolderId, MakeUnique<FencesHolder>()).second; 44 MOZ_ASSERT(inserted, "Map already contained FencesHolder for id!"); 45 } 46 47 void CompositeProcessD3D11FencesHolderMap::RegisterReference( 48 CompositeProcessFencesHolderId aHolderId) { 49 if (!aHolderId.IsValid()) { 50 return; 51 } 52 53 MonitorAutoLock lock(mMonitor); 54 55 auto it = mFencesHolderById.find(aHolderId); 56 if (it == mFencesHolderById.end()) { 57 MOZ_ASSERT_UNREACHABLE("Map missing FencesHolder for id!"); 58 return; 59 } 60 61 MOZ_ASSERT(it->second->mOwners > 0); 62 ++it->second->mOwners; 63 } 64 65 void CompositeProcessD3D11FencesHolderMap::Unregister( 66 CompositeProcessFencesHolderId aHolderId) { 67 if (!aHolderId.IsValid()) { 68 return; 69 } 70 71 MonitorAutoLock lock(mMonitor); 72 73 auto it = mFencesHolderById.find(aHolderId); 74 if (it == mFencesHolderById.end()) { 75 MOZ_ASSERT_UNREACHABLE("Map missing FencesHolder for id!"); 76 return; 77 } 78 79 MOZ_ASSERT(it->second->mOwners > 0); 80 if (--it->second->mOwners == 0) { 81 mFencesHolderById.erase(it); 82 } 83 } 84 85 void CompositeProcessD3D11FencesHolderMap::SetWriteFence( 86 CompositeProcessFencesHolderId aHolderId, RefPtr<FenceD3D11> aWriteFence) { 87 MOZ_ASSERT(aWriteFence); 88 89 if (!aWriteFence) { 90 return; 91 } 92 93 MonitorAutoLock lock(mMonitor); 94 95 MOZ_ASSERT(aHolderId.IsValid()); 96 auto it = mFencesHolderById.find(aHolderId); 97 if (it == mFencesHolderById.end()) { 98 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 99 return; 100 } 101 102 RefPtr<FenceD3D11> fence = aWriteFence->CloneFromHandle(); 103 if (!fence) { 104 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 105 return; 106 } 107 108 MOZ_ASSERT(!it->second->mWriteFence); 109 MOZ_ASSERT(it->second->mReadFences.empty()); 110 111 it->second->mWriteFence = fence; 112 } 113 114 void CompositeProcessD3D11FencesHolderMap::SetReadFence( 115 CompositeProcessFencesHolderId aHolderId, RefPtr<FenceD3D11> aReadFence) { 116 MOZ_ASSERT(aReadFence); 117 118 if (!aReadFence) { 119 return; 120 } 121 122 MonitorAutoLock lock(mMonitor); 123 124 MOZ_ASSERT(aHolderId.IsValid()); 125 auto it = mFencesHolderById.find(aHolderId); 126 if (it == mFencesHolderById.end()) { 127 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 128 return; 129 } 130 131 RefPtr<FenceD3D11> fence = aReadFence->CloneFromHandle(); 132 if (!fence) { 133 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 134 return; 135 } 136 137 it->second->mReadFences.push_back(fence); 138 } 139 140 bool CompositeProcessD3D11FencesHolderMap::WaitWriteFence( 141 CompositeProcessFencesHolderId aHolderId, ID3D11Device* aDevice) { 142 MOZ_ASSERT(aDevice); 143 144 if (!aDevice) { 145 return false; 146 } 147 148 RefPtr<FenceD3D11> writeFence; 149 { 150 MonitorAutoLock lock(mMonitor); 151 152 MOZ_ASSERT(aHolderId.IsValid()); 153 auto it = mFencesHolderById.find(aHolderId); 154 if (it == mFencesHolderById.end()) { 155 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 156 return false; 157 } 158 writeFence = it->second->mWriteFence; 159 } 160 161 if (!writeFence) { 162 return true; 163 } 164 165 return writeFence->Wait(aDevice); 166 } 167 168 std::pair<const RefPtr<gfx::FileHandleWrapper>, uint64_t> 169 CompositeProcessD3D11FencesHolderMap::GetWriteFenceHandleAndValue( 170 CompositeProcessFencesHolderId aHolderId) const { 171 MonitorAutoLock lock(mMonitor); 172 RefPtr<FenceD3D11> writeFence; 173 MOZ_ASSERT(aHolderId.IsValid()); 174 175 auto it = mFencesHolderById.find(aHolderId); 176 MOZ_ASSERT(it != mFencesHolderById.end()); 177 if (it != mFencesHolderById.end()) { 178 writeFence = it->second->mWriteFence; 179 } 180 181 if (writeFence) { 182 return {writeFence->mHandle, writeFence->GetFenceValue()}; 183 } 184 return {}; 185 } 186 187 bool CompositeProcessD3D11FencesHolderMap::WaitAllFencesAndForget( 188 CompositeProcessFencesHolderId aHolderId, ID3D11Device* aDevice) { 189 MOZ_ASSERT(aDevice); 190 191 if (!aDevice) { 192 return false; 193 } 194 195 RefPtr<FenceD3D11> writeFence; 196 std::vector<RefPtr<FenceD3D11>> readFences; 197 { 198 MonitorAutoLock lock(mMonitor); 199 200 MOZ_ASSERT(aHolderId.IsValid()); 201 auto it = mFencesHolderById.find(aHolderId); 202 if (it == mFencesHolderById.end()) { 203 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 204 return false; 205 } 206 writeFence = it->second->mWriteFence.forget(); 207 readFences.swap(it->second->mReadFences); 208 209 MOZ_ASSERT(!it->second->mWriteFence); 210 MOZ_ASSERT(it->second->mReadFences.empty()); 211 } 212 213 if (writeFence) { 214 writeFence->Wait(aDevice); 215 } 216 217 for (auto& fence : readFences) { 218 fence->Wait(aDevice); 219 } 220 221 return true; 222 } 223 224 } // namespace layers 225 } // namespace mozilla