Coverage Report

Created: 2018-09-25 14:53

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