blob: 128e2b010673f285cc3d063251146943baa85f12 [file] [log] [blame]
Chia-I Wuaab99f52016-10-05 12:59:58 +08001/*
2 * Copyright 2016 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#undef LOG_TAG
18#define LOG_TAG "HwcComposer"
19
20#include <inttypes.h>
21#include <log/log.h>
22
23#include "ComposerHal.h"
24
25namespace android {
26
27using hardware::Return;
28using hardware::hidl_vec;
29
30namespace Hwc2 {
31
32namespace {
33
34class BufferHandle {
35public:
36 BufferHandle(const native_handle_t* buffer)
37 {
38 // nullptr is not a valid handle to HIDL
39 mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
40 }
41
42 operator const native_handle_t*() const
43 {
44 return mHandle;
45 }
46
47private:
48 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 0, 0);
49 const native_handle_t* mHandle;
50};
51
52class FenceHandle
53{
54public:
55 FenceHandle(int fd, bool owned)
56 : mOwned(owned)
57 {
58 if (fd >= 0) {
59 mHandle = native_handle_init(mStorage, 1, 0);
60 mHandle->data[0] = fd;
61 } else {
62 // nullptr is not a valid handle to HIDL
63 mHandle = native_handle_init(mStorage, 0, 0);
64 }
65 }
66
67 ~FenceHandle()
68 {
69 if (mOwned) {
70 native_handle_close(mHandle);
71 }
72 }
73
74 operator const native_handle_t*() const
75 {
76 return mHandle;
77 }
78
79private:
80 bool mOwned;
81 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 1, 0);
82 native_handle_t* mHandle;
83};
84
85// assume NO_RESOURCES when Status::isOk returns false
86constexpr Error kDefaultError = Error::NO_RESOURCES;
87
88template<typename T, typename U>
89T unwrapRet(Return<T>& ret, const U& default_val)
90{
91 return (ret.getStatus().isOk()) ? static_cast<T>(ret) :
92 static_cast<T>(default_val);
93}
94
95Error unwrapRet(Return<Error>& ret)
96{
97 return unwrapRet(ret, kDefaultError);
98}
99
100template<typename T>
101void assignFromHidlVec(std::vector<T>& vec, const hidl_vec<T>& data)
102{
103 vec.clear();
104 vec.insert(vec.begin(), &data[0], &data[data.size()]);
105}
106
107} // anonymous namespace
108
109Composer::Composer()
110{
111 mService = IComposer::getService("hwcomposer");
112 if (mService == nullptr) {
113 LOG_ALWAYS_FATAL("failed to get hwcomposer service");
114 }
115}
116
117std::vector<IComposer::Capability> Composer::getCapabilities() const
118{
119 std::vector<IComposer::Capability> capabilities;
120 mService->getCapabilities(
121 [&](const auto& tmpCapabilities) {
122 assignFromHidlVec(capabilities, tmpCapabilities);
123 });
124
125 return capabilities;
126}
127
128std::string Composer::dumpDebugInfo() const
129{
130 std::string info;
131 mService->dumpDebugInfo([&](const auto& tmpInfo) {
132 info = tmpInfo.c_str();
133 });
134
135 return info;
136}
137
138void Composer::registerCallback(const sp<IComposerCallback>& callback) const
139{
140 auto ret = mService->registerCallback(callback);
141 if (!ret.getStatus().isOk()) {
142 ALOGE("failed to register IComposerCallback");
143 }
144}
145
146uint32_t Composer::getMaxVirtualDisplayCount() const
147{
148 auto ret = mService->getMaxVirtualDisplayCount();
149 return unwrapRet(ret, 0);
150}
151
152Error Composer::createVirtualDisplay(uint32_t width, uint32_t height,
153 PixelFormat& format, Display& display) const
154{
155 Error error = kDefaultError;
156 mService->createVirtualDisplay(width, height, format,
157 [&](const auto& tmpError, const auto& tmpDisplay,
158 const auto& tmpFormat) {
159 error = tmpError;
160 if (error != Error::NONE) {
161 return;
162 }
163
164 display = tmpDisplay;
165 format = tmpFormat;
166 });
167
168 return error;
169}
170
171Error Composer::destroyVirtualDisplay(Display display) const
172{
173 auto ret = mService->destroyVirtualDisplay(display);
174 return unwrapRet(ret);
175}
176
177Error Composer::acceptDisplayChanges(Display display) const
178{
179 auto ret = mService->acceptDisplayChanges(display);
180 return unwrapRet(ret);
181}
182
183Error Composer::createLayer(Display display, Layer& layer) const
184{
185 Error error = kDefaultError;
186 mService->createLayer(display,
187 [&](const auto& tmpError, const auto& tmpLayer) {
188 error = tmpError;
189 if (error != Error::NONE) {
190 return;
191 }
192
193 layer = tmpLayer;
194 });
195
196 return error;
197}
198
199Error Composer::destroyLayer(Display display, Layer layer) const
200{
201 auto ret = mService->destroyLayer(display, layer);
202 return unwrapRet(ret);
203}
204
205Error Composer::getActiveConfig(Display display, Config& config) const
206{
207 Error error = kDefaultError;
208 mService->getActiveConfig(display,
209 [&](const auto& tmpError, const auto& tmpConfig) {
210 error = tmpError;
211 if (error != Error::NONE) {
212 return;
213 }
214
215 config = tmpConfig;
216 });
217
218 return error;
219}
220
221Error Composer::getChangedCompositionTypes(Display display,
222 std::vector<Layer>& layers,
223 std::vector<IComposer::Composition>& types) const
224{
225 Error error = kDefaultError;
226 mService->getChangedCompositionTypes(display,
227 [&](const auto& tmpError, const auto& tmpLayers,
228 const auto& tmpTypes) {
229 error = tmpError;
230 if (error != Error::NONE) {
231 return;
232 }
233
234 assignFromHidlVec(layers, tmpLayers);
235 assignFromHidlVec(types, tmpTypes);
236 });
237
238 return error;
239}
240
241Error Composer::getColorModes(Display display,
242 std::vector<ColorMode>& modes) const
243{
244 Error error = kDefaultError;
245 mService->getColorModes(display,
246 [&](const auto& tmpError, const auto& tmpModes) {
247 error = tmpError;
248 if (error != Error::NONE) {
249 return;
250 }
251
252 assignFromHidlVec(modes, tmpModes);
253 });
254
255 return error;
256}
257
258Error Composer::getDisplayAttribute(Display display, Config config,
259 IComposer::Attribute attribute, int32_t& value) const
260{
261 Error error = kDefaultError;
262 mService->getDisplayAttribute(display, config, attribute,
263 [&](const auto& tmpError, const auto& tmpValue) {
264 error = tmpError;
265 if (error != Error::NONE) {
266 return;
267 }
268
269 value = tmpValue;
270 });
271
272 return error;
273}
274
275Error Composer::getDisplayConfigs(Display display,
276 std::vector<Config>& configs) const
277{
278 Error error = kDefaultError;
279 mService->getDisplayConfigs(display,
280 [&](const auto& tmpError, const auto& tmpConfigs) {
281 error = tmpError;
282 if (error != Error::NONE) {
283 return;
284 }
285
286 assignFromHidlVec(configs, tmpConfigs);
287 });
288
289 return error;
290}
291
292Error Composer::getDisplayName(Display display, std::string& name) const
293{
294 Error error = kDefaultError;
295 mService->getDisplayName(display,
296 [&](const auto& tmpError, const auto& tmpName) {
297 error = tmpError;
298 if (error != Error::NONE) {
299 return;
300 }
301
302 name = tmpName.c_str();
303 });
304
305 return error;
306}
307
308Error Composer::getDisplayRequests(Display display,
309 uint32_t& displayRequestMask, std::vector<Layer>& layers,
310 std::vector<uint32_t>& layerRequestMasks) const
311{
312 Error error = kDefaultError;
313 mService->getDisplayRequests(display,
314 [&](const auto& tmpError, const auto& tmpDisplayRequestMask,
315 const auto& tmpLayers, const auto& tmpLayerRequestMasks) {
316 error = tmpError;
317 if (error != Error::NONE) {
318 return;
319 }
320
321 displayRequestMask = tmpDisplayRequestMask;
322 assignFromHidlVec(layers, tmpLayers);
323 assignFromHidlVec(layerRequestMasks, tmpLayerRequestMasks);
324 });
325
326 return error;
327}
328
329Error Composer::getDisplayType(Display display, IComposer::DisplayType& type) const
330{
331 Error error = kDefaultError;
332 mService->getDisplayType(display,
333 [&](const auto& tmpError, const auto& tmpType) {
334 error = tmpError;
335 if (error != Error::NONE) {
336 return;
337 }
338
339 type = tmpType;
340 });
341
342 return error;
343}
344
345Error Composer::getDozeSupport(Display display, bool& support) const
346{
347 Error error = kDefaultError;
348 mService->getDozeSupport(display,
349 [&](const auto& tmpError, const auto& tmpSupport) {
350 error = tmpError;
351 if (error != Error::NONE) {
352 return;
353 }
354
355 support = tmpSupport;
356 });
357
358 return error;
359}
360
361Error Composer::getHdrCapabilities(Display display, std::vector<Hdr>& types,
362 float& maxLuminance, float& maxAverageLuminance,
363 float& minLuminance) const
364{
365 Error error = kDefaultError;
366 mService->getHdrCapabilities(display,
367 [&](const auto& tmpError, const auto& tmpTypes,
368 const auto& tmpMaxLuminance,
369 const auto& tmpMaxAverageLuminance,
370 const auto& tmpMinLuminance) {
371 error = tmpError;
372 if (error != Error::NONE) {
373 return;
374 }
375
376 assignFromHidlVec(types, tmpTypes);
377 maxLuminance = tmpMaxLuminance;
378 maxAverageLuminance = tmpMaxAverageLuminance;
379 minLuminance = tmpMinLuminance;
380 });
381
382 return error;
383}
384
385Error Composer::getReleaseFences(Display display, std::vector<Layer>& layers,
386 std::vector<int>& releaseFences) const
387{
388 Error error = kDefaultError;
389 mService->getReleaseFences(display,
390 [&](const auto& tmpError, const auto& tmpLayers,
391 const auto& tmpReleaseFences) {
392 error = tmpError;
393 if (error != Error::NONE) {
394 return;
395 }
396
397 if (static_cast<int>(tmpLayers.size()) !=
398 tmpReleaseFences->numFds) {
399 ALOGE("invalid releaseFences outputs: "
400 "layer count %zu != fence count %d",
401 tmpLayers.size(), tmpReleaseFences->numFds);
402 error = Error::NO_RESOURCES;
403 return;
404 }
405
406 // dup the file descriptors
407 std::vector<int> tmpFds;
408 tmpFds.reserve(tmpReleaseFences->numFds);
409 for (int i = 0; i < tmpReleaseFences->numFds; i++) {
410 int fd = dup(tmpReleaseFences->data[i]);
411 if (fd < 0) {
412 break;
413 }
414 tmpFds.push_back(fd);
415 }
416 if (static_cast<int>(tmpFds.size()) <
417 tmpReleaseFences->numFds) {
418 for (auto fd : tmpFds) {
419 close(fd);
420 }
421
422 error = Error::NO_RESOURCES;
423 return;
424 }
425
426 assignFromHidlVec(layers, tmpLayers);
427 releaseFences = std::move(tmpFds);
428 });
429
430 return error;
431}
432
433Error Composer::presentDisplay(Display display, int& presentFence) const
434{
435 Error error = kDefaultError;
436 mService->presentDisplay(display,
437 [&](const auto& tmpError, const auto& tmpPresentFence) {
438 error = tmpError;
439 if (error != Error::NONE) {
440 return;
441 }
442
443 if (tmpPresentFence->numFds == 1) {
444 int fd = dup(tmpPresentFence->data[0]);
445 if (fd >= 0) {
446 presentFence = fd;
447 } else {
448 error = Error::NO_RESOURCES;
449 }
450 } else {
451 presentFence = -1;
452 }
453 });
454
455 return error;
456}
457
458Error Composer::setActiveConfig(Display display, Config config) const
459{
460 auto ret = mService->setActiveConfig(display, config);
461 return unwrapRet(ret);
462}
463
464Error Composer::setClientTarget(Display display, const native_handle_t* target,
465 int acquireFence, Dataspace dataspace,
466 const std::vector<IComposer::Rect>& damage) const
467{
468 BufferHandle tmpTarget(target);
469 FenceHandle tmpAcquireFence(acquireFence, true);
470
471 hidl_vec<IComposer::Rect> tmpDamage;
472 tmpDamage.setToExternal(const_cast<IComposer::Rect*>(damage.data()),
473 damage.size());
474
475 auto ret = mService->setClientTarget(display, tmpTarget,
476 tmpAcquireFence, dataspace, tmpDamage);
477 return unwrapRet(ret);
478}
479
480Error Composer::setColorMode(Display display, ColorMode mode) const
481{
482 auto ret = mService->setColorMode(display, mode);
483 return unwrapRet(ret);
484}
485
486Error Composer::setColorTransform(Display display, const float* matrix,
487 ColorTransform hint) const
488{
489 hidl_vec<float> tmpMatrix;
490 tmpMatrix.setToExternal(const_cast<float*>(matrix), 16);
491
492 auto ret = mService->setColorTransform(display, tmpMatrix, hint);
493 return unwrapRet(ret);
494}
495
496Error Composer::setOutputBuffer(Display display, const native_handle_t* buffer,
497 int releaseFence) const
498{
499 BufferHandle tmpBuffer(buffer);
500 FenceHandle tmpReleaseFence(releaseFence, false);
501
502 auto ret = mService->setOutputBuffer(display, tmpBuffer, tmpReleaseFence);
503 return unwrapRet(ret);
504}
505
506Error Composer::setPowerMode(Display display, IComposer::PowerMode mode) const
507{
508 auto ret = mService->setPowerMode(display, mode);
509 return unwrapRet(ret);
510}
511
512Error Composer::setVsyncEnabled(Display display, IComposer::Vsync enabled) const
513{
514 auto ret = mService->setVsyncEnabled(display, enabled);
515 return unwrapRet(ret);
516}
517
518Error Composer::validateDisplay(Display display, uint32_t& numTypes, uint32_t&
519 numRequests) const
520{
521 Error error = kDefaultError;
522 mService->validateDisplay(display,
523 [&](const auto& tmpError, const auto& tmpNumTypes,
524 const auto& tmpNumRequests) {
525 error = tmpError;
526 if (error != Error::NONE) {
527 return;
528 }
529
530 numTypes = tmpNumTypes;
531 numRequests = tmpNumRequests;
532 });
533
534 return error;
535}
536
537Error Composer::setCursorPosition(Display display, Layer layer,
538 int32_t x, int32_t y) const
539{
540 auto ret = mService->setCursorPosition(display, layer, x, y);
541 return unwrapRet(ret);
542}
543
544Error Composer::setLayerBuffer(Display display, Layer layer,
545 const native_handle_t* buffer, int acquireFence) const
546{
547 BufferHandle tmpBuffer(buffer);
548 FenceHandle tmpAcquireFence(acquireFence, true);
549
550 auto ret = mService->setLayerBuffer(display, layer,
551 tmpBuffer, tmpAcquireFence);
552 return unwrapRet(ret);
553}
554
555Error Composer::setLayerSurfaceDamage(Display display, Layer layer,
556 const std::vector<IComposer::Rect>& damage) const
557{
558 hidl_vec<IComposer::Rect> tmpDamage;
559 tmpDamage.setToExternal(const_cast<IComposer::Rect*>(damage.data()),
560 damage.size());
561
562 auto ret = mService->setLayerSurfaceDamage(display, layer, tmpDamage);
563 return unwrapRet(ret);
564}
565
566Error Composer::setLayerBlendMode(Display display, Layer layer,
567 IComposer::BlendMode mode) const
568{
569 auto ret = mService->setLayerBlendMode(display, layer, mode);
570 return unwrapRet(ret);
571}
572
573Error Composer::setLayerColor(Display display, Layer layer,
574 const IComposer::Color& color) const
575{
576 auto ret = mService->setLayerColor(display, layer, color);
577 return unwrapRet(ret);
578}
579
580Error Composer::setLayerCompositionType(Display display, Layer layer,
581 IComposer::Composition type) const
582{
583 auto ret = mService->setLayerCompositionType(display, layer, type);
584 return unwrapRet(ret);
585}
586
587Error Composer::setLayerDataspace(Display display, Layer layer,
588 Dataspace dataspace) const
589{
590 auto ret = mService->setLayerDataspace(display, layer, dataspace);
591 return unwrapRet(ret);
592}
593
594Error Composer::setLayerDisplayFrame(Display display, Layer layer,
595 const IComposer::Rect& frame) const
596{
597 auto ret = mService->setLayerDisplayFrame(display, layer, frame);
598 return unwrapRet(ret);
599}
600
601Error Composer::setLayerPlaneAlpha(Display display, Layer layer,
602 float alpha) const
603{
604 auto ret = mService->setLayerPlaneAlpha(display, layer, alpha);
605 return unwrapRet(ret);
606}
607
608Error Composer::setLayerSidebandStream(Display display, Layer layer,
609 const native_handle_t* stream) const
610{
611 BufferHandle tmpStream(stream);
612
613 auto ret = mService->setLayerSidebandStream(display, layer, tmpStream);
614 return unwrapRet(ret);
615}
616
617Error Composer::setLayerSourceCrop(Display display, Layer layer,
618 const IComposer::FRect& crop) const
619{
620 auto ret = mService->setLayerSourceCrop(display, layer, crop);
621 return unwrapRet(ret);
622}
623
624Error Composer::setLayerTransform(Display display, Layer layer,
625 Transform transform) const
626{
627 auto ret = mService->setLayerTransform(display, layer, transform);
628 return unwrapRet(ret);
629}
630
631Error Composer::setLayerVisibleRegion(Display display, Layer layer,
632 const std::vector<IComposer::Rect>& visible) const
633{
634 hidl_vec<IComposer::Rect> tmpVisible;
635 tmpVisible.setToExternal(const_cast<IComposer::Rect*>(visible.data()),
636 visible.size());
637
638 auto ret = mService->setLayerVisibleRegion(display, layer, tmpVisible);
639 return unwrapRet(ret);
640}
641
642Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z) const
643{
644 auto ret = mService->setLayerZOrder(display, layer, z);
645 return unwrapRet(ret);
646}
647
648} // namespace Hwc2
649
650} // namespace android