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