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