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