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