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