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 
getCacheSize() const147 size_t ComposerHandleCache::getCacheSize() const {
148     return mHandles.size();
149 }
150 
initCache(HandleType type,uint32_t cacheSize)151 bool ComposerHandleCache::initCache(HandleType type, uint32_t cacheSize) {
152     // already initialized
153     if (mHandleType != HandleType::INVALID) {
154         return false;
155     }
156 
157     mHandleType = type;
158     mHandles.resize(cacheSize, nullptr);
159 
160     return true;
161 }
162 
lookupCache(uint32_t slot,const native_handle_t ** outHandle)163 Error ComposerHandleCache::lookupCache(uint32_t slot, const native_handle_t** outHandle) {
164     if (slot >= 0 && slot < mHandles.size()) {
165         *outHandle = mHandles[slot];
166         return Error::NONE;
167     } else {
168         return Error::BAD_PARAMETER;
169     }
170 }
171 
updateCache(uint32_t slot,const native_handle_t * handle,const native_handle ** outReplacedHandle)172 Error ComposerHandleCache::updateCache(uint32_t slot, const native_handle_t* handle,
173                                        const native_handle** outReplacedHandle) {
174     if (slot >= 0 && slot < mHandles.size()) {
175         auto& cachedHandle = mHandles[slot];
176         *outReplacedHandle = cachedHandle;
177         cachedHandle = handle;
178         return Error::NONE;
179     } else {
180         return Error::BAD_PARAMETER;
181     }
182 }
183 
184 // 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)185 Error ComposerHandleCache::getHandle(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
186                                      const native_handle_t** outHandle,
187                                      const native_handle** outReplacedHandle) {
188     if (fromCache) {
189         *outReplacedHandle = nullptr;
190         return lookupCache(slot, outHandle);
191     } else {
192         *outHandle = inHandle;
193         return updateCache(slot, inHandle, outReplacedHandle);
194     }
195 }
196 
ComposerLayerResource(ComposerHandleImporter & importer,uint32_t bufferCacheSize)197 ComposerLayerResource::ComposerLayerResource(ComposerHandleImporter& importer,
198                                              uint32_t bufferCacheSize)
199     : mBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, bufferCacheSize),
200       mSidebandStreamCache(importer, ComposerHandleCache::HandleType::STREAM, 1) {}
201 
getBuffer(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)202 Error ComposerLayerResource::getBuffer(uint32_t slot, bool fromCache,
203                                        const native_handle_t* inHandle,
204                                        const native_handle_t** outHandle,
205                                        const native_handle** outReplacedHandle) {
206     return mBufferCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
207 }
208 
getSidebandStream(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)209 Error ComposerLayerResource::getSidebandStream(uint32_t slot, bool fromCache,
210                                                const native_handle_t* inHandle,
211                                                const native_handle_t** outHandle,
212                                                const native_handle** outReplacedHandle) {
213     return mSidebandStreamCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
214 }
215 
ComposerDisplayResource(DisplayType type,ComposerHandleImporter & importer,uint32_t outputBufferCacheSize)216 ComposerDisplayResource::ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
217                                                  uint32_t outputBufferCacheSize)
218     : mType(type),
219       mClientTargetCache(importer),
220       mOutputBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, outputBufferCacheSize),
221       mMustValidate(true) {}
222 
initClientTargetCache(uint32_t cacheSize)223 bool ComposerDisplayResource::initClientTargetCache(uint32_t cacheSize) {
224     return mClientTargetCache.initCache(ComposerHandleCache::HandleType::BUFFER, cacheSize);
225 }
226 
getClientTargetCacheSize() const227 size_t ComposerDisplayResource::getClientTargetCacheSize() const {
228     return mClientTargetCache.getCacheSize();
229 }
230 
getOutputBufferCacheSize() const231 size_t ComposerDisplayResource::getOutputBufferCacheSize() const {
232     return mOutputBufferCache.getCacheSize();
233 }
234 
isVirtual() const235 bool ComposerDisplayResource::isVirtual() const {
236     return mType == DisplayType::VIRTUAL;
237 }
238 
getClientTarget(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)239 Error ComposerDisplayResource::getClientTarget(uint32_t slot, bool fromCache,
240                                                const native_handle_t* inHandle,
241                                                const native_handle_t** outHandle,
242                                                const native_handle** outReplacedHandle) {
243     return mClientTargetCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
244 }
245 
getOutputBuffer(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)246 Error ComposerDisplayResource::getOutputBuffer(uint32_t slot, bool fromCache,
247                                                const native_handle_t* inHandle,
248                                                const native_handle_t** outHandle,
249                                                const native_handle** outReplacedHandle) {
250     return mOutputBufferCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
251 }
252 
addLayer(Layer layer,std::unique_ptr<ComposerLayerResource> layerResource)253 bool ComposerDisplayResource::addLayer(Layer layer,
254                                        std::unique_ptr<ComposerLayerResource> layerResource) {
255     auto result = mLayerResources.emplace(layer, std::move(layerResource));
256     return result.second;
257 }
258 
removeLayer(Layer layer)259 bool ComposerDisplayResource::removeLayer(Layer layer) {
260     return mLayerResources.erase(layer) > 0;
261 }
262 
findLayerResource(Layer layer)263 ComposerLayerResource* ComposerDisplayResource::findLayerResource(Layer layer) {
264     auto layerIter = mLayerResources.find(layer);
265     if (layerIter == mLayerResources.end()) {
266         return nullptr;
267     }
268 
269     return layerIter->second.get();
270 }
271 
getLayers() const272 std::vector<Layer> ComposerDisplayResource::getLayers() const {
273     std::vector<Layer> layers;
274     layers.reserve(mLayerResources.size());
275     for (const auto& layerKey : mLayerResources) {
276         layers.push_back(layerKey.first);
277     }
278     return layers;
279 }
280 
setMustValidateState(bool mustValidate)281 void ComposerDisplayResource::setMustValidateState(bool mustValidate) {
282     mMustValidate = mustValidate;
283 }
284 
mustValidate() const285 bool ComposerDisplayResource::mustValidate() const {
286     return mMustValidate;
287 }
288 
create()289 std::unique_ptr<ComposerResources> ComposerResources::create() {
290     auto resources = std::make_unique<ComposerResources>();
291     return resources->init() ? std::move(resources) : nullptr;
292 }
293 
init()294 bool ComposerResources::init() {
295     return mImporter.init();
296 }
297 
clear(RemoveDisplay removeDisplay)298 void ComposerResources::clear(RemoveDisplay removeDisplay) {
299     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
300     for (const auto& displayKey : mDisplayResources) {
301         Display display = displayKey.first;
302         const ComposerDisplayResource& displayResource = *displayKey.second;
303         removeDisplay(display, displayResource.isVirtual(), displayResource.getLayers());
304     }
305     mDisplayResources.clear();
306 }
307 
hasDisplay(Display display)308 bool ComposerResources::hasDisplay(Display display) {
309     return mDisplayResources.count(display) > 0;
310 }
311 
addPhysicalDisplay(Display display)312 Error ComposerResources::addPhysicalDisplay(Display display) {
313     auto displayResource = createDisplayResource(ComposerDisplayResource::DisplayType::PHYSICAL, 0);
314 
315     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
316     auto result = mDisplayResources.emplace(display, std::move(displayResource));
317     return result.second ? Error::NONE : Error::BAD_DISPLAY;
318 }
319 
addVirtualDisplay(Display display,uint32_t outputBufferCacheSize)320 Error ComposerResources::addVirtualDisplay(Display display, uint32_t outputBufferCacheSize) {
321     auto displayResource = createDisplayResource(ComposerDisplayResource::DisplayType::VIRTUAL,
322                                                  outputBufferCacheSize);
323 
324     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
325     auto result = mDisplayResources.emplace(display, std::move(displayResource));
326     return result.second ? Error::NONE : Error::BAD_DISPLAY;
327 }
328 
removeDisplay(Display display)329 Error ComposerResources::removeDisplay(Display display) {
330     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
331     return mDisplayResources.erase(display) > 0 ? Error::NONE : Error::BAD_DISPLAY;
332 }
333 
setDisplayClientTargetCacheSize(Display display,uint32_t clientTargetCacheSize)334 Error ComposerResources::setDisplayClientTargetCacheSize(Display display,
335                                                          uint32_t clientTargetCacheSize) {
336     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
337     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
338     if (!displayResource) {
339         return Error::BAD_DISPLAY;
340     }
341 
342     return displayResource->initClientTargetCache(clientTargetCacheSize) ? Error::NONE
343                                                                          : Error::BAD_PARAMETER;
344 }
345 
getDisplayClientTargetCacheSize(Display display,size_t * outCacheSize)346 Error ComposerResources::getDisplayClientTargetCacheSize(Display display, size_t* outCacheSize) {
347     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
348     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
349     if (!displayResource) {
350         return Error::BAD_DISPLAY;
351     }
352     *outCacheSize = displayResource->getClientTargetCacheSize();
353     return Error::NONE;
354 }
355 
getDisplayOutputBufferCacheSize(Display display,size_t * outCacheSize)356 Error ComposerResources::getDisplayOutputBufferCacheSize(Display display, size_t* outCacheSize) {
357     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
358     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
359     if (!displayResource) {
360         return Error::BAD_DISPLAY;
361     }
362     *outCacheSize = displayResource->getOutputBufferCacheSize();
363     return Error::NONE;
364 }
365 
addLayer(Display display,Layer layer,uint32_t bufferCacheSize)366 Error ComposerResources::addLayer(Display display, Layer layer, uint32_t bufferCacheSize) {
367     auto layerResource = createLayerResource(bufferCacheSize);
368 
369     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
370     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
371     if (!displayResource) {
372         return Error::BAD_DISPLAY;
373     }
374 
375     return displayResource->addLayer(layer, std::move(layerResource)) ? Error::NONE
376                                                                       : Error::BAD_LAYER;
377 }
378 
removeLayer(Display display,Layer layer)379 Error ComposerResources::removeLayer(Display display, Layer layer) {
380     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
381     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
382     if (!displayResource) {
383         return Error::BAD_DISPLAY;
384     }
385 
386     return displayResource->removeLayer(layer) ? Error::NONE : Error::BAD_LAYER;
387 }
388 
getDisplayClientTarget(Display display,uint32_t slot,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle,ReplacedHandle * outReplacedBuffer)389 Error ComposerResources::getDisplayClientTarget(Display display, uint32_t slot, bool fromCache,
390                                                 const native_handle_t* rawHandle,
391                                                 const native_handle_t** outBufferHandle,
392                                                 ReplacedHandle* outReplacedBuffer) {
393     return getHandle(display, 0, slot, Cache::CLIENT_TARGET, fromCache, rawHandle, outBufferHandle,
394                      outReplacedBuffer);
395 }
396 
getDisplayOutputBuffer(Display display,uint32_t slot,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle,ReplacedHandle * outReplacedBuffer)397 Error ComposerResources::getDisplayOutputBuffer(Display display, uint32_t slot, bool fromCache,
398                                                 const native_handle_t* rawHandle,
399                                                 const native_handle_t** outBufferHandle,
400                                                 ReplacedHandle* outReplacedBuffer) {
401     return getHandle(display, 0, slot, Cache::OUTPUT_BUFFER, fromCache, rawHandle, outBufferHandle,
402                      outReplacedBuffer);
403 }
404 
getLayerBuffer(Display display,Layer layer,uint32_t slot,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle,ReplacedHandle * outReplacedBuffer)405 Error ComposerResources::getLayerBuffer(Display display, Layer layer, uint32_t slot, bool fromCache,
406                                         const native_handle_t* rawHandle,
407                                         const native_handle_t** outBufferHandle,
408                                         ReplacedHandle* outReplacedBuffer) {
409     return getHandle(display, layer, slot, Cache::LAYER_BUFFER, fromCache, rawHandle,
410                      outBufferHandle, outReplacedBuffer);
411 }
412 
getLayerSidebandStream(Display display,Layer layer,const native_handle_t * rawHandle,const native_handle_t ** outStreamHandle,ReplacedHandle * outReplacedStream)413 Error ComposerResources::getLayerSidebandStream(Display display, Layer layer,
414                                                 const native_handle_t* rawHandle,
415                                                 const native_handle_t** outStreamHandle,
416                                                 ReplacedHandle* outReplacedStream) {
417     return getHandle(display, layer, 0, Cache::LAYER_SIDEBAND_STREAM, false, rawHandle,
418                      outStreamHandle, outReplacedStream);
419 }
420 
setDisplayMustValidateState(Display display,bool mustValidate)421 void ComposerResources::setDisplayMustValidateState(Display display, bool mustValidate) {
422     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
423     auto* displayResource = findDisplayResourceLocked(display);
424     if (displayResource) {
425         displayResource->setMustValidateState(mustValidate);
426     }
427 }
428 
mustValidateDisplay(Display display)429 bool ComposerResources::mustValidateDisplay(Display display) {
430     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
431     auto* displayResource = findDisplayResourceLocked(display);
432     if (displayResource) {
433         return displayResource->mustValidate();
434     }
435     return false;
436 }
437 
createDisplayResource(ComposerDisplayResource::DisplayType type,uint32_t outputBufferCacheSize)438 std::unique_ptr<ComposerDisplayResource> ComposerResources::createDisplayResource(
439         ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) {
440     return std::make_unique<ComposerDisplayResource>(type, mImporter, outputBufferCacheSize);
441 }
442 
createLayerResource(uint32_t bufferCacheSize)443 std::unique_ptr<ComposerLayerResource> ComposerResources::createLayerResource(
444         uint32_t bufferCacheSize) {
445     return std::make_unique<ComposerLayerResource>(mImporter, bufferCacheSize);
446 }
447 
findDisplayResourceLocked(Display display)448 ComposerDisplayResource* ComposerResources::findDisplayResourceLocked(Display display) {
449     auto iter = mDisplayResources.find(display);
450     if (iter == mDisplayResources.end()) {
451         return nullptr;
452     }
453     return iter->second.get();
454 }
455 
getHandle(Display display,Layer layer,uint32_t slot,Cache cache,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outHandle,ReplacedHandle * outReplacedHandle)456 Error ComposerResources::getHandle(Display display, Layer layer, uint32_t slot, Cache cache,
457                                    bool fromCache, const native_handle_t* rawHandle,
458                                    const native_handle_t** outHandle,
459                                    ReplacedHandle* outReplacedHandle) {
460     Error error;
461 
462     // import the raw handle (or ignore raw handle when fromCache is true)
463     const native_handle_t* importedHandle = nullptr;
464     if (!fromCache) {
465         error = (outReplacedHandle->isBuffer())
466                         ? mImporter.importBuffer(rawHandle, &importedHandle)
467                         : mImporter.importStream(rawHandle, &importedHandle);
468         if (error != Error::NONE) {
469             return error;
470         }
471     }
472 
473     std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
474 
475     // find display/layer resource
476     const bool needLayerResource = (cache == ComposerResources::Cache::LAYER_BUFFER ||
477                                     cache == ComposerResources::Cache::LAYER_SIDEBAND_STREAM);
478     ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
479     ComposerLayerResource* layerResource = (displayResource && needLayerResource)
480                                                    ? displayResource->findLayerResource(layer)
481                                                    : nullptr;
482 
483     // lookup or update cache
484     const native_handle_t* replacedHandle = nullptr;
485     if (displayResource && (!needLayerResource || layerResource)) {
486         switch (cache) {
487             case ComposerResources::Cache::CLIENT_TARGET:
488                 error = displayResource->getClientTarget(slot, fromCache, importedHandle, outHandle,
489                                                          &replacedHandle);
490                 break;
491             case ComposerResources::Cache::OUTPUT_BUFFER:
492                 error = displayResource->getOutputBuffer(slot, fromCache, importedHandle, outHandle,
493                                                          &replacedHandle);
494                 break;
495             case ComposerResources::Cache::LAYER_BUFFER:
496                 error = layerResource->getBuffer(slot, fromCache, importedHandle, outHandle,
497                                                  &replacedHandle);
498                 break;
499             case ComposerResources::Cache::LAYER_SIDEBAND_STREAM:
500                 error = layerResource->getSidebandStream(slot, fromCache, importedHandle, outHandle,
501                                                          &replacedHandle);
502                 break;
503             default:
504                 error = Error::BAD_PARAMETER;
505                 break;
506         }
507 
508         if (error != Error::NONE) {
509             ALOGW("invalid cache %d slot %d", int(cache), int(slot));
510         }
511     } else if (!displayResource) {
512         error = Error::BAD_DISPLAY;
513     } else {
514         error = Error::BAD_LAYER;
515     }
516 
517     // clean up on errors
518     if (error != Error::NONE) {
519         if (!fromCache) {
520             if (outReplacedHandle->isBuffer()) {
521                 mImporter.freeBuffer(importedHandle);
522             } else {
523                 mImporter.freeStream(importedHandle);
524             }
525         }
526         return error;
527     }
528 
529     outReplacedHandle->reset(&mImporter, replacedHandle);
530 
531     return Error::NONE;
532 }
533 
534 }  // namespace hal
535 }  // namespace V2_1
536 }  // namespace composer
537 }  // namespace graphics
538 }  // namespace hardware
539 }  // namespace android
540