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