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