blob: 11d41c063e4da3e674d64b9a248a55e76ff86d3e [file] [log] [blame]
Ady Abraham9fc28052021-10-14 17:21:38 -07001/*
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// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
21#undef LOG_TAG
22#define LOG_TAG "HwcComposer"
23#define ATRACE_TAG ATRACE_TAG_GRAPHICS
24
25#include "HidlComposerHal.h"
26
27#include <android/binder_manager.h>
28#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
29#include <hidl/HidlTransportSupport.h>
30#include <hidl/HidlTransportUtils.h>
31#include <log/log.h>
32#include <utils/Trace.h>
33
34#include <algorithm>
35#include <cinttypes>
36
37namespace android {
38
39using hardware::hidl_handle;
40using hardware::hidl_vec;
41using hardware::Return;
42
43namespace Hwc2 {
44
45HidlComposer::~HidlComposer() = default;
46
47namespace {
48
49class BufferHandle {
50public:
51 explicit BufferHandle(const native_handle_t* buffer) {
52 // nullptr is not a valid handle to HIDL
53 mHandle = (buffer) ? buffer : native_handle_init(mStorage, 0, 0);
54 }
55
56 operator const hidl_handle&() const // NOLINT(google-explicit-constructor)
57 {
58 return mHandle;
59 }
60
61private:
62 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 0, 0);
63 hidl_handle mHandle;
64};
65
66class FenceHandle {
67public:
68 FenceHandle(int fd, bool owned) : mOwned(owned) {
69 native_handle_t* handle;
70 if (fd >= 0) {
71 handle = native_handle_init(mStorage, 1, 0);
72 handle->data[0] = fd;
73 } else {
74 // nullptr is not a valid handle to HIDL
75 handle = native_handle_init(mStorage, 0, 0);
76 }
77 mHandle = handle;
78 }
79
80 ~FenceHandle() {
81 if (mOwned) {
82 native_handle_close(mHandle);
83 }
84 }
85
86 operator const hidl_handle&() const // NOLINT(google-explicit-constructor)
87 {
88 return mHandle;
89 }
90
91private:
92 bool mOwned;
93 NATIVE_HANDLE_DECLARE_STORAGE(mStorage, 1, 0);
94 hidl_handle mHandle;
95};
96
97// assume NO_RESOURCES when Status::isOk returns false
98constexpr Error kDefaultError = Error::NO_RESOURCES;
99constexpr V2_4::Error kDefaultError_2_4 = static_cast<V2_4::Error>(kDefaultError);
100
101template <typename T, typename U>
102T unwrapRet(Return<T>& ret, const U& default_val) {
103 return (ret.isOk()) ? static_cast<T>(ret) : static_cast<T>(default_val);
104}
105
106Error unwrapRet(Return<Error>& ret) {
107 return unwrapRet(ret, kDefaultError);
108}
109
110} // anonymous namespace
111
112HidlComposer::HidlComposer(const std::string& serviceName) : mWriter(kWriterInitialSize) {
113 mComposer = V2_1::IComposer::getService(serviceName);
114
115 if (mComposer == nullptr) {
116 LOG_ALWAYS_FATAL("failed to get hwcomposer service");
117 }
118
119 if (sp<IComposer> composer_2_4 = IComposer::castFrom(mComposer)) {
120 composer_2_4->createClient_2_4([&](const auto& tmpError, const auto& tmpClient) {
121 if (tmpError == V2_4::Error::NONE) {
122 mClient = tmpClient;
123 mClient_2_2 = tmpClient;
124 mClient_2_3 = tmpClient;
125 mClient_2_4 = tmpClient;
126 }
127 });
128 } else if (sp<V2_3::IComposer> composer_2_3 = V2_3::IComposer::castFrom(mComposer)) {
129 composer_2_3->createClient_2_3([&](const auto& tmpError, const auto& tmpClient) {
130 if (tmpError == Error::NONE) {
131 mClient = tmpClient;
132 mClient_2_2 = tmpClient;
133 mClient_2_3 = tmpClient;
134 }
135 });
136 } else {
137 mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {
138 if (tmpError != Error::NONE) {
139 return;
140 }
141
142 mClient = tmpClient;
143 if (sp<V2_2::IComposer> composer_2_2 = V2_2::IComposer::castFrom(mComposer)) {
144 mClient_2_2 = V2_2::IComposerClient::castFrom(mClient);
145 LOG_ALWAYS_FATAL_IF(mClient_2_2 == nullptr,
146 "IComposer 2.2 did not return IComposerClient 2.2");
147 }
148 });
149 }
150
151 if (mClient == nullptr) {
152 LOG_ALWAYS_FATAL("failed to create composer client");
153 }
154}
155
156std::vector<IComposer::Capability> HidlComposer::getCapabilities() {
157 std::vector<IComposer::Capability> capabilities;
158 mComposer->getCapabilities(
159 [&](const auto& tmpCapabilities) { capabilities = tmpCapabilities; });
160 return capabilities;
161}
162
163std::string HidlComposer::dumpDebugInfo() {
164 std::string info;
165 mComposer->dumpDebugInfo([&](const auto& tmpInfo) { info = tmpInfo.c_str(); });
166
167 return info;
168}
169
170void HidlComposer::registerCallback(const sp<IComposerCallback>& callback) {
171 android::hardware::setMinSchedulerPolicy(callback, SCHED_FIFO, 2);
172
173 auto ret = [&]() {
174 if (mClient_2_4) {
175 return mClient_2_4->registerCallback_2_4(callback);
176 }
177 return mClient->registerCallback(callback);
178 }();
179 if (!ret.isOk()) {
180 ALOGE("failed to register IComposerCallback");
181 }
182}
183
184void HidlComposer::resetCommands() {
185 mWriter.reset();
186}
187
188Error HidlComposer::executeCommands() {
189 return execute();
190}
191
192uint32_t HidlComposer::getMaxVirtualDisplayCount() {
193 auto ret = mClient->getMaxVirtualDisplayCount();
194 return unwrapRet(ret, 0);
195}
196
197Error HidlComposer::createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format,
198 Display* outDisplay) {
199 const uint32_t bufferSlotCount = 1;
200 Error error = kDefaultError;
201 if (mClient_2_2) {
202 mClient_2_2->createVirtualDisplay_2_2(width, height,
203 static_cast<types::V1_1::PixelFormat>(*format),
204 bufferSlotCount,
205 [&](const auto& tmpError, const auto& tmpDisplay,
206 const auto& tmpFormat) {
207 error = tmpError;
208 if (error != Error::NONE) {
209 return;
210 }
211
212 *outDisplay = tmpDisplay;
213 *format = static_cast<types::V1_2::PixelFormat>(
214 tmpFormat);
215 });
216 } else {
217 mClient->createVirtualDisplay(width, height, static_cast<types::V1_0::PixelFormat>(*format),
218 bufferSlotCount,
219 [&](const auto& tmpError, const auto& tmpDisplay,
220 const auto& tmpFormat) {
221 error = tmpError;
222 if (error != Error::NONE) {
223 return;
224 }
225
226 *outDisplay = tmpDisplay;
227 *format = static_cast<PixelFormat>(tmpFormat);
228 });
229 }
230
231 return error;
232}
233
234Error HidlComposer::destroyVirtualDisplay(Display display) {
235 auto ret = mClient->destroyVirtualDisplay(display);
236 return unwrapRet(ret);
237}
238
239Error HidlComposer::acceptDisplayChanges(Display display) {
240 mWriter.selectDisplay(display);
241 mWriter.acceptDisplayChanges();
242 return Error::NONE;
243}
244
245Error HidlComposer::createLayer(Display display, Layer* outLayer) {
246 Error error = kDefaultError;
247 mClient->createLayer(display, kMaxLayerBufferCount,
248 [&](const auto& tmpError, const auto& tmpLayer) {
249 error = tmpError;
250 if (error != Error::NONE) {
251 return;
252 }
253
254 *outLayer = tmpLayer;
255 });
256
257 return error;
258}
259
260Error HidlComposer::destroyLayer(Display display, Layer layer) {
261 auto ret = mClient->destroyLayer(display, layer);
262 return unwrapRet(ret);
263}
264
265Error HidlComposer::getActiveConfig(Display display, Config* outConfig) {
266 Error error = kDefaultError;
267 mClient->getActiveConfig(display, [&](const auto& tmpError, const auto& tmpConfig) {
268 error = tmpError;
269 if (error != Error::NONE) {
270 return;
271 }
272
273 *outConfig = tmpConfig;
274 });
275
276 return error;
277}
278
279Error HidlComposer::getChangedCompositionTypes(
280 Display display, std::vector<Layer>* outLayers,
281 std::vector<IComposerClient::Composition>* outTypes) {
282 mReader.takeChangedCompositionTypes(display, outLayers, outTypes);
283 return Error::NONE;
284}
285
286Error HidlComposer::getColorModes(Display display, std::vector<ColorMode>* outModes) {
287 Error error = kDefaultError;
288
289 if (mClient_2_3) {
290 mClient_2_3->getColorModes_2_3(display, [&](const auto& tmpError, const auto& tmpModes) {
291 error = tmpError;
292 if (error != Error::NONE) {
293 return;
294 }
295
296 *outModes = tmpModes;
297 });
298 } else if (mClient_2_2) {
299 mClient_2_2->getColorModes_2_2(display, [&](const auto& tmpError, const auto& tmpModes) {
300 error = tmpError;
301 if (error != Error::NONE) {
302 return;
303 }
304
305 for (types::V1_1::ColorMode colorMode : tmpModes) {
306 outModes->push_back(static_cast<ColorMode>(colorMode));
307 }
308 });
309 } else {
310 mClient->getColorModes(display, [&](const auto& tmpError, const auto& tmpModes) {
311 error = tmpError;
312 if (error != Error::NONE) {
313 return;
314 }
315 for (types::V1_0::ColorMode colorMode : tmpModes) {
316 outModes->push_back(static_cast<ColorMode>(colorMode));
317 }
318 });
319 }
320
321 return error;
322}
323
324Error HidlComposer::getDisplayAttribute(Display display, Config config,
325 IComposerClient::Attribute attribute, int32_t* outValue) {
326 Error error = kDefaultError;
327 if (mClient_2_4) {
328 mClient_2_4->getDisplayAttribute_2_4(display, config, attribute,
329 [&](const auto& tmpError, const auto& tmpValue) {
330 error = static_cast<Error>(tmpError);
331 if (error != Error::NONE) {
332 return;
333 }
334
335 *outValue = tmpValue;
336 });
337 } else {
338 mClient->getDisplayAttribute(display, config,
339 static_cast<V2_1::IComposerClient::Attribute>(attribute),
340 [&](const auto& tmpError, const auto& tmpValue) {
341 error = tmpError;
342 if (error != Error::NONE) {
343 return;
344 }
345
346 *outValue = tmpValue;
347 });
348 }
349
350 return error;
351}
352
353Error HidlComposer::getDisplayConfigs(Display display, std::vector<Config>* outConfigs) {
354 Error error = kDefaultError;
355 mClient->getDisplayConfigs(display, [&](const auto& tmpError, const auto& tmpConfigs) {
356 error = tmpError;
357 if (error != Error::NONE) {
358 return;
359 }
360
361 *outConfigs = tmpConfigs;
362 });
363
364 return error;
365}
366
367Error HidlComposer::getDisplayName(Display display, std::string* outName) {
368 Error error = kDefaultError;
369 mClient->getDisplayName(display, [&](const auto& tmpError, const auto& tmpName) {
370 error = tmpError;
371 if (error != Error::NONE) {
372 return;
373 }
374
375 *outName = tmpName.c_str();
376 });
377
378 return error;
379}
380
381Error HidlComposer::getDisplayRequests(Display display, uint32_t* outDisplayRequestMask,
382 std::vector<Layer>* outLayers,
383 std::vector<uint32_t>* outLayerRequestMasks) {
384 mReader.takeDisplayRequests(display, outDisplayRequestMask, outLayers, outLayerRequestMasks);
385 return Error::NONE;
386}
387
388Error HidlComposer::getDozeSupport(Display display, bool* outSupport) {
389 Error error = kDefaultError;
390 mClient->getDozeSupport(display, [&](const auto& tmpError, const auto& tmpSupport) {
391 error = tmpError;
392 if (error != Error::NONE) {
393 return;
394 }
395
396 *outSupport = tmpSupport;
397 });
398
399 return error;
400}
401
402Error HidlComposer::getHdrCapabilities(Display display, std::vector<Hdr>* outTypes,
403 float* outMaxLuminance, float* outMaxAverageLuminance,
404 float* outMinLuminance) {
405 Error error = kDefaultError;
406 if (mClient_2_3) {
407 mClient_2_3->getHdrCapabilities_2_3(display,
408 [&](const auto& tmpError, const auto& tmpTypes,
409 const auto& tmpMaxLuminance,
410 const auto& tmpMaxAverageLuminance,
411 const auto& tmpMinLuminance) {
412 error = tmpError;
413 if (error != Error::NONE) {
414 return;
415 }
416
417 *outTypes = tmpTypes;
418 *outMaxLuminance = tmpMaxLuminance;
419 *outMaxAverageLuminance = tmpMaxAverageLuminance;
420 *outMinLuminance = tmpMinLuminance;
421 });
422 } else {
423 mClient->getHdrCapabilities(display,
424 [&](const auto& tmpError, const auto& tmpTypes,
425 const auto& tmpMaxLuminance,
426 const auto& tmpMaxAverageLuminance,
427 const auto& tmpMinLuminance) {
428 error = tmpError;
429 if (error != Error::NONE) {
430 return;
431 }
432
433 outTypes->clear();
434 for (auto type : tmpTypes) {
435 outTypes->push_back(static_cast<Hdr>(type));
436 }
437
438 *outMaxLuminance = tmpMaxLuminance;
439 *outMaxAverageLuminance = tmpMaxAverageLuminance;
440 *outMinLuminance = tmpMinLuminance;
441 });
442 }
443
444 return error;
445}
446
447Error HidlComposer::getReleaseFences(Display display, std::vector<Layer>* outLayers,
448 std::vector<int>* outReleaseFences) {
449 mReader.takeReleaseFences(display, outLayers, outReleaseFences);
450 return Error::NONE;
451}
452
453Error HidlComposer::presentDisplay(Display display, int* outPresentFence) {
454 ATRACE_NAME("HwcPresentDisplay");
455 mWriter.selectDisplay(display);
456 mWriter.presentDisplay();
457
458 Error error = execute();
459 if (error != Error::NONE) {
460 return error;
461 }
462
463 mReader.takePresentFence(display, outPresentFence);
464
465 return Error::NONE;
466}
467
468Error HidlComposer::setActiveConfig(Display display, Config config) {
469 auto ret = mClient->setActiveConfig(display, config);
470 return unwrapRet(ret);
471}
472
473Error HidlComposer::setClientTarget(Display display, uint32_t slot, const sp<GraphicBuffer>& target,
474 int acquireFence, Dataspace dataspace,
475 const std::vector<IComposerClient::Rect>& damage) {
476 mWriter.selectDisplay(display);
477
478 const native_handle_t* handle = nullptr;
479 if (target.get()) {
480 handle = target->getNativeBuffer()->handle;
481 }
482
483 mWriter.setClientTarget(slot, handle, acquireFence, dataspace, damage);
484 return Error::NONE;
485}
486
487Error HidlComposer::setColorMode(Display display, ColorMode mode, RenderIntent renderIntent) {
488 hardware::Return<Error> ret(kDefaultError);
489 if (mClient_2_3) {
490 ret = mClient_2_3->setColorMode_2_3(display, mode, renderIntent);
491 } else if (mClient_2_2) {
492 ret = mClient_2_2->setColorMode_2_2(display, static_cast<types::V1_1::ColorMode>(mode),
493 renderIntent);
494 } else {
495 ret = mClient->setColorMode(display, static_cast<types::V1_0::ColorMode>(mode));
496 }
497 return unwrapRet(ret);
498}
499
500Error HidlComposer::setColorTransform(Display display, const float* matrix, ColorTransform hint) {
501 mWriter.selectDisplay(display);
502 mWriter.setColorTransform(matrix, hint);
503 return Error::NONE;
504}
505
506Error HidlComposer::setOutputBuffer(Display display, const native_handle_t* buffer,
507 int releaseFence) {
508 mWriter.selectDisplay(display);
509 mWriter.setOutputBuffer(0, buffer, dup(releaseFence));
510 return Error::NONE;
511}
512
513Error HidlComposer::setPowerMode(Display display, IComposerClient::PowerMode mode) {
514 Return<Error> ret(Error::UNSUPPORTED);
515 if (mClient_2_2) {
516 ret = mClient_2_2->setPowerMode_2_2(display, mode);
517 } else if (mode != IComposerClient::PowerMode::ON_SUSPEND) {
518 ret = mClient->setPowerMode(display, static_cast<V2_1::IComposerClient::PowerMode>(mode));
519 }
520
521 return unwrapRet(ret);
522}
523
524Error HidlComposer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) {
525 auto ret = mClient->setVsyncEnabled(display, enabled);
526 return unwrapRet(ret);
527}
528
529Error HidlComposer::setClientTargetSlotCount(Display display) {
530 const uint32_t bufferSlotCount = BufferQueue::NUM_BUFFER_SLOTS;
531 auto ret = mClient->setClientTargetSlotCount(display, bufferSlotCount);
532 return unwrapRet(ret);
533}
534
535Error HidlComposer::validateDisplay(Display display, uint32_t* outNumTypes,
536 uint32_t* outNumRequests) {
537 ATRACE_NAME("HwcValidateDisplay");
538 mWriter.selectDisplay(display);
539 mWriter.validateDisplay();
540
541 Error error = execute();
542 if (error != Error::NONE) {
543 return error;
544 }
545
546 mReader.hasChanges(display, outNumTypes, outNumRequests);
547
548 return Error::NONE;
549}
550
551Error HidlComposer::presentOrValidateDisplay(Display display, uint32_t* outNumTypes,
552 uint32_t* outNumRequests, int* outPresentFence,
553 uint32_t* state) {
554 ATRACE_NAME("HwcPresentOrValidateDisplay");
555 mWriter.selectDisplay(display);
556 mWriter.presentOrvalidateDisplay();
557
558 Error error = execute();
559 if (error != Error::NONE) {
560 return error;
561 }
562
563 mReader.takePresentOrValidateStage(display, state);
564
565 if (*state == 1) { // Present succeeded
566 mReader.takePresentFence(display, outPresentFence);
567 }
568
569 if (*state == 0) { // Validate succeeded.
570 mReader.hasChanges(display, outNumTypes, outNumRequests);
571 }
572
573 return Error::NONE;
574}
575
576Error HidlComposer::setCursorPosition(Display display, Layer layer, int32_t x, int32_t y) {
577 mWriter.selectDisplay(display);
578 mWriter.selectLayer(layer);
579 mWriter.setLayerCursorPosition(x, y);
580 return Error::NONE;
581}
582
583Error HidlComposer::setLayerBuffer(Display display, Layer layer, uint32_t slot,
584 const sp<GraphicBuffer>& buffer, int acquireFence) {
585 mWriter.selectDisplay(display);
586 mWriter.selectLayer(layer);
587
588 const native_handle_t* handle = nullptr;
589 if (buffer.get()) {
590 handle = buffer->getNativeBuffer()->handle;
591 }
592
593 mWriter.setLayerBuffer(slot, handle, acquireFence);
594 return Error::NONE;
595}
596
597Error HidlComposer::setLayerSurfaceDamage(Display display, Layer layer,
598 const std::vector<IComposerClient::Rect>& damage) {
599 mWriter.selectDisplay(display);
600 mWriter.selectLayer(layer);
601 mWriter.setLayerSurfaceDamage(damage);
602 return Error::NONE;
603}
604
605Error HidlComposer::setLayerBlendMode(Display display, Layer layer,
606 IComposerClient::BlendMode mode) {
607 mWriter.selectDisplay(display);
608 mWriter.selectLayer(layer);
609 mWriter.setLayerBlendMode(mode);
610 return Error::NONE;
611}
612
613Error HidlComposer::setLayerColor(Display display, Layer layer,
614 const IComposerClient::Color& color) {
615 mWriter.selectDisplay(display);
616 mWriter.selectLayer(layer);
617 mWriter.setLayerColor(color);
618 return Error::NONE;
619}
620
621Error HidlComposer::setLayerCompositionType(Display display, Layer layer,
622 IComposerClient::Composition type) {
623 mWriter.selectDisplay(display);
624 mWriter.selectLayer(layer);
625 mWriter.setLayerCompositionType(type);
626 return Error::NONE;
627}
628
629Error HidlComposer::setLayerDataspace(Display display, Layer layer, Dataspace dataspace) {
630 mWriter.selectDisplay(display);
631 mWriter.selectLayer(layer);
632 mWriter.setLayerDataspace(dataspace);
633 return Error::NONE;
634}
635
636Error HidlComposer::setLayerDisplayFrame(Display display, Layer layer,
637 const IComposerClient::Rect& frame) {
638 mWriter.selectDisplay(display);
639 mWriter.selectLayer(layer);
640 mWriter.setLayerDisplayFrame(frame);
641 return Error::NONE;
642}
643
644Error HidlComposer::setLayerPlaneAlpha(Display display, Layer layer, float alpha) {
645 mWriter.selectDisplay(display);
646 mWriter.selectLayer(layer);
647 mWriter.setLayerPlaneAlpha(alpha);
648 return Error::NONE;
649}
650
651Error HidlComposer::setLayerSidebandStream(Display display, Layer layer,
652 const native_handle_t* stream) {
653 mWriter.selectDisplay(display);
654 mWriter.selectLayer(layer);
655 mWriter.setLayerSidebandStream(stream);
656 return Error::NONE;
657}
658
659Error HidlComposer::setLayerSourceCrop(Display display, Layer layer,
660 const IComposerClient::FRect& crop) {
661 mWriter.selectDisplay(display);
662 mWriter.selectLayer(layer);
663 mWriter.setLayerSourceCrop(crop);
664 return Error::NONE;
665}
666
667Error HidlComposer::setLayerTransform(Display display, Layer layer, Transform transform) {
668 mWriter.selectDisplay(display);
669 mWriter.selectLayer(layer);
670 mWriter.setLayerTransform(transform);
671 return Error::NONE;
672}
673
674Error HidlComposer::setLayerVisibleRegion(Display display, Layer layer,
675 const std::vector<IComposerClient::Rect>& visible) {
676 mWriter.selectDisplay(display);
677 mWriter.selectLayer(layer);
678 mWriter.setLayerVisibleRegion(visible);
679 return Error::NONE;
680}
681
682Error HidlComposer::setLayerZOrder(Display display, Layer layer, uint32_t z) {
683 mWriter.selectDisplay(display);
684 mWriter.selectLayer(layer);
685 mWriter.setLayerZOrder(z);
686 return Error::NONE;
687}
688
689Error HidlComposer::execute() {
690 // prepare input command queue
691 bool queueChanged = false;
692 uint32_t commandLength = 0;
693 hidl_vec<hidl_handle> commandHandles;
694 if (!mWriter.writeQueue(&queueChanged, &commandLength, &commandHandles)) {
695 mWriter.reset();
696 return Error::NO_RESOURCES;
697 }
698
699 // set up new input command queue if necessary
700 if (queueChanged) {
701 auto ret = mClient->setInputCommandQueue(*mWriter.getMQDescriptor());
702 auto error = unwrapRet(ret);
703 if (error != Error::NONE) {
704 mWriter.reset();
705 return error;
706 }
707 }
708
709 if (commandLength == 0) {
710 mWriter.reset();
711 return Error::NONE;
712 }
713
714 Error error = kDefaultError;
715 hardware::Return<void> ret;
716 auto hidl_callback = [&](const auto& tmpError, const auto& tmpOutChanged,
717 const auto& tmpOutLength, const auto& tmpOutHandles) {
718 error = tmpError;
719
720 // set up new output command queue if necessary
721 if (error == Error::NONE && tmpOutChanged) {
722 error = kDefaultError;
723 mClient->getOutputCommandQueue([&](const auto& tmpError, const auto& tmpDescriptor) {
724 error = tmpError;
725 if (error != Error::NONE) {
726 return;
727 }
728
729 mReader.setMQDescriptor(tmpDescriptor);
730 });
731 }
732
733 if (error != Error::NONE) {
734 return;
735 }
736
737 if (mReader.readQueue(tmpOutLength, tmpOutHandles)) {
738 error = mReader.parse();
739 mReader.reset();
740 } else {
741 error = Error::NO_RESOURCES;
742 }
743 };
744 if (mClient_2_2) {
745 ret = mClient_2_2->executeCommands_2_2(commandLength, commandHandles, hidl_callback);
746 } else {
747 ret = mClient->executeCommands(commandLength, commandHandles, hidl_callback);
748 }
749 // executeCommands can fail because of out-of-fd and we do not want to
750 // abort() in that case
751 if (!ret.isOk()) {
752 ALOGE("executeCommands failed because of %s", ret.description().c_str());
753 }
754
755 if (error == Error::NONE) {
756 std::vector<CommandReader::CommandError> commandErrors = mReader.takeErrors();
757
758 for (const auto& cmdErr : commandErrors) {
759 auto command =
760 static_cast<IComposerClient::Command>(mWriter.getCommand(cmdErr.location));
761
762 if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
763 command == IComposerClient::Command::PRESENT_DISPLAY ||
764 command == IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY) {
765 error = cmdErr.error;
766 } else {
767 ALOGW("command 0x%x generated error %d", command, cmdErr.error);
768 }
769 }
770 }
771
772 mWriter.reset();
773
774 return error;
775}
776
777// Composer HAL 2.2
778
779Error HidlComposer::setLayerPerFrameMetadata(
780 Display display, Layer layer,
781 const std::vector<IComposerClient::PerFrameMetadata>& perFrameMetadatas) {
782 if (!mClient_2_2) {
783 return Error::UNSUPPORTED;
784 }
785
786 mWriter.selectDisplay(display);
787 mWriter.selectLayer(layer);
788 mWriter.setLayerPerFrameMetadata(perFrameMetadatas);
789 return Error::NONE;
790}
791
792std::vector<IComposerClient::PerFrameMetadataKey> HidlComposer::getPerFrameMetadataKeys(
793 Display display) {
794 std::vector<IComposerClient::PerFrameMetadataKey> keys;
795 if (!mClient_2_2) {
796 return keys;
797 }
798
799 Error error = kDefaultError;
800 if (mClient_2_3) {
801 mClient_2_3->getPerFrameMetadataKeys_2_3(display,
802 [&](const auto& tmpError, const auto& tmpKeys) {
803 error = tmpError;
804 if (error != Error::NONE) {
805 ALOGW("getPerFrameMetadataKeys failed "
806 "with %d",
807 tmpError);
808 return;
809 }
810 keys = tmpKeys;
811 });
812 } else {
813 mClient_2_2
814 ->getPerFrameMetadataKeys(display, [&](const auto& tmpError, const auto& tmpKeys) {
815 error = tmpError;
816 if (error != Error::NONE) {
817 ALOGW("getPerFrameMetadataKeys failed with %d", tmpError);
818 return;
819 }
820
821 keys.clear();
822 for (auto key : tmpKeys) {
823 keys.push_back(static_cast<IComposerClient::PerFrameMetadataKey>(key));
824 }
825 });
826 }
827
828 return keys;
829}
830
831Error HidlComposer::getRenderIntents(Display display, ColorMode colorMode,
832 std::vector<RenderIntent>* outRenderIntents) {
833 if (!mClient_2_2) {
834 outRenderIntents->push_back(RenderIntent::COLORIMETRIC);
835 return Error::NONE;
836 }
837
838 Error error = kDefaultError;
839
840 auto getRenderIntentsLambda = [&](const auto& tmpError, const auto& tmpKeys) {
841 error = tmpError;
842 if (error != Error::NONE) {
843 return;
844 }
845
846 *outRenderIntents = tmpKeys;
847 };
848
849 if (mClient_2_3) {
850 mClient_2_3->getRenderIntents_2_3(display, colorMode, getRenderIntentsLambda);
851 } else {
852 mClient_2_2->getRenderIntents(display, static_cast<types::V1_1::ColorMode>(colorMode),
853 getRenderIntentsLambda);
854 }
855
856 return error;
857}
858
859Error HidlComposer::getDataspaceSaturationMatrix(Dataspace dataspace, mat4* outMatrix) {
860 if (!mClient_2_2) {
861 *outMatrix = mat4();
862 return Error::NONE;
863 }
864
865 Error error = kDefaultError;
866 mClient_2_2->getDataspaceSaturationMatrix(static_cast<types::V1_1::Dataspace>(dataspace),
867 [&](const auto& tmpError, const auto& tmpMatrix) {
868 error = tmpError;
869 if (error != Error::NONE) {
870 return;
871 }
872 *outMatrix = mat4(tmpMatrix.data());
873 });
874
875 return error;
876}
877
878// Composer HAL 2.3
879
880Error HidlComposer::getDisplayIdentificationData(Display display, uint8_t* outPort,
881 std::vector<uint8_t>* outData) {
882 if (!mClient_2_3) {
883 return Error::UNSUPPORTED;
884 }
885
886 Error error = kDefaultError;
887 mClient_2_3->getDisplayIdentificationData(display,
888 [&](const auto& tmpError, const auto& tmpPort,
889 const auto& tmpData) {
890 error = tmpError;
891 if (error != Error::NONE) {
892 return;
893 }
894
895 *outPort = tmpPort;
896 *outData = tmpData;
897 });
898
899 return error;
900}
901
902Error HidlComposer::setLayerColorTransform(Display display, Layer layer, const float* matrix) {
903 if (!mClient_2_3) {
904 return Error::UNSUPPORTED;
905 }
906
907 mWriter.selectDisplay(display);
908 mWriter.selectLayer(layer);
909 mWriter.setLayerColorTransform(matrix);
910 return Error::NONE;
911}
912
913Error HidlComposer::getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat,
914 Dataspace* outDataspace,
915 uint8_t* outComponentMask) {
916 if (!outFormat || !outDataspace || !outComponentMask) {
917 return Error::BAD_PARAMETER;
918 }
919 if (!mClient_2_3) {
920 return Error::UNSUPPORTED;
921 }
922 Error error = kDefaultError;
923 mClient_2_3->getDisplayedContentSamplingAttributes(display,
924 [&](const auto tmpError,
925 const auto& tmpFormat,
926 const auto& tmpDataspace,
927 const auto& tmpComponentMask) {
928 error = tmpError;
929 if (error == Error::NONE) {
930 *outFormat = tmpFormat;
931 *outDataspace = tmpDataspace;
932 *outComponentMask =
933 static_cast<uint8_t>(
934 tmpComponentMask);
935 }
936 });
937 return error;
938}
939
940Error HidlComposer::setDisplayContentSamplingEnabled(Display display, bool enabled,
941 uint8_t componentMask, uint64_t maxFrames) {
942 if (!mClient_2_3) {
943 return Error::UNSUPPORTED;
944 }
945
946 auto enable = enabled ? V2_3::IComposerClient::DisplayedContentSampling::ENABLE
947 : V2_3::IComposerClient::DisplayedContentSampling::DISABLE;
948 return mClient_2_3->setDisplayedContentSamplingEnabled(display, enable, componentMask,
949 maxFrames);
950}
951
952Error HidlComposer::getDisplayedContentSample(Display display, uint64_t maxFrames,
953 uint64_t timestamp, DisplayedFrameStats* outStats) {
954 if (!outStats) {
955 return Error::BAD_PARAMETER;
956 }
957 if (!mClient_2_3) {
958 return Error::UNSUPPORTED;
959 }
960 Error error = kDefaultError;
961 mClient_2_3->getDisplayedContentSample(display, maxFrames, timestamp,
962 [&](const auto tmpError, auto tmpNumFrames,
963 const auto& tmpSamples0, const auto& tmpSamples1,
964 const auto& tmpSamples2, const auto& tmpSamples3) {
965 error = tmpError;
966 if (error == Error::NONE) {
967 outStats->numFrames = tmpNumFrames;
968 outStats->component_0_sample = tmpSamples0;
969 outStats->component_1_sample = tmpSamples1;
970 outStats->component_2_sample = tmpSamples2;
971 outStats->component_3_sample = tmpSamples3;
972 }
973 });
974 return error;
975}
976
977Error HidlComposer::setLayerPerFrameMetadataBlobs(
978 Display display, Layer layer,
979 const std::vector<IComposerClient::PerFrameMetadataBlob>& metadata) {
980 if (!mClient_2_3) {
981 return Error::UNSUPPORTED;
982 }
983
984 mWriter.selectDisplay(display);
985 mWriter.selectLayer(layer);
986 mWriter.setLayerPerFrameMetadataBlobs(metadata);
987 return Error::NONE;
988}
989
990Error HidlComposer::setDisplayBrightness(Display display, float brightness) {
991 if (!mClient_2_3) {
992 return Error::UNSUPPORTED;
993 }
994 return mClient_2_3->setDisplayBrightness(display, brightness);
995}
996
997// Composer HAL 2.4
998
999Error HidlComposer::getDisplayCapabilities(Display display,
1000 std::vector<DisplayCapability>* outCapabilities) {
1001 if (!mClient_2_3) {
1002 return Error::UNSUPPORTED;
1003 }
1004
1005 V2_4::Error error = kDefaultError_2_4;
1006 if (mClient_2_4) {
1007 mClient_2_4->getDisplayCapabilities_2_4(display,
1008 [&](const auto& tmpError, const auto& tmpCaps) {
1009 error = tmpError;
1010 if (error != V2_4::Error::NONE) {
1011 return;
1012 }
1013 *outCapabilities = tmpCaps;
1014 });
1015 } else {
1016 mClient_2_3
1017 ->getDisplayCapabilities(display, [&](const auto& tmpError, const auto& tmpCaps) {
1018 error = static_cast<V2_4::Error>(tmpError);
1019 if (error != V2_4::Error::NONE) {
1020 return;
1021 }
1022
1023 outCapabilities->resize(tmpCaps.size());
1024 std::transform(tmpCaps.begin(), tmpCaps.end(), outCapabilities->begin(),
1025 [](auto cap) { return static_cast<DisplayCapability>(cap); });
1026 });
1027 }
1028
1029 return static_cast<Error>(error);
1030}
1031
1032V2_4::Error HidlComposer::getDisplayConnectionType(
1033 Display display, IComposerClient::DisplayConnectionType* outType) {
1034 using Error = V2_4::Error;
1035 if (!mClient_2_4) {
1036 return Error::UNSUPPORTED;
1037 }
1038
1039 Error error = kDefaultError_2_4;
1040 mClient_2_4->getDisplayConnectionType(display, [&](const auto& tmpError, const auto& tmpType) {
1041 error = tmpError;
1042 if (error != V2_4::Error::NONE) {
1043 return;
1044 }
1045
1046 *outType = tmpType;
1047 });
1048
1049 return error;
1050}
1051
1052V2_4::Error HidlComposer::getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) {
1053 using Error = V2_4::Error;
1054 if (!mClient_2_4) {
1055 return Error::UNSUPPORTED;
1056 }
1057
1058 Error error = kDefaultError_2_4;
1059 mClient_2_4->getDisplayVsyncPeriod(display,
1060 [&](const auto& tmpError, const auto& tmpVsyncPeriod) {
1061 error = tmpError;
1062 if (error != Error::NONE) {
1063 return;
1064 }
1065
1066 *outVsyncPeriod = tmpVsyncPeriod;
1067 });
1068
1069 return error;
1070}
1071
1072V2_4::Error HidlComposer::setActiveConfigWithConstraints(
1073 Display display, Config config,
1074 const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
1075 VsyncPeriodChangeTimeline* outTimeline) {
1076 using Error = V2_4::Error;
1077 if (!mClient_2_4) {
1078 return Error::UNSUPPORTED;
1079 }
1080
1081 Error error = kDefaultError_2_4;
1082 mClient_2_4->setActiveConfigWithConstraints(display, config, vsyncPeriodChangeConstraints,
1083 [&](const auto& tmpError, const auto& tmpTimeline) {
1084 error = tmpError;
1085 if (error != Error::NONE) {
1086 return;
1087 }
1088
1089 *outTimeline = tmpTimeline;
1090 });
1091
1092 return error;
1093}
1094
1095V2_4::Error HidlComposer::setAutoLowLatencyMode(Display display, bool on) {
1096 using Error = V2_4::Error;
1097 if (!mClient_2_4) {
1098 return Error::UNSUPPORTED;
1099 }
1100
1101 return mClient_2_4->setAutoLowLatencyMode(display, on);
1102}
1103
1104V2_4::Error HidlComposer::getSupportedContentTypes(
1105 Display displayId, std::vector<IComposerClient::ContentType>* outSupportedContentTypes) {
1106 using Error = V2_4::Error;
1107 if (!mClient_2_4) {
1108 return Error::UNSUPPORTED;
1109 }
1110
1111 Error error = kDefaultError_2_4;
1112 mClient_2_4->getSupportedContentTypes(displayId,
1113 [&](const auto& tmpError,
1114 const auto& tmpSupportedContentTypes) {
1115 error = tmpError;
1116 if (error != Error::NONE) {
1117 return;
1118 }
1119
1120 *outSupportedContentTypes = tmpSupportedContentTypes;
1121 });
1122 return error;
1123}
1124
1125V2_4::Error HidlComposer::setContentType(Display display,
1126 IComposerClient::ContentType contentType) {
1127 using Error = V2_4::Error;
1128 if (!mClient_2_4) {
1129 return Error::UNSUPPORTED;
1130 }
1131
1132 return mClient_2_4->setContentType(display, contentType);
1133}
1134
1135V2_4::Error HidlComposer::setLayerGenericMetadata(Display display, Layer layer,
1136 const std::string& key, bool mandatory,
1137 const std::vector<uint8_t>& value) {
1138 using Error = V2_4::Error;
1139 if (!mClient_2_4) {
1140 return Error::UNSUPPORTED;
1141 }
1142 mWriter.selectDisplay(display);
1143 mWriter.selectLayer(layer);
1144 mWriter.setLayerGenericMetadata(key, mandatory, value);
1145 return Error::NONE;
1146}
1147
1148V2_4::Error HidlComposer::getLayerGenericMetadataKeys(
1149 std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) {
1150 using Error = V2_4::Error;
1151 if (!mClient_2_4) {
1152 return Error::UNSUPPORTED;
1153 }
1154 Error error = kDefaultError_2_4;
1155 mClient_2_4->getLayerGenericMetadataKeys([&](const auto& tmpError, const auto& tmpKeys) {
1156 error = tmpError;
1157 if (error != Error::NONE) {
1158 return;
1159 }
1160
1161 *outKeys = tmpKeys;
1162 });
1163 return error;
1164}
1165
1166Error HidlComposer::getClientTargetProperty(
Alec Mouricdf6cbc2021-11-01 17:21:15 -07001167 Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty,
1168 float* outWhitePointNits) {
Ady Abraham9fc28052021-10-14 17:21:38 -07001169 mReader.takeClientTargetProperty(display, outClientTargetProperty);
Alec Mouricdf6cbc2021-11-01 17:21:15 -07001170 *outWhitePointNits = -1.f;
1171 return Error::NONE;
1172}
1173
1174Error HidlComposer::setLayerWhitePointNits(Display, Layer, float) {
Ady Abraham9fc28052021-10-14 17:21:38 -07001175 return Error::NONE;
1176}
1177
1178CommandReader::~CommandReader() {
1179 resetData();
1180}
1181
1182Error CommandReader::parse() {
1183 resetData();
1184
1185 IComposerClient::Command command;
1186 uint16_t length = 0;
1187
1188 while (!isEmpty()) {
1189 if (!beginCommand(&command, &length)) {
1190 break;
1191 }
1192
1193 bool parsed = false;
1194 switch (command) {
1195 case IComposerClient::Command::SELECT_DISPLAY:
1196 parsed = parseSelectDisplay(length);
1197 break;
1198 case IComposerClient::Command::SET_ERROR:
1199 parsed = parseSetError(length);
1200 break;
1201 case IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES:
1202 parsed = parseSetChangedCompositionTypes(length);
1203 break;
1204 case IComposerClient::Command::SET_DISPLAY_REQUESTS:
1205 parsed = parseSetDisplayRequests(length);
1206 break;
1207 case IComposerClient::Command::SET_PRESENT_FENCE:
1208 parsed = parseSetPresentFence(length);
1209 break;
1210 case IComposerClient::Command::SET_RELEASE_FENCES:
1211 parsed = parseSetReleaseFences(length);
1212 break;
1213 case IComposerClient::Command ::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT:
1214 parsed = parseSetPresentOrValidateDisplayResult(length);
1215 break;
1216 case IComposerClient::Command::SET_CLIENT_TARGET_PROPERTY:
1217 parsed = parseSetClientTargetProperty(length);
1218 break;
1219 default:
1220 parsed = false;
1221 break;
1222 }
1223
1224 endCommand();
1225
1226 if (!parsed) {
1227 ALOGE("failed to parse command 0x%x length %" PRIu16, command, length);
1228 break;
1229 }
1230 }
1231
1232 return isEmpty() ? Error::NONE : Error::NO_RESOURCES;
1233}
1234
1235bool CommandReader::parseSelectDisplay(uint16_t length) {
1236 if (length != CommandWriterBase::kSelectDisplayLength) {
1237 return false;
1238 }
1239
1240 mCurrentReturnData = &mReturnData[read64()];
1241
1242 return true;
1243}
1244
1245bool CommandReader::parseSetError(uint16_t length) {
1246 if (length != CommandWriterBase::kSetErrorLength) {
1247 return false;
1248 }
1249
1250 auto location = read();
1251 auto error = static_cast<Error>(readSigned());
1252
1253 mErrors.emplace_back(CommandError{location, error});
1254
1255 return true;
1256}
1257
1258bool CommandReader::parseSetChangedCompositionTypes(uint16_t length) {
1259 // (layer id, composition type) pairs
1260 if (length % 3 != 0 || !mCurrentReturnData) {
1261 return false;
1262 }
1263
1264 uint32_t count = length / 3;
1265 mCurrentReturnData->changedLayers.reserve(count);
1266 mCurrentReturnData->compositionTypes.reserve(count);
1267 while (count > 0) {
1268 auto layer = read64();
1269 auto type = static_cast<IComposerClient::Composition>(readSigned());
1270
1271 mCurrentReturnData->changedLayers.push_back(layer);
1272 mCurrentReturnData->compositionTypes.push_back(type);
1273
1274 count--;
1275 }
1276
1277 return true;
1278}
1279
1280bool CommandReader::parseSetDisplayRequests(uint16_t length) {
1281 // display requests followed by (layer id, layer requests) pairs
1282 if (length % 3 != 1 || !mCurrentReturnData) {
1283 return false;
1284 }
1285
1286 mCurrentReturnData->displayRequests = read();
1287
1288 uint32_t count = (length - 1) / 3;
1289 mCurrentReturnData->requestedLayers.reserve(count);
1290 mCurrentReturnData->requestMasks.reserve(count);
1291 while (count > 0) {
1292 auto layer = read64();
1293 auto layerRequestMask = read();
1294
1295 mCurrentReturnData->requestedLayers.push_back(layer);
1296 mCurrentReturnData->requestMasks.push_back(layerRequestMask);
1297
1298 count--;
1299 }
1300
1301 return true;
1302}
1303
1304bool CommandReader::parseSetPresentFence(uint16_t length) {
1305 if (length != CommandWriterBase::kSetPresentFenceLength || !mCurrentReturnData) {
1306 return false;
1307 }
1308
1309 if (mCurrentReturnData->presentFence >= 0) {
1310 close(mCurrentReturnData->presentFence);
1311 }
1312 mCurrentReturnData->presentFence = readFence();
1313
1314 return true;
1315}
1316
1317bool CommandReader::parseSetReleaseFences(uint16_t length) {
1318 // (layer id, release fence index) pairs
1319 if (length % 3 != 0 || !mCurrentReturnData) {
1320 return false;
1321 }
1322
1323 uint32_t count = length / 3;
1324 mCurrentReturnData->releasedLayers.reserve(count);
1325 mCurrentReturnData->releaseFences.reserve(count);
1326 while (count > 0) {
1327 auto layer = read64();
1328 auto fence = readFence();
1329
1330 mCurrentReturnData->releasedLayers.push_back(layer);
1331 mCurrentReturnData->releaseFences.push_back(fence);
1332
1333 count--;
1334 }
1335
1336 return true;
1337}
1338
1339bool CommandReader::parseSetPresentOrValidateDisplayResult(uint16_t length) {
1340 if (length != CommandWriterBase::kPresentOrValidateDisplayResultLength || !mCurrentReturnData) {
1341 return false;
1342 }
1343 mCurrentReturnData->presentOrValidateState = read();
1344 return true;
1345}
1346
1347bool CommandReader::parseSetClientTargetProperty(uint16_t length) {
1348 if (length != CommandWriterBase::kSetClientTargetPropertyLength || !mCurrentReturnData) {
1349 return false;
1350 }
1351 mCurrentReturnData->clientTargetProperty.pixelFormat = static_cast<PixelFormat>(readSigned());
1352 mCurrentReturnData->clientTargetProperty.dataspace = static_cast<Dataspace>(readSigned());
1353 return true;
1354}
1355
1356void CommandReader::resetData() {
1357 mErrors.clear();
1358
1359 for (auto& data : mReturnData) {
1360 if (data.second.presentFence >= 0) {
1361 close(data.second.presentFence);
1362 }
1363 for (auto fence : data.second.releaseFences) {
1364 if (fence >= 0) {
1365 close(fence);
1366 }
1367 }
1368 }
1369
1370 mReturnData.clear();
1371 mCurrentReturnData = nullptr;
1372}
1373
1374std::vector<CommandReader::CommandError> CommandReader::takeErrors() {
1375 return std::move(mErrors);
1376}
1377
1378bool CommandReader::hasChanges(Display display, uint32_t* outNumChangedCompositionTypes,
1379 uint32_t* outNumLayerRequestMasks) const {
1380 auto found = mReturnData.find(display);
1381 if (found == mReturnData.end()) {
1382 *outNumChangedCompositionTypes = 0;
1383 *outNumLayerRequestMasks = 0;
1384 return false;
1385 }
1386
1387 const ReturnData& data = found->second;
1388
1389 *outNumChangedCompositionTypes = data.compositionTypes.size();
1390 *outNumLayerRequestMasks = data.requestMasks.size();
1391
1392 return !(data.compositionTypes.empty() && data.requestMasks.empty());
1393}
1394
1395void CommandReader::takeChangedCompositionTypes(
1396 Display display, std::vector<Layer>* outLayers,
1397 std::vector<IComposerClient::Composition>* outTypes) {
1398 auto found = mReturnData.find(display);
1399 if (found == mReturnData.end()) {
1400 outLayers->clear();
1401 outTypes->clear();
1402 return;
1403 }
1404
1405 ReturnData& data = found->second;
1406
1407 *outLayers = std::move(data.changedLayers);
1408 *outTypes = std::move(data.compositionTypes);
1409}
1410
1411void CommandReader::takeDisplayRequests(Display display, uint32_t* outDisplayRequestMask,
1412 std::vector<Layer>* outLayers,
1413 std::vector<uint32_t>* outLayerRequestMasks) {
1414 auto found = mReturnData.find(display);
1415 if (found == mReturnData.end()) {
1416 *outDisplayRequestMask = 0;
1417 outLayers->clear();
1418 outLayerRequestMasks->clear();
1419 return;
1420 }
1421
1422 ReturnData& data = found->second;
1423
1424 *outDisplayRequestMask = data.displayRequests;
1425 *outLayers = std::move(data.requestedLayers);
1426 *outLayerRequestMasks = std::move(data.requestMasks);
1427}
1428
1429void CommandReader::takeReleaseFences(Display display, std::vector<Layer>* outLayers,
1430 std::vector<int>* outReleaseFences) {
1431 auto found = mReturnData.find(display);
1432 if (found == mReturnData.end()) {
1433 outLayers->clear();
1434 outReleaseFences->clear();
1435 return;
1436 }
1437
1438 ReturnData& data = found->second;
1439
1440 *outLayers = std::move(data.releasedLayers);
1441 *outReleaseFences = std::move(data.releaseFences);
1442}
1443
1444void CommandReader::takePresentFence(Display display, int* outPresentFence) {
1445 auto found = mReturnData.find(display);
1446 if (found == mReturnData.end()) {
1447 *outPresentFence = -1;
1448 return;
1449 }
1450
1451 ReturnData& data = found->second;
1452
1453 *outPresentFence = data.presentFence;
1454 data.presentFence = -1;
1455}
1456
1457void CommandReader::takePresentOrValidateStage(Display display, uint32_t* state) {
1458 auto found = mReturnData.find(display);
1459 if (found == mReturnData.end()) {
1460 *state = -1;
1461 return;
1462 }
1463 ReturnData& data = found->second;
1464 *state = data.presentOrValidateState;
1465}
1466
1467void CommandReader::takeClientTargetProperty(
1468 Display display, IComposerClient::ClientTargetProperty* outClientTargetProperty) {
1469 auto found = mReturnData.find(display);
1470
1471 // If not found, return the default values.
1472 if (found == mReturnData.end()) {
1473 outClientTargetProperty->pixelFormat = PixelFormat::RGBA_8888;
1474 outClientTargetProperty->dataspace = Dataspace::UNKNOWN;
1475 return;
1476 }
1477
1478 ReturnData& data = found->second;
1479 *outClientTargetProperty = data.clientTargetProperty;
1480}
1481
1482} // namespace Hwc2
1483} // namespace android
1484
1485// TODO(b/129481165): remove the #pragma below and fix conversion issues
1486#pragma clang diagnostic pop // ignored "-Wconversion"