blob: 21f60355f8e965ae6ca80cfd494b5907db701daf [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
147bool 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
159Error 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
168Error 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
181Error 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
193ComposerLayerResource::ComposerLayerResource(ComposerHandleImporter& importer,
194 uint32_t bufferCacheSize)
195 : mBufferCache(importer, ComposerHandleCache::HandleType::BUFFER, bufferCacheSize),
196 mSidebandStreamCache(importer, ComposerHandleCache::HandleType::STREAM, 1) {}
197
198Error 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
205Error 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
212ComposerDisplayResource::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
219bool ComposerDisplayResource::initClientTargetCache(uint32_t cacheSize) {
220 return mClientTargetCache.initCache(ComposerHandleCache::HandleType::BUFFER, cacheSize);
221}
222
223bool ComposerDisplayResource::isVirtual() const {
224 return mType == DisplayType::VIRTUAL;
225}
226
227Error 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
234Error 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
241bool 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
247bool ComposerDisplayResource::removeLayer(Layer layer) {
248 return mLayerResources.erase(layer) > 0;
249}
250
251ComposerLayerResource* 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
260std::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
269void ComposerDisplayResource::setMustValidateState(bool mustValidate) {
270 mMustValidate = mustValidate;
271}
272
273bool ComposerDisplayResource::mustValidate() const {
274 return mMustValidate;
275}
276
277std::unique_ptr<ComposerResources> ComposerResources::create() {
278 auto resources = std::make_unique<ComposerResources>();
279 return resources->init() ? std::move(resources) : nullptr;
280}
281
282bool ComposerResources::init() {
283 return mImporter.init();
284}
285
286void 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
296Error 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
304Error 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
313Error 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
318Error 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
330Error 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
343Error 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
353Error 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
361Error 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
369Error 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
377Error 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
385void 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
393bool 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
402std::unique_ptr<ComposerDisplayResource> ComposerResources::createDisplayResource(
403 ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize) {
404 return std::make_unique<ComposerDisplayResource>(type, mImporter, outputBufferCacheSize);
405}
406
407std::unique_ptr<ComposerLayerResource> ComposerResources::createLayerResource(
408 uint32_t bufferCacheSize) {
409 return std::make_unique<ComposerLayerResource>(mImporter, bufferCacheSize);
410}
411
412ComposerDisplayResource* 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
420Error 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