• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "ComposerResources"
18 
19 #include "composer-resources/2.1/ComposerResources.h"
20 
21 #include <ui/GraphicBufferMapper.h>
22 
23 namespace android {
24 namespace hardware {
25 namespace graphics {
26 namespace composer {
27 namespace V2_1 {
28 namespace hal {
29 
ComposerHandleImporter()30 ComposerHandleImporter::ComposerHandleImporter() : mMapper{GraphicBufferMapper::get()} {}
31 
init()32 bool ComposerHandleImporter::init() {
33     return true;
34 }
35 
importBuffer(const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle)36 Error ComposerHandleImporter::importBuffer(const native_handle_t* rawHandle,
37                                            const native_handle_t** outBufferHandle) {
38     if (!rawHandle || (!rawHandle->numFds && !rawHandle->numInts)) {
39         *outBufferHandle = nullptr;
40         return Error::NONE;
41     }
42 
43     status_t status = mMapper.importBufferNoValidate(rawHandle, outBufferHandle);
44     if (status == STATUS_OK) {
45         return Error::NONE;
46     } else {
47         return Error::NO_RESOURCES;
48     }
49 }
50 
freeBuffer(const native_handle_t * bufferHandle)51 void ComposerHandleImporter::freeBuffer(const native_handle_t* bufferHandle) {
52     if (bufferHandle) {
53         mMapper.freeBuffer(bufferHandle);
54     }
55 }
56 
importStream(const native_handle_t * rawHandle,const native_handle_t ** outStreamHandle)57 Error ComposerHandleImporter::importStream(const native_handle_t* rawHandle,
58                                            const native_handle_t** outStreamHandle) {
59     const native_handle_t* streamHandle = nullptr;
60     if (rawHandle) {
61         streamHandle = native_handle_clone(rawHandle);
62         if (!streamHandle) {
63             return Error::NO_RESOURCES;
64         }
65     }
66 
67     *outStreamHandle = streamHandle;
68     return Error::NONE;
69 }
70 
freeStream(const native_handle_t * streamHandle)71 void ComposerHandleImporter::freeStream(const native_handle_t* streamHandle) {
72     if (streamHandle) {
73         native_handle_close(streamHandle);
74         native_handle_delete(const_cast<native_handle_t*>(streamHandle));
75     }
76 }
77 
ComposerHandleCache(ComposerHandleImporter & importer,HandleType type,uint32_t cacheSize)78 ComposerHandleCache::ComposerHandleCache(ComposerHandleImporter& importer, HandleType type,
79                                          uint32_t cacheSize)
80     : mImporter(importer), mHandleType(type), mHandles(cacheSize, nullptr) {}
81 
82 // must be initialized later with initCache
ComposerHandleCache(ComposerHandleImporter & importer)83 ComposerHandleCache::ComposerHandleCache(ComposerHandleImporter& importer) : mImporter(importer) {}
84 
~ComposerHandleCache()85 ComposerHandleCache::~ComposerHandleCache() {
86     switch (mHandleType) {
87         case HandleType::BUFFER:
88             for (auto handle : mHandles) {
89                 mImporter.freeBuffer(handle);
90             }
91             break;
92         case HandleType::STREAM:
93             for (auto handle : mHandles) {
94                 mImporter.freeStream(handle);
95             }
96             break;
97         default:
98             break;
99     }
100 }
101 
getCacheSize() const102 size_t ComposerHandleCache::getCacheSize() const {
103     return mHandles.size();
104 }
105 
initCache(HandleType type,uint32_t cacheSize)106 bool ComposerHandleCache::initCache(HandleType type, uint32_t cacheSize) {
107     // already initialized
108     if (mHandleType != HandleType::INVALID) {
109         return false;
110     }
111 
112     mHandleType = type;
113     mHandles.resize(cacheSize, nullptr);
114 
115     return true;
116 }
117 
lookupCache(uint32_t slot,const native_handle_t ** outHandle)118 Error ComposerHandleCache::lookupCache(uint32_t slot, const native_handle_t** outHandle) {
119     if (slot >= 0 && slot < mHandles.size()) {
120         *outHandle = mHandles[slot];
121         return Error::NONE;
122     } else {
123         return Error::BAD_PARAMETER;
124     }
125 }
126 
updateCache(uint32_t slot,const native_handle_t * handle,const native_handle ** outReplacedHandle)127 Error ComposerHandleCache::updateCache(uint32_t slot, const native_handle_t* handle,
128                                        const native_handle** outReplacedHandle) {
129     if (slot >= 0 && slot < mHandles.size()) {
130         auto& cachedHandle = mHandles[slot];
131         *outReplacedHandle = cachedHandle;
132         cachedHandle = handle;
133         return Error::NONE;
134     } else {
135         return Error::BAD_PARAMETER;
136     }
137 }
138 
139 // when fromCache is true, look up in the cache; otherwise, update the cache
getHandle(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)140 Error ComposerHandleCache::getHandle(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
141                                      const native_handle_t** outHandle,
142                                      const native_handle** outReplacedHandle) {
143     if (fromCache) {
144         *outReplacedHandle = nullptr;
145         return lookupCache(slot, outHandle);
146     } else {
147         *outHandle = inHandle;
148         return updateCache(slot, inHandle, outReplacedHandle);
149     }
150 }
151 
ComposerLayerResource(ComposerHandleImporter & importer,uint32_t bufferCacheSize)152 ComposerLayerResource::ComposerLayerResource(ComposerHandleImporter& importer,
153                                              uint32_t bufferCacheSize)
154     : mBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, bufferCacheSize),
155       mSidebandStreamCache(importer, ComposerHandleCache::HandleType::STREAM, 1) {}
156 
getBuffer(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)157 Error ComposerLayerResource::getBuffer(uint32_t slot, bool fromCache,
158                                        const native_handle_t* inHandle,
159                                        const native_handle_t** outHandle,
160                                        const native_handle** outReplacedHandle) {
161     return mBufferCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
162 }
163 
getSidebandStream(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)164 Error ComposerLayerResource::getSidebandStream(uint32_t slot, bool fromCache,
165                                                const native_handle_t* inHandle,
166                                                const native_handle_t** outHandle,
167                                                const native_handle** outReplacedHandle) {
168     return mSidebandStreamCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
169 }
170 
ComposerDisplayResource(DisplayType type,ComposerHandleImporter & importer,uint32_t outputBufferCacheSize)171 ComposerDisplayResource::ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
172                                                  uint32_t outputBufferCacheSize)
173     : mType(type),
174       mClientTargetCache(importer),
175       mOutputBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, outputBufferCacheSize),
176       mMustValidate(true) {}
177 
initClientTargetCache(uint32_t cacheSize)178 bool ComposerDisplayResource::initClientTargetCache(uint32_t cacheSize) {
179     return mClientTargetCache.initCache(ComposerHandleCache::HandleType::BUFFER, cacheSize);
180 }
181 
getClientTargetCacheSize() const182 size_t ComposerDisplayResource::getClientTargetCacheSize() const {
183     return mClientTargetCache.getCacheSize();
184 }
185 
getOutputBufferCacheSize() const186 size_t ComposerDisplayResource::getOutputBufferCacheSize() const {
187     return mOutputBufferCache.getCacheSize();
188 }
189 
isVirtual() const190 bool ComposerDisplayResource::isVirtual() const {
191     return mType == DisplayType::VIRTUAL;
192 }
193 
getClientTarget(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)194 Error ComposerDisplayResource::getClientTarget(uint32_t slot, bool fromCache,
195                                                const native_handle_t* inHandle,
196                                                const native_handle_t** outHandle,
197                                                const native_handle** outReplacedHandle) {
198     return mClientTargetCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
199 }
200 
getOutputBuffer(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)201 Error ComposerDisplayResource::getOutputBuffer(uint32_t slot, bool fromCache,
202                                                const native_handle_t* inHandle,
203                                                const native_handle_t** outHandle,
204                                                const native_handle** outReplacedHandle) {
205     return mOutputBufferCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
206 }
207 
addLayer(Layer layer,std::unique_ptr<ComposerLayerResource> layerResource)208 bool ComposerDisplayResource::addLayer(Layer layer,
209                                        std::unique_ptr<ComposerLayerResource> layerResource) {
210     auto result = mLayerResources.emplace(layer, std::move(layerResource));
211     return result.second;
212 }
213 
removeLayer(Layer layer)214 bool ComposerDisplayResource::removeLayer(Layer layer) {
215     return mLayerResources.erase(layer) > 0;
216 }
217 
findLayerResource(Layer layer)218 ComposerLayerResource* ComposerDisplayResource::findLayerResource(Layer layer) {
219     auto layerIter = mLayerResources.find(layer);
220     if (layerIter == mLayerResources.end()) {
221         return nullptr;
222     }
223 
224     return layerIter->second.get();
225 }
226 
getLayers() const227 std::vector<Layer> ComposerDisplayResource::getLayers() const {
228     std::vector<Layer> layers;
229     layers.reserve(mLayerResources.size());
230     for (const auto& layerKey : mLayerResources) {
231         layers.push_back(layerKey.first);
232     }
233     return layers;
234 }
235 
setMustValidateState(bool mustValidate)236 void ComposerDisplayResource::setMustValidateState(bool mustValidate) {
237     mMustValidate = mustValidate;
238 }
239 
mustValidate() const240 bool ComposerDisplayResource::mustValidate() const {
241     return mMustValidate;
242 }
243 
create()244 std::unique_ptr<ComposerResources> ComposerResources::create() {
245     auto resources = std::make_unique<ComposerResources>();
246     return resources->init() ? std::move(resources) : nullptr;
247 }
248 
init()249 bool ComposerResources::init() {
250     return mImporter.init();
251 }
252 
clear(RemoveDisplay removeDisplay)253 void ComposerResources::clear(RemoveDisplay removeDisplay) {
254     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
255     for (const auto& displayKey : mDisplayResources) {
256         Display display = displayKey.first;
257         const ComposerDisplayResource& displayResource = *displayKey.second;
258         removeDisplay(display, displayResource.isVirtual(), displayResource.getLayers());
259     }
260     mDisplayResources.clear();
261 }
262 
hasDisplay(Display display)263 bool ComposerResources::hasDisplay(Display display) {
264     return mDisplayResources.count(display) > 0;
265 }
266 
addPhysicalDisplay(Display display)267 Error ComposerResources::addPhysicalDisplay(Display display) {
268     auto displayResource = createDisplayResource(ComposerDisplayResource::DisplayType::PHYSICAL, 0);
269 
270     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
271     auto result = mDisplayResources.emplace(display, std::move(displayResource));
272     return result.second ? Error::NONE : Error::BAD_DISPLAY;
273 }
274 
addVirtualDisplay(Display display,uint32_t outputBufferCacheSize)275 Error ComposerResources::addVirtualDisplay(Display display, uint32_t outputBufferCacheSize) {
276     auto displayResource = createDisplayResource(ComposerDisplayResource::DisplayType::VIRTUAL,
277                                                  outputBufferCacheSize);
278 
279     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
280     auto result = mDisplayResources.emplace(display, std::move(displayResource));
281     return result.second ? Error::NONE : Error::BAD_DISPLAY;
282 }
283 
removeDisplay(Display display)284 Error ComposerResources::removeDisplay(Display display) {
285     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
286     return mDisplayResources.erase(display) > 0 ? Error::NONE : Error::BAD_DISPLAY;
287 }
288 
setDisplayClientTargetCacheSize(Display display,uint32_t clientTargetCacheSize)289 Error ComposerResources::setDisplayClientTargetCacheSize(Display display,
290                                                          uint32_t clientTargetCacheSize) {
291     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
292     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
293     if (!displayResource) {
294         return Error::BAD_DISPLAY;
295     }
296 
297     return displayResource->initClientTargetCache(clientTargetCacheSize) ? Error::NONE
298                                                                          : Error::BAD_PARAMETER;
299 }
300 
getDisplayClientTargetCacheSize(Display display,size_t * outCacheSize)301 Error ComposerResources::getDisplayClientTargetCacheSize(Display display, size_t* outCacheSize) {
302     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
303     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
304     if (!displayResource) {
305         return Error::BAD_DISPLAY;
306     }
307     *outCacheSize = displayResource->getClientTargetCacheSize();
308     return Error::NONE;
309 }
310 
getDisplayOutputBufferCacheSize(Display display,size_t * outCacheSize)311 Error ComposerResources::getDisplayOutputBufferCacheSize(Display display, size_t* outCacheSize) {
312     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
313     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
314     if (!displayResource) {
315         return Error::BAD_DISPLAY;
316     }
317     *outCacheSize = displayResource->getOutputBufferCacheSize();
318     return Error::NONE;
319 }
320 
addLayer(Display display,Layer layer,uint32_t bufferCacheSize)321 Error ComposerResources::addLayer(Display display, Layer layer, uint32_t bufferCacheSize) {
322     auto layerResource = createLayerResource(bufferCacheSize);
323 
324     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
325     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
326     if (!displayResource) {
327         return Error::BAD_DISPLAY;
328     }
329 
330     return displayResource->addLayer(layer, std::move(layerResource)) ? Error::NONE
331                                                                       : Error::BAD_LAYER;
332 }
333 
removeLayer(Display display,Layer layer)334 Error ComposerResources::removeLayer(Display display, Layer layer) {
335     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
336     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
337     if (!displayResource) {
338         return Error::BAD_DISPLAY;
339     }
340 
341     return displayResource->removeLayer(layer) ? Error::NONE : Error::BAD_LAYER;
342 }
343 
getDisplayClientTarget(Display display,uint32_t slot,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle,ReplacedHandle * outReplacedBuffer)344 Error ComposerResources::getDisplayClientTarget(Display display, uint32_t slot, bool fromCache,
345                                                 const native_handle_t* rawHandle,
346                                                 const native_handle_t** outBufferHandle,
347                                                 ReplacedHandle* outReplacedBuffer) {
348     return getHandle(display, 0, slot, Cache::CLIENT_TARGET, fromCache, rawHandle, outBufferHandle,
349                      outReplacedBuffer);
350 }
351 
getDisplayOutputBuffer(Display display,uint32_t slot,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle,ReplacedHandle * outReplacedBuffer)352 Error ComposerResources::getDisplayOutputBuffer(Display display, uint32_t slot, bool fromCache,
353                                                 const native_handle_t* rawHandle,
354                                                 const native_handle_t** outBufferHandle,
355                                                 ReplacedHandle* outReplacedBuffer) {
356     return getHandle(display, 0, slot, Cache::OUTPUT_BUFFER, fromCache, rawHandle, outBufferHandle,
357                      outReplacedBuffer);
358 }
359 
getLayerBuffer(Display display,Layer layer,uint32_t slot,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle,ReplacedHandle * outReplacedBuffer)360 Error ComposerResources::getLayerBuffer(Display display, Layer layer, uint32_t slot, bool fromCache,
361                                         const native_handle_t* rawHandle,
362                                         const native_handle_t** outBufferHandle,
363                                         ReplacedHandle* outReplacedBuffer) {
364     return getHandle(display, layer, slot, Cache::LAYER_BUFFER, fromCache, rawHandle,
365                      outBufferHandle, outReplacedBuffer);
366 }
367 
getLayerSidebandStream(Display display,Layer layer,const native_handle_t * rawHandle,const native_handle_t ** outStreamHandle,ReplacedHandle * outReplacedStream)368 Error ComposerResources::getLayerSidebandStream(Display display, Layer layer,
369                                                 const native_handle_t* rawHandle,
370                                                 const native_handle_t** outStreamHandle,
371                                                 ReplacedHandle* outReplacedStream) {
372     return getHandle(display, layer, 0, Cache::LAYER_SIDEBAND_STREAM, false, rawHandle,
373                      outStreamHandle, outReplacedStream);
374 }
375 
setDisplayMustValidateState(Display display,bool mustValidate)376 void ComposerResources::setDisplayMustValidateState(Display display, bool mustValidate) {
377     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
378     auto* displayResource = findDisplayResourceLocked(display);
379     if (displayResource) {
380         displayResource->setMustValidateState(mustValidate);
381     }
382 }
383 
mustValidateDisplay(Display display)384 bool ComposerResources::mustValidateDisplay(Display display) {
385     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
386     auto* displayResource = findDisplayResourceLocked(display);
387     if (displayResource) {
388         return displayResource->mustValidate();
389     }
390     return false;
391 }
392 
createDisplayResource(ComposerDisplayResource::DisplayType type,uint32_t outputBufferCacheSize)393 std::unique_ptr<ComposerDisplayResource> ComposerResources::createDisplayResource(
394         ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) {
395     return std::make_unique<ComposerDisplayResource>(type, mImporter, outputBufferCacheSize);
396 }
397 
createLayerResource(uint32_t bufferCacheSize)398 std::unique_ptr<ComposerLayerResource> ComposerResources::createLayerResource(
399         uint32_t bufferCacheSize) {
400     return std::make_unique<ComposerLayerResource>(mImporter, bufferCacheSize);
401 }
402 
findDisplayResourceLocked(Display display)403 ComposerDisplayResource* ComposerResources::findDisplayResourceLocked(Display display) {
404     auto iter = mDisplayResources.find(display);
405     if (iter == mDisplayResources.end()) {
406         return nullptr;
407     }
408     return iter->second.get();
409 }
410 
getHandle(Display display,Layer layer,uint32_t slot,Cache cache,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outHandle,ReplacedHandle * outReplacedHandle)411 Error ComposerResources::getHandle(Display display, Layer layer, uint32_t slot, Cache cache,
412                                    bool fromCache, const native_handle_t* rawHandle,
413                                    const native_handle_t** outHandle,
414                                    ReplacedHandle* outReplacedHandle) {
415     Error error;
416 
417     // import the raw handle (or ignore raw handle when fromCache is true)
418     const native_handle_t* importedHandle = nullptr;
419     if (!fromCache) {
420         error = (outReplacedHandle->isBuffer())
421                         ? mImporter.importBuffer(rawHandle, &importedHandle)
422                         : mImporter.importStream(rawHandle, &importedHandle);
423         if (error != Error::NONE) {
424             return error;
425         }
426     }
427 
428     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
429 
430     // find display/layer resource
431     const bool needLayerResource = (cache == ComposerResources::Cache::LAYER_BUFFER ||
432                                     cache == ComposerResources::Cache::LAYER_SIDEBAND_STREAM);
433     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
434     ComposerLayerResource* layerResource = (displayResource && needLayerResource)
435                                                    ? displayResource->findLayerResource(layer)
436                                                    : nullptr;
437 
438     // lookup or update cache
439     const native_handle_t* replacedHandle = nullptr;
440     if (displayResource && (!needLayerResource || layerResource)) {
441         switch (cache) {
442             case ComposerResources::Cache::CLIENT_TARGET:
443                 error = displayResource->getClientTarget(slot, fromCache, importedHandle, outHandle,
444                                                          &replacedHandle);
445                 break;
446             case ComposerResources::Cache::OUTPUT_BUFFER:
447                 error = displayResource->getOutputBuffer(slot, fromCache, importedHandle, outHandle,
448                                                          &replacedHandle);
449                 break;
450             case ComposerResources::Cache::LAYER_BUFFER:
451                 error = layerResource->getBuffer(slot, fromCache, importedHandle, outHandle,
452                                                  &replacedHandle);
453                 break;
454             case ComposerResources::Cache::LAYER_SIDEBAND_STREAM:
455                 error = layerResource->getSidebandStream(slot, fromCache, importedHandle, outHandle,
456                                                          &replacedHandle);
457                 break;
458             default:
459                 error = Error::BAD_PARAMETER;
460                 break;
461         }
462 
463         if (error != Error::NONE) {
464             ALOGW("invalid cache %d slot %d", int(cache), int(slot));
465         }
466     } else if (!displayResource) {
467         error = Error::BAD_DISPLAY;
468     } else {
469         error = Error::BAD_LAYER;
470     }
471 
472     // clean up on errors
473     if (error != Error::NONE) {
474         if (!fromCache) {
475             if (outReplacedHandle->isBuffer()) {
476                 mImporter.freeBuffer(importedHandle);
477             } else {
478                 mImporter.freeStream(importedHandle);
479             }
480         }
481         return error;
482     }
483 
484     outReplacedHandle->reset(&mImporter, replacedHandle);
485 
486     return Error::NONE;
487 }
488 
489 }  // namespace hal
490 }  // namespace V2_1
491 }  // namespace composer
492 }  // namespace graphics
493 }  // namespace hardware
494 }  // namespace android
495