blob: e52bf7124a5f0d5c6ae60db9d32778f04f9ac746 [file] [log] [blame]
Marissa Walla8c31302019-08-15 14:42:50 -07001/*
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
21namespace android {
22namespace hardware {
23namespace graphics {
24namespace composer {
25namespace V2_1 {
26namespace hal {
27
28bool ComposerHandleImporter::init() {
Marissa Wallb96c2eb2019-06-20 13:30:10 -070029 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
Marissa Walla8c31302019-08-15 14:42:50 -070035 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
47Error 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 }
Marissa Wallb96c2eb2019-06-20 13:30:10 -070075 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 }
Marissa Walla8c31302019-08-15 14:42:50 -070085
86 *outBufferHandle = bufferHandle;
87 return Error::NONE;
88}
89
90void 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)));
Marissa Wallb96c2eb2019-06-20 13:30:10 -070096 } else if (mMapper4) {
97 mMapper4->freeBuffer(static_cast<void*>(const_cast<native_handle_t*>(bufferHandle)));
Marissa Walla8c31302019-08-15 14:42:50 -070098 }
99 }
100}
101
102Error 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
116void 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
123ComposerHandleCache::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
128ComposerHandleCache::ComposerHandleCache(ComposerHandleImporter& importer) : mImporter(importer) {}
129
130ComposerHandleCache::~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
Marin Shalamanovac6cc1f2020-10-23 17:42:59 +0200147size_t ComposerHandleCache::getCacheSize() const {
148 return mHandles.size();
149}
150
Marissa Walla8c31302019-08-15 14:42:50 -0700151bool 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
163Error 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
172Error 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
185Error 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
197ComposerLayerResource::ComposerLayerResource(ComposerHandleImporter& importer,
198 uint32_t bufferCacheSize)
199 : mBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, bufferCacheSize),
200 mSidebandStreamCache(importer, ComposerHandleCache::HandleType::STREAM, 1) {}
201
202Error 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
209Error 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
216ComposerDisplayResource::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
223bool ComposerDisplayResource::initClientTargetCache(uint32_t cacheSize) {
224 return mClientTargetCache.initCache(ComposerHandleCache::HandleType::BUFFER, cacheSize);
225}
226
Marin Shalamanovac6cc1f2020-10-23 17:42:59 +0200227size_t ComposerDisplayResource::getClientTargetCacheSize() const {
228 return mClientTargetCache.getCacheSize();
229}
230
231size_t ComposerDisplayResource::getOutputBufferCacheSize() const {
232 return mOutputBufferCache.getCacheSize();
233}
234
Marissa Walla8c31302019-08-15 14:42:50 -0700235bool ComposerDisplayResource::isVirtual() const {
236 return mType == DisplayType::VIRTUAL;
237}
238
239Error 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
246Error 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
253bool 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
259bool ComposerDisplayResource::removeLayer(Layer layer) {
260 return mLayerResources.erase(layer) > 0;
261}
262
263ComposerLayerResource* 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
272std::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
281void ComposerDisplayResource::setMustValidateState(bool mustValidate) {
282 mMustValidate = mustValidate;
283}
284
285bool ComposerDisplayResource::mustValidate() const {
286 return mMustValidate;
287}
288
289std::unique_ptr<ComposerResources> ComposerResources::create() {
290 auto resources = std::make_unique<ComposerResources>();
291 return resources->init() ? std::move(resources) : nullptr;
292}
293
294bool ComposerResources::init() {
295 return mImporter.init();
296}
297
298void 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
Marin Shalamanovac6cc1f2020-10-23 17:42:59 +0200308bool ComposerResources::hasDisplay(Display display) {
309 return mDisplayResources.count(display) > 0;
310}
311
Marissa Walla8c31302019-08-15 14:42:50 -0700312Error 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
320Error 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
329Error 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
334Error 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
Marin Shalamanovac6cc1f2020-10-23 17:42:59 +0200346Error 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
356Error 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
Marissa Walla8c31302019-08-15 14:42:50 -0700366Error 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
379Error 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
389Error 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
397Error 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
405Error 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
413Error 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
421void 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
429bool 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
438std::unique_ptr<ComposerDisplayResource> ComposerResources::createDisplayResource(
439 ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) {
440 return std::make_unique<ComposerDisplayResource>(type, mImporter, outputBufferCacheSize);
441}
442
443std::unique_ptr<ComposerLayerResource> ComposerResources::createLayerResource(
444 uint32_t bufferCacheSize) {
445 return std::make_unique<ComposerLayerResource>(mImporter, bufferCacheSize);
446}
447
448ComposerDisplayResource* 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
456Error 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