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 #include <ui/GraphicBufferMapper.h>
22
23 namespace android {
24 namespace hardware {
25 namespace graphics {
26 namespace composer {
27 namespace V2_1 {
28 namespace hal {
29
ComposerHandleImporter()30 ComposerHandleImporter::ComposerHandleImporter() : mMapper{GraphicBufferMapper::get()} {}
31
init()32 bool ComposerHandleImporter::init() {
33 return true;
34 }
35
importBuffer(const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle)36 Error ComposerHandleImporter::importBuffer(const native_handle_t* rawHandle,
37 const native_handle_t** outBufferHandle) {
38 if (!rawHandle || (!rawHandle->numFds && !rawHandle->numInts)) {
39 *outBufferHandle = nullptr;
40 return Error::NONE;
41 }
42
43 status_t status = mMapper.importBufferNoValidate(rawHandle, outBufferHandle);
44 if (status == STATUS_OK) {
45 return Error::NONE;
46 } else {
47 return Error::NO_RESOURCES;
48 }
49 }
50
freeBuffer(const native_handle_t * bufferHandle)51 void ComposerHandleImporter::freeBuffer(const native_handle_t* bufferHandle) {
52 if (bufferHandle) {
53 mMapper.freeBuffer(bufferHandle);
54 }
55 }
56
importStream(const native_handle_t * rawHandle,const native_handle_t ** outStreamHandle)57 Error ComposerHandleImporter::importStream(const native_handle_t* rawHandle,
58 const native_handle_t** outStreamHandle) {
59 const native_handle_t* streamHandle = nullptr;
60 if (rawHandle) {
61 streamHandle = native_handle_clone(rawHandle);
62 if (!streamHandle) {
63 return Error::NO_RESOURCES;
64 }
65 }
66
67 *outStreamHandle = streamHandle;
68 return Error::NONE;
69 }
70
freeStream(const native_handle_t * streamHandle)71 void ComposerHandleImporter::freeStream(const native_handle_t* streamHandle) {
72 if (streamHandle) {
73 native_handle_close(streamHandle);
74 native_handle_delete(const_cast<native_handle_t*>(streamHandle));
75 }
76 }
77
ComposerHandleCache(ComposerHandleImporter & importer,HandleType type,uint32_t cacheSize)78 ComposerHandleCache::ComposerHandleCache(ComposerHandleImporter& importer, HandleType type,
79 uint32_t cacheSize)
80 : mImporter(importer), mHandleType(type), mHandles(cacheSize, nullptr) {}
81
82 // must be initialized later with initCache
ComposerHandleCache(ComposerHandleImporter & importer)83 ComposerHandleCache::ComposerHandleCache(ComposerHandleImporter& importer) : mImporter(importer) {}
84
~ComposerHandleCache()85 ComposerHandleCache::~ComposerHandleCache() {
86 switch (mHandleType) {
87 case HandleType::BUFFER:
88 for (auto handle : mHandles) {
89 mImporter.freeBuffer(handle);
90 }
91 break;
92 case HandleType::STREAM:
93 for (auto handle : mHandles) {
94 mImporter.freeStream(handle);
95 }
96 break;
97 default:
98 break;
99 }
100 }
101
getCacheSize() const102 size_t ComposerHandleCache::getCacheSize() const {
103 return mHandles.size();
104 }
105
initCache(HandleType type,uint32_t cacheSize)106 bool ComposerHandleCache::initCache(HandleType type, uint32_t cacheSize) {
107 // already initialized
108 if (mHandleType != HandleType::INVALID) {
109 return false;
110 }
111
112 mHandleType = type;
113 mHandles.resize(cacheSize, nullptr);
114
115 return true;
116 }
117
lookupCache(uint32_t slot,const native_handle_t ** outHandle)118 Error ComposerHandleCache::lookupCache(uint32_t slot, const native_handle_t** outHandle) {
119 if (slot >= 0 && slot < mHandles.size()) {
120 *outHandle = mHandles[slot];
121 return Error::NONE;
122 } else {
123 return Error::BAD_PARAMETER;
124 }
125 }
126
updateCache(uint32_t slot,const native_handle_t * handle,const native_handle ** outReplacedHandle)127 Error ComposerHandleCache::updateCache(uint32_t slot, const native_handle_t* handle,
128 const native_handle** outReplacedHandle) {
129 if (slot >= 0 && slot < mHandles.size()) {
130 auto& cachedHandle = mHandles[slot];
131 *outReplacedHandle = cachedHandle;
132 cachedHandle = handle;
133 return Error::NONE;
134 } else {
135 return Error::BAD_PARAMETER;
136 }
137 }
138
139 // 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)140 Error ComposerHandleCache::getHandle(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
141 const native_handle_t** outHandle,
142 const native_handle** outReplacedHandle) {
143 if (fromCache) {
144 *outReplacedHandle = nullptr;
145 return lookupCache(slot, outHandle);
146 } else {
147 *outHandle = inHandle;
148 return updateCache(slot, inHandle, outReplacedHandle);
149 }
150 }
151
ComposerLayerResource(ComposerHandleImporter & importer,uint32_t bufferCacheSize)152 ComposerLayerResource::ComposerLayerResource(ComposerHandleImporter& importer,
153 uint32_t bufferCacheSize)
154 : mBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, bufferCacheSize),
155 mSidebandStreamCache(importer, ComposerHandleCache::HandleType::STREAM, 1) {}
156
getBuffer(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)157 Error ComposerLayerResource::getBuffer(uint32_t slot, bool fromCache,
158 const native_handle_t* inHandle,
159 const native_handle_t** outHandle,
160 const native_handle** outReplacedHandle) {
161 return mBufferCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
162 }
163
getSidebandStream(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)164 Error ComposerLayerResource::getSidebandStream(uint32_t slot, bool fromCache,
165 const native_handle_t* inHandle,
166 const native_handle_t** outHandle,
167 const native_handle** outReplacedHandle) {
168 return mSidebandStreamCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
169 }
170
ComposerDisplayResource(DisplayType type,ComposerHandleImporter & importer,uint32_t outputBufferCacheSize)171 ComposerDisplayResource::ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
172 uint32_t outputBufferCacheSize)
173 : mType(type),
174 mClientTargetCache(importer),
175 mOutputBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, outputBufferCacheSize),
176 mMustValidate(true) {}
177
initClientTargetCache(uint32_t cacheSize)178 bool ComposerDisplayResource::initClientTargetCache(uint32_t cacheSize) {
179 return mClientTargetCache.initCache(ComposerHandleCache::HandleType::BUFFER, cacheSize);
180 }
181
getClientTargetCacheSize() const182 size_t ComposerDisplayResource::getClientTargetCacheSize() const {
183 return mClientTargetCache.getCacheSize();
184 }
185
getOutputBufferCacheSize() const186 size_t ComposerDisplayResource::getOutputBufferCacheSize() const {
187 return mOutputBufferCache.getCacheSize();
188 }
189
isVirtual() const190 bool ComposerDisplayResource::isVirtual() const {
191 return mType == DisplayType::VIRTUAL;
192 }
193
getClientTarget(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)194 Error ComposerDisplayResource::getClientTarget(uint32_t slot, bool fromCache,
195 const native_handle_t* inHandle,
196 const native_handle_t** outHandle,
197 const native_handle** outReplacedHandle) {
198 return mClientTargetCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
199 }
200
getOutputBuffer(uint32_t slot,bool fromCache,const native_handle_t * inHandle,const native_handle_t ** outHandle,const native_handle ** outReplacedHandle)201 Error ComposerDisplayResource::getOutputBuffer(uint32_t slot, bool fromCache,
202 const native_handle_t* inHandle,
203 const native_handle_t** outHandle,
204 const native_handle** outReplacedHandle) {
205 return mOutputBufferCache.getHandle(slot, fromCache, inHandle, outHandle, outReplacedHandle);
206 }
207
addLayer(Layer layer,std::unique_ptr<ComposerLayerResource> layerResource)208 bool ComposerDisplayResource::addLayer(Layer layer,
209 std::unique_ptr<ComposerLayerResource> layerResource) {
210 auto result = mLayerResources.emplace(layer, std::move(layerResource));
211 return result.second;
212 }
213
removeLayer(Layer layer)214 bool ComposerDisplayResource::removeLayer(Layer layer) {
215 return mLayerResources.erase(layer) > 0;
216 }
217
findLayerResource(Layer layer)218 ComposerLayerResource* ComposerDisplayResource::findLayerResource(Layer layer) {
219 auto layerIter = mLayerResources.find(layer);
220 if (layerIter == mLayerResources.end()) {
221 return nullptr;
222 }
223
224 return layerIter->second.get();
225 }
226
getLayers() const227 std::vector<Layer> ComposerDisplayResource::getLayers() const {
228 std::vector<Layer> layers;
229 layers.reserve(mLayerResources.size());
230 for (const auto& layerKey : mLayerResources) {
231 layers.push_back(layerKey.first);
232 }
233 return layers;
234 }
235
setMustValidateState(bool mustValidate)236 void ComposerDisplayResource::setMustValidateState(bool mustValidate) {
237 mMustValidate = mustValidate;
238 }
239
mustValidate() const240 bool ComposerDisplayResource::mustValidate() const {
241 return mMustValidate;
242 }
243
create()244 std::unique_ptr<ComposerResources> ComposerResources::create() {
245 auto resources = std::make_unique<ComposerResources>();
246 return resources->init() ? std::move(resources) : nullptr;
247 }
248
init()249 bool ComposerResources::init() {
250 return mImporter.init();
251 }
252
clear(RemoveDisplay removeDisplay)253 void ComposerResources::clear(RemoveDisplay removeDisplay) {
254 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
255 for (const auto& displayKey : mDisplayResources) {
256 Display display = displayKey.first;
257 const ComposerDisplayResource& displayResource = *displayKey.second;
258 removeDisplay(display, displayResource.isVirtual(), displayResource.getLayers());
259 }
260 mDisplayResources.clear();
261 }
262
hasDisplay(Display display)263 bool ComposerResources::hasDisplay(Display display) {
264 return mDisplayResources.count(display) > 0;
265 }
266
addPhysicalDisplay(Display display)267 Error ComposerResources::addPhysicalDisplay(Display display) {
268 auto displayResource = createDisplayResource(ComposerDisplayResource::DisplayType::PHYSICAL, 0);
269
270 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
271 auto result = mDisplayResources.emplace(display, std::move(displayResource));
272 return result.second ? Error::NONE : Error::BAD_DISPLAY;
273 }
274
addVirtualDisplay(Display display,uint32_t outputBufferCacheSize)275 Error ComposerResources::addVirtualDisplay(Display display, uint32_t outputBufferCacheSize) {
276 auto displayResource = createDisplayResource(ComposerDisplayResource::DisplayType::VIRTUAL,
277 outputBufferCacheSize);
278
279 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
280 auto result = mDisplayResources.emplace(display, std::move(displayResource));
281 return result.second ? Error::NONE : Error::BAD_DISPLAY;
282 }
283
removeDisplay(Display display)284 Error ComposerResources::removeDisplay(Display display) {
285 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
286 return mDisplayResources.erase(display) > 0 ? Error::NONE : Error::BAD_DISPLAY;
287 }
288
setDisplayClientTargetCacheSize(Display display,uint32_t clientTargetCacheSize)289 Error ComposerResources::setDisplayClientTargetCacheSize(Display display,
290 uint32_t clientTargetCacheSize) {
291 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
292 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
293 if (!displayResource) {
294 return Error::BAD_DISPLAY;
295 }
296
297 return displayResource->initClientTargetCache(clientTargetCacheSize) ? Error::NONE
298 : Error::BAD_PARAMETER;
299 }
300
getDisplayClientTargetCacheSize(Display display,size_t * outCacheSize)301 Error ComposerResources::getDisplayClientTargetCacheSize(Display display, size_t* outCacheSize) {
302 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
303 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
304 if (!displayResource) {
305 return Error::BAD_DISPLAY;
306 }
307 *outCacheSize = displayResource->getClientTargetCacheSize();
308 return Error::NONE;
309 }
310
getDisplayOutputBufferCacheSize(Display display,size_t * outCacheSize)311 Error ComposerResources::getDisplayOutputBufferCacheSize(Display display, size_t* outCacheSize) {
312 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
313 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
314 if (!displayResource) {
315 return Error::BAD_DISPLAY;
316 }
317 *outCacheSize = displayResource->getOutputBufferCacheSize();
318 return Error::NONE;
319 }
320
addLayer(Display display,Layer layer,uint32_t bufferCacheSize)321 Error ComposerResources::addLayer(Display display, Layer layer, uint32_t bufferCacheSize) {
322 auto layerResource = createLayerResource(bufferCacheSize);
323
324 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
325 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
326 if (!displayResource) {
327 return Error::BAD_DISPLAY;
328 }
329
330 return displayResource->addLayer(layer, std::move(layerResource)) ? Error::NONE
331 : Error::BAD_LAYER;
332 }
333
removeLayer(Display display,Layer layer)334 Error ComposerResources::removeLayer(Display display, Layer layer) {
335 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
336 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
337 if (!displayResource) {
338 return Error::BAD_DISPLAY;
339 }
340
341 return displayResource->removeLayer(layer) ? Error::NONE : Error::BAD_LAYER;
342 }
343
getDisplayClientTarget(Display display,uint32_t slot,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle,ReplacedHandle * outReplacedBuffer)344 Error ComposerResources::getDisplayClientTarget(Display display, uint32_t slot, bool fromCache,
345 const native_handle_t* rawHandle,
346 const native_handle_t** outBufferHandle,
347 ReplacedHandle* outReplacedBuffer) {
348 return getHandle(display, 0, slot, Cache::CLIENT_TARGET, fromCache, rawHandle, outBufferHandle,
349 outReplacedBuffer);
350 }
351
getDisplayOutputBuffer(Display display,uint32_t slot,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle,ReplacedHandle * outReplacedBuffer)352 Error ComposerResources::getDisplayOutputBuffer(Display display, uint32_t slot, bool fromCache,
353 const native_handle_t* rawHandle,
354 const native_handle_t** outBufferHandle,
355 ReplacedHandle* outReplacedBuffer) {
356 return getHandle(display, 0, slot, Cache::OUTPUT_BUFFER, fromCache, rawHandle, outBufferHandle,
357 outReplacedBuffer);
358 }
359
getLayerBuffer(Display display,Layer layer,uint32_t slot,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outBufferHandle,ReplacedHandle * outReplacedBuffer)360 Error ComposerResources::getLayerBuffer(Display display, Layer layer, uint32_t slot, bool fromCache,
361 const native_handle_t* rawHandle,
362 const native_handle_t** outBufferHandle,
363 ReplacedHandle* outReplacedBuffer) {
364 return getHandle(display, layer, slot, Cache::LAYER_BUFFER, fromCache, rawHandle,
365 outBufferHandle, outReplacedBuffer);
366 }
367
getLayerSidebandStream(Display display,Layer layer,const native_handle_t * rawHandle,const native_handle_t ** outStreamHandle,ReplacedHandle * outReplacedStream)368 Error ComposerResources::getLayerSidebandStream(Display display, Layer layer,
369 const native_handle_t* rawHandle,
370 const native_handle_t** outStreamHandle,
371 ReplacedHandle* outReplacedStream) {
372 return getHandle(display, layer, 0, Cache::LAYER_SIDEBAND_STREAM, false, rawHandle,
373 outStreamHandle, outReplacedStream);
374 }
375
setDisplayMustValidateState(Display display,bool mustValidate)376 void ComposerResources::setDisplayMustValidateState(Display display, bool mustValidate) {
377 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
378 auto* displayResource = findDisplayResourceLocked(display);
379 if (displayResource) {
380 displayResource->setMustValidateState(mustValidate);
381 }
382 }
383
mustValidateDisplay(Display display)384 bool ComposerResources::mustValidateDisplay(Display display) {
385 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
386 auto* displayResource = findDisplayResourceLocked(display);
387 if (displayResource) {
388 return displayResource->mustValidate();
389 }
390 return false;
391 }
392
createDisplayResource(ComposerDisplayResource::DisplayType type,uint32_t outputBufferCacheSize)393 std::unique_ptr<ComposerDisplayResource> ComposerResources::createDisplayResource(
394 ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) {
395 return std::make_unique<ComposerDisplayResource>(type, mImporter, outputBufferCacheSize);
396 }
397
createLayerResource(uint32_t bufferCacheSize)398 std::unique_ptr<ComposerLayerResource> ComposerResources::createLayerResource(
399 uint32_t bufferCacheSize) {
400 return std::make_unique<ComposerLayerResource>(mImporter, bufferCacheSize);
401 }
402
findDisplayResourceLocked(Display display)403 ComposerDisplayResource* ComposerResources::findDisplayResourceLocked(Display display) {
404 auto iter = mDisplayResources.find(display);
405 if (iter == mDisplayResources.end()) {
406 return nullptr;
407 }
408 return iter->second.get();
409 }
410
getHandle(Display display,Layer layer,uint32_t slot,Cache cache,bool fromCache,const native_handle_t * rawHandle,const native_handle_t ** outHandle,ReplacedHandle * outReplacedHandle)411 Error ComposerResources::getHandle(Display display, Layer layer, uint32_t slot, Cache cache,
412 bool fromCache, const native_handle_t* rawHandle,
413 const native_handle_t** outHandle,
414 ReplacedHandle* outReplacedHandle) {
415 Error error;
416
417 // import the raw handle (or ignore raw handle when fromCache is true)
418 const native_handle_t* importedHandle = nullptr;
419 if (!fromCache) {
420 error = (outReplacedHandle->isBuffer())
421 ? mImporter.importBuffer(rawHandle, &importedHandle)
422 : mImporter.importStream(rawHandle, &importedHandle);
423 if (error != Error::NONE) {
424 return error;
425 }
426 }
427
428 std::lock_guard<std::mutex> lock(mDisplayResourcesMutex);
429
430 // find display/layer resource
431 const bool needLayerResource = (cache == ComposerResources::Cache::LAYER_BUFFER ||
432 cache == ComposerResources::Cache::LAYER_SIDEBAND_STREAM);
433 ComposerDisplayResource* displayResource = findDisplayResourceLocked(display);
434 ComposerLayerResource* layerResource = (displayResource && needLayerResource)
435 ? displayResource->findLayerResource(layer)
436 : nullptr;
437
438 // lookup or update cache
439 const native_handle_t* replacedHandle = nullptr;
440 if (displayResource && (!needLayerResource || layerResource)) {
441 switch (cache) {
442 case ComposerResources::Cache::CLIENT_TARGET:
443 error = displayResource->getClientTarget(slot, fromCache, importedHandle, outHandle,
444 &replacedHandle);
445 break;
446 case ComposerResources::Cache::OUTPUT_BUFFER:
447 error = displayResource->getOutputBuffer(slot, fromCache, importedHandle, outHandle,
448 &replacedHandle);
449 break;
450 case ComposerResources::Cache::LAYER_BUFFER:
451 error = layerResource->getBuffer(slot, fromCache, importedHandle, outHandle,
452 &replacedHandle);
453 break;
454 case ComposerResources::Cache::LAYER_SIDEBAND_STREAM:
455 error = layerResource->getSidebandStream(slot, fromCache, importedHandle, outHandle,
456 &replacedHandle);
457 break;
458 default:
459 error = Error::BAD_PARAMETER;
460 break;
461 }
462
463 if (error != Error::NONE) {
464 ALOGW("invalid cache %d slot %d", int(cache), int(slot));
465 }
466 } else if (!displayResource) {
467 error = Error::BAD_DISPLAY;
468 } else {
469 error = Error::BAD_LAYER;
470 }
471
472 // clean up on errors
473 if (error != Error::NONE) {
474 if (!fromCache) {
475 if (outReplacedHandle->isBuffer()) {
476 mImporter.freeBuffer(importedHandle);
477 } else {
478 mImporter.freeStream(importedHandle);
479 }
480 }
481 return error;
482 }
483
484 outReplacedHandle->reset(&mImporter, replacedHandle);
485
486 return Error::NONE;
487 }
488
489 } // namespace hal
490 } // namespace V2_1
491 } // namespace composer
492 } // namespace graphics
493 } // namespace hardware
494 } // namespace android
495