MediaSystemResourceService.cpp (6290B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "MediaSystemResourceService.h" 8 9 #include "MediaSystemResourceManagerParent.h" 10 #include "mozilla/layers/CompositorThread.h" 11 12 using namespace mozilla::layers; 13 14 namespace mozilla { 15 16 /* static */ 17 StaticRefPtr<MediaSystemResourceService> MediaSystemResourceService::sSingleton; 18 19 /* static */ 20 MediaSystemResourceService* MediaSystemResourceService::Get() { 21 if (sSingleton) { 22 return sSingleton; 23 } 24 Init(); 25 return sSingleton; 26 } 27 28 /* static */ 29 void MediaSystemResourceService::Init() { 30 if (!sSingleton) { 31 sSingleton = new MediaSystemResourceService(); 32 } 33 } 34 35 /* static */ 36 void MediaSystemResourceService::Shutdown() { 37 if (sSingleton) { 38 sSingleton->Destroy(); 39 sSingleton = nullptr; 40 } 41 } 42 43 MediaSystemResourceService::MediaSystemResourceService() : mDestroyed(false) { 44 MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); 45 } 46 47 MediaSystemResourceService::~MediaSystemResourceService() = default; 48 49 void MediaSystemResourceService::Destroy() { mDestroyed = true; } 50 51 void MediaSystemResourceService::Acquire( 52 media::MediaSystemResourceManagerParent* aParent, uint32_t aId, 53 MediaSystemResourceType aResourceType, bool aWillWait) { 54 MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); 55 MOZ_ASSERT(aParent); 56 57 if (mDestroyed) { 58 return; 59 } 60 61 MediaSystemResource* resource = 62 mResources.Get(static_cast<uint32_t>(aResourceType)); 63 64 if (!resource || resource->mResourceCount == 0) { 65 // Resource does not exit 66 // Send fail response 67 (void)aParent->SendResponse(aId, false /* fail */); 68 return; 69 } 70 71 // Try to acquire a resource 72 if (resource->mAcquiredRequests.size() < resource->mResourceCount) { 73 // Resource is available 74 resource->mAcquiredRequests.push_back( 75 MediaSystemResourceRequest(aParent, aId)); 76 // Send success response 77 (void)aParent->SendResponse(aId, true /* success */); 78 return; 79 } 80 81 if (!aWillWait) { 82 // Resource is not available and do not wait. 83 // Send fail response 84 (void)aParent->SendResponse(aId, false /* fail */); 85 return; 86 } 87 // Wait until acquire. 88 resource->mWaitingRequests.push_back( 89 MediaSystemResourceRequest(aParent, aId)); 90 } 91 92 void MediaSystemResourceService::ReleaseResource( 93 media::MediaSystemResourceManagerParent* aParent, uint32_t aId, 94 MediaSystemResourceType aResourceType) { 95 MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); 96 MOZ_ASSERT(aParent); 97 98 if (mDestroyed) { 99 return; 100 } 101 102 MediaSystemResource* resource = 103 mResources.Get(static_cast<uint32_t>(aResourceType)); 104 105 if (!resource || resource->mResourceCount == 0) { 106 // Resource does not exit 107 return; 108 } 109 RemoveRequest(aParent, aId, aResourceType); 110 UpdateRequests(aResourceType); 111 } 112 113 void MediaSystemResourceService::ReleaseResource( 114 media::MediaSystemResourceManagerParent* aParent) { 115 MOZ_ASSERT(aParent); 116 117 if (mDestroyed) { 118 return; 119 } 120 121 for (const uint32_t& key : mResources.Keys()) { 122 RemoveRequests(aParent, static_cast<MediaSystemResourceType>(key)); 123 UpdateRequests(static_cast<MediaSystemResourceType>(key)); 124 } 125 } 126 127 void MediaSystemResourceService::RemoveRequest( 128 media::MediaSystemResourceManagerParent* aParent, uint32_t aId, 129 MediaSystemResourceType aResourceType) { 130 MOZ_ASSERT(aParent); 131 132 MediaSystemResource* resource = 133 mResources.Get(static_cast<uint32_t>(aResourceType)); 134 if (!resource) { 135 return; 136 } 137 138 std::deque<MediaSystemResourceRequest>::iterator it; 139 std::deque<MediaSystemResourceRequest>& acquiredRequests = 140 resource->mAcquiredRequests; 141 for (it = acquiredRequests.begin(); it != acquiredRequests.end(); it++) { 142 if (((*it).mParent == aParent) && ((*it).mId == aId)) { 143 acquiredRequests.erase(it); 144 return; 145 } 146 } 147 148 std::deque<MediaSystemResourceRequest>& waitingRequests = 149 resource->mWaitingRequests; 150 for (it = waitingRequests.begin(); it != waitingRequests.end(); it++) { 151 if (((*it).mParent == aParent) && ((*it).mId == aId)) { 152 waitingRequests.erase(it); 153 return; 154 } 155 } 156 } 157 158 void MediaSystemResourceService::RemoveRequests( 159 media::MediaSystemResourceManagerParent* aParent, 160 MediaSystemResourceType aResourceType) { 161 MOZ_ASSERT(aParent); 162 163 MediaSystemResource* resource = 164 mResources.Get(static_cast<uint32_t>(aResourceType)); 165 166 if (!resource || resource->mResourceCount == 0) { 167 // Resource does not exit 168 return; 169 } 170 171 std::deque<MediaSystemResourceRequest>::iterator it; 172 std::deque<MediaSystemResourceRequest>& acquiredRequests = 173 resource->mAcquiredRequests; 174 for (it = acquiredRequests.begin(); it != acquiredRequests.end();) { 175 if ((*it).mParent == aParent) { 176 it = acquiredRequests.erase(it); 177 } else { 178 it++; 179 } 180 } 181 182 std::deque<MediaSystemResourceRequest>& waitingRequests = 183 resource->mWaitingRequests; 184 for (it = waitingRequests.begin(); it != waitingRequests.end();) { 185 if ((*it).mParent == aParent) { 186 it = waitingRequests.erase(it); 187 } else { 188 it++; 189 } 190 } 191 } 192 193 void MediaSystemResourceService::UpdateRequests( 194 MediaSystemResourceType aResourceType) { 195 MediaSystemResource* resource = 196 mResources.Get(static_cast<uint32_t>(aResourceType)); 197 198 if (!resource || resource->mResourceCount == 0) { 199 // Resource does not exit 200 return; 201 } 202 203 std::deque<MediaSystemResourceRequest>& acquiredRequests = 204 resource->mAcquiredRequests; 205 std::deque<MediaSystemResourceRequest>& waitingRequests = 206 resource->mWaitingRequests; 207 208 while ((acquiredRequests.size() < resource->mResourceCount) && 209 (!waitingRequests.empty())) { 210 MediaSystemResourceRequest& request = waitingRequests.front(); 211 MOZ_ASSERT(request.mParent); 212 // Send response 213 (void)request.mParent->SendResponse(request.mId, true /* success */); 214 // Move request to mAcquiredRequests 215 acquiredRequests.push_back(waitingRequests.front()); 216 waitingRequests.pop_front(); 217 } 218 } 219 220 } // namespace mozilla