tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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