blob: f09482cd2c229e6cc514b7944af1a17542223ce0 [file] [log] [blame]
ramindaniedf3ef92022-01-07 00:04:23 +00001/**
2 * Copyright (c) 2022, 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
ramindani458e53e2022-02-23 17:30:16 +000017#include "VtsComposerClient.h"
ramindaniedf3ef92022-01-07 00:04:23 +000018#include <aidlcommonsupport/NativeHandle.h>
19#include <android-base/logging.h>
20#include <log/log_main.h>
21
22#undef LOG_TAG
23#define LOG_TAG "VtsComposerClient"
24
25using namespace std::chrono_literals;
26
27namespace aidl::android::hardware::graphics::composer3::vts {
28
29VtsComposerClient::VtsComposerClient(const std::string& name) {
30 SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
31 ALOGE_IF(binder == nullptr, "Could not initialize the service binder");
32 if (binder != nullptr) {
33 mComposer = IComposer::fromBinder(binder);
34 ALOGE_IF(mComposer == nullptr, "Failed to acquire the composer from the binder");
35 }
Ady Abrahama00d2462023-12-26 14:21:20 -080036
37 const auto& [status, capabilities] = getCapabilities();
38 EXPECT_TRUE(status.isOk());
39 if (std::any_of(capabilities.begin(), capabilities.end(), [&](const Capability& cap) {
40 return cap == Capability::LAYER_LIFECYCLE_BATCH_COMMAND;
41 })) {
42 mSupportsBatchedCreateLayer = true;
43 }
ramindaniedf3ef92022-01-07 00:04:23 +000044}
45
46ScopedAStatus VtsComposerClient::createClient() {
47 if (mComposer == nullptr) {
48 ALOGE("IComposer not initialized");
49 return ScopedAStatus::fromServiceSpecificError(IComposerClient::INVALID_CONFIGURATION);
50 }
51 auto status = mComposer->createClient(&mComposerClient);
52 if (!status.isOk() || mComposerClient == nullptr) {
53 ALOGE("Failed to create client for IComposerClient with %s",
54 status.getDescription().c_str());
55 return status;
56 }
57 mComposerCallback = SharedRefBase::make<GraphicsComposerCallback>();
58 if (mComposerCallback == nullptr) {
59 ALOGE("Unable to create ComposerCallback");
60 return ScopedAStatus::fromServiceSpecificError(IComposerClient::INVALID_CONFIGURATION);
61 }
62 return mComposerClient->registerCallback(mComposerCallback);
63}
64
Ady Abrahama00d2462023-12-26 14:21:20 -080065bool VtsComposerClient::tearDown(ComposerClientWriter* writer) {
66 return verifyComposerCallbackParams() && destroyAllLayers(writer);
ramindaniedf3ef92022-01-07 00:04:23 +000067}
68
ramindani02fe4772023-06-30 18:04:41 -070069std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() const {
Brian Lindahl78ff2d62022-12-18 11:21:41 -070070 int32_t version = 1;
Leon Scroggins III94f4b202024-01-09 11:43:45 -050071 if (!mComposerClient) {
72 return {ScopedAStatus{nullptr}, version};
73 }
Brian Lindahl78ff2d62022-12-18 11:21:41 -070074 auto status = mComposerClient->getInterfaceVersion(&version);
75 return {std::move(status), version};
76}
77
ramindaniedf3ef92022-01-07 00:04:23 +000078std::pair<ScopedAStatus, VirtualDisplay> VtsComposerClient::createVirtualDisplay(
79 int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount) {
80 VirtualDisplay outVirtualDisplay;
81 auto status = mComposerClient->createVirtualDisplay(width, height, pixelFormat, bufferSlotCount,
82 &outVirtualDisplay);
83 if (!status.isOk()) {
84 return {std::move(status), outVirtualDisplay};
85 }
86 return {addDisplayToDisplayResources(outVirtualDisplay.display, /*isVirtual*/ true),
87 outVirtualDisplay};
88}
89
90ScopedAStatus VtsComposerClient::destroyVirtualDisplay(int64_t display) {
91 auto status = mComposerClient->destroyVirtualDisplay(display);
92 if (!status.isOk()) {
93 return status;
94 }
95 mDisplayResources.erase(display);
96 return status;
97}
98
99std::pair<ScopedAStatus, int64_t> VtsComposerClient::createLayer(int64_t display,
Ady Abrahama00d2462023-12-26 14:21:20 -0800100 int32_t bufferSlotCount,
101 ComposerClientWriter* writer) {
102 if (mSupportsBatchedCreateLayer) {
103 int64_t layer = mNextLayerHandle++;
104 writer->setLayerLifecycleBatchCommandType(display, layer,
105 LayerLifecycleBatchCommandType::CREATE);
106 writer->setNewBufferSlotCount(display, layer, bufferSlotCount);
107 return {addLayerToDisplayResources(display, layer), layer};
108 }
109
ramindaniedf3ef92022-01-07 00:04:23 +0000110 int64_t outLayer;
111 auto status = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
112
113 if (!status.isOk()) {
114 return {std::move(status), outLayer};
115 }
116 return {addLayerToDisplayResources(display, outLayer), outLayer};
117}
118
Ady Abrahama00d2462023-12-26 14:21:20 -0800119ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer,
120 ComposerClientWriter* writer) {
121 if (mSupportsBatchedCreateLayer) {
122 writer->setLayerLifecycleBatchCommandType(display, layer,
123 LayerLifecycleBatchCommandType::DESTROY);
124 } else {
125 auto status = mComposerClient->destroyLayer(display, layer);
126 if (!status.isOk()) {
127 return status;
128 }
ramindaniedf3ef92022-01-07 00:04:23 +0000129 }
Ady Abrahama00d2462023-12-26 14:21:20 -0800130
ramindaniedf3ef92022-01-07 00:04:23 +0000131 removeLayerFromDisplayResources(display, layer);
Ady Abrahama00d2462023-12-26 14:21:20 -0800132 return ScopedAStatus::ok();
ramindaniedf3ef92022-01-07 00:04:23 +0000133}
134
135std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
136 int32_t outConfig;
137 return {mComposerClient->getActiveConfig(display, &outConfig), outConfig};
138}
139
140ScopedAStatus VtsComposerClient::setActiveConfig(VtsDisplay* vtsDisplay, int32_t config) {
141 auto status = mComposerClient->setActiveConfig(vtsDisplay->getDisplayId(), config);
142 if (!status.isOk()) {
143 return status;
144 }
145 return updateDisplayProperties(vtsDisplay, config);
146}
147
ramindani9dd8c482023-02-21 18:07:56 -0800148ScopedAStatus VtsComposerClient::setPeakRefreshRateConfig(VtsDisplay* vtsDisplay) {
149 const auto displayId = vtsDisplay->getDisplayId();
150 auto [activeStatus, activeConfig] = getActiveConfig(displayId);
151 EXPECT_TRUE(activeStatus.isOk());
152 auto peakDisplayConfig = vtsDisplay->getDisplayConfig(activeConfig);
153 auto peakConfig = activeConfig;
154
155 const auto displayConfigs = vtsDisplay->getDisplayConfigs();
156 for (const auto [config, displayConfig] : displayConfigs) {
157 if (displayConfig.configGroup == peakDisplayConfig.configGroup &&
158 displayConfig.vsyncPeriod < peakDisplayConfig.vsyncPeriod) {
159 peakDisplayConfig = displayConfig;
160 peakConfig = config;
161 }
162 }
163 return setActiveConfig(vtsDisplay, peakConfig);
164}
165
ramindaniedf3ef92022-01-07 00:04:23 +0000166std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute(
167 int64_t display, int32_t config, DisplayAttribute displayAttribute) {
168 int32_t outDisplayAttribute;
169 return {mComposerClient->getDisplayAttribute(display, config, displayAttribute,
170 &outDisplayAttribute),
171 outDisplayAttribute};
172}
173
174ScopedAStatus VtsComposerClient::setPowerMode(int64_t display, PowerMode powerMode) {
175 return mComposerClient->setPowerMode(display, powerMode);
176}
177
178ScopedAStatus VtsComposerClient::setVsync(int64_t display, bool enable) {
179 return mComposerClient->setVsyncEnabled(display, enable);
180}
181
182void VtsComposerClient::setVsyncAllowed(bool isAllowed) {
183 mComposerCallback->setVsyncAllowed(isAllowed);
184}
185
186std::pair<ScopedAStatus, std::vector<float>> VtsComposerClient::getDataspaceSaturationMatrix(
187 Dataspace dataspace) {
188 std::vector<float> outMatrix;
189 return {mComposerClient->getDataspaceSaturationMatrix(dataspace, &outMatrix), outMatrix};
190}
191
192std::pair<ScopedAStatus, std::vector<CommandResultPayload>> VtsComposerClient::executeCommands(
193 const std::vector<DisplayCommand>& commands) {
194 std::vector<CommandResultPayload> outResultPayload;
195 return {mComposerClient->executeCommands(commands, &outResultPayload),
196 std::move(outResultPayload)};
197}
198
199std::optional<VsyncPeriodChangeTimeline> VtsComposerClient::takeLastVsyncPeriodChangeTimeline() {
200 return mComposerCallback->takeLastVsyncPeriodChangeTimeline();
201}
202
203ScopedAStatus VtsComposerClient::setContentType(int64_t display, ContentType contentType) {
204 return mComposerClient->setContentType(display, contentType);
205}
206
207std::pair<ScopedAStatus, VsyncPeriodChangeTimeline>
208VtsComposerClient::setActiveConfigWithConstraints(VtsDisplay* vtsDisplay, int32_t config,
209 const VsyncPeriodChangeConstraints& constraints) {
210 VsyncPeriodChangeTimeline outTimeline;
211 auto status = mComposerClient->setActiveConfigWithConstraints(
212 vtsDisplay->getDisplayId(), config, constraints, &outTimeline);
213 if (!status.isOk()) {
214 return {std::move(status), outTimeline};
215 }
216 return {updateDisplayProperties(vtsDisplay, config), outTimeline};
217}
218
219std::pair<ScopedAStatus, std::vector<DisplayCapability>> VtsComposerClient::getDisplayCapabilities(
220 int64_t display) {
221 std::vector<DisplayCapability> outCapabilities;
222 return {mComposerClient->getDisplayCapabilities(display, &outCapabilities), outCapabilities};
223}
224
225ScopedAStatus VtsComposerClient::dumpDebugInfo() {
Ady Abraham89d72702022-02-18 17:04:55 -0800226 int pipefds[2];
227 if (pipe(pipefds) < 0) {
228 return ScopedAStatus::fromServiceSpecificError(IComposer::EX_NO_RESOURCES);
229 }
230
231 const auto status = mComposer->dump(pipefds[1], /*args*/ nullptr, /*numArgs*/ 0);
232 close(pipefds[0]);
233 close(pipefds[1]);
234 return ScopedAStatus::fromStatus(status);
ramindaniedf3ef92022-01-07 00:04:23 +0000235}
236
237std::pair<ScopedAStatus, DisplayIdentification> VtsComposerClient::getDisplayIdentificationData(
238 int64_t display) {
239 DisplayIdentification outDisplayIdentification;
240 return {mComposerClient->getDisplayIdentificationData(display, &outDisplayIdentification),
241 outDisplayIdentification};
242}
243
244std::pair<ScopedAStatus, HdrCapabilities> VtsComposerClient::getHdrCapabilities(int64_t display) {
245 HdrCapabilities outHdrCapabilities;
246 return {mComposerClient->getHdrCapabilities(display, &outHdrCapabilities), outHdrCapabilities};
247}
248
249std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>>
250VtsComposerClient::getPerFrameMetadataKeys(int64_t display) {
251 std::vector<PerFrameMetadataKey> outPerFrameMetadataKeys;
252 return {mComposerClient->getPerFrameMetadataKeys(display, &outPerFrameMetadataKeys),
253 outPerFrameMetadataKeys};
254}
255
256std::pair<ScopedAStatus, ReadbackBufferAttributes> VtsComposerClient::getReadbackBufferAttributes(
257 int64_t display) {
258 ReadbackBufferAttributes outReadbackBufferAttributes;
259 return {mComposerClient->getReadbackBufferAttributes(display, &outReadbackBufferAttributes),
260 outReadbackBufferAttributes};
261}
262
263ScopedAStatus VtsComposerClient::setReadbackBuffer(int64_t display, const native_handle_t* buffer,
264 const ScopedFileDescriptor& releaseFence) {
265 return mComposerClient->setReadbackBuffer(display, ::android::dupToAidl(buffer), releaseFence);
266}
267
268std::pair<ScopedAStatus, ScopedFileDescriptor> VtsComposerClient::getReadbackBufferFence(
269 int64_t display) {
270 ScopedFileDescriptor outReleaseFence;
271 return {mComposerClient->getReadbackBufferFence(display, &outReleaseFence),
272 std::move(outReleaseFence)};
273}
274
275std::pair<ScopedAStatus, std::vector<ColorMode>> VtsComposerClient::getColorModes(int64_t display) {
276 std::vector<ColorMode> outColorModes;
277 return {mComposerClient->getColorModes(display, &outColorModes), outColorModes};
278}
279
280std::pair<ScopedAStatus, std::vector<RenderIntent>> VtsComposerClient::getRenderIntents(
281 int64_t display, ColorMode colorMode) {
282 std::vector<RenderIntent> outRenderIntents;
283 return {mComposerClient->getRenderIntents(display, colorMode, &outRenderIntents),
284 outRenderIntents};
285}
286
287ScopedAStatus VtsComposerClient::setColorMode(int64_t display, ColorMode colorMode,
288 RenderIntent renderIntent) {
289 return mComposerClient->setColorMode(display, colorMode, renderIntent);
290}
291
292std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
293VtsComposerClient::getDisplayedContentSamplingAttributes(int64_t display) {
294 DisplayContentSamplingAttributes outAttributes;
295 return {mComposerClient->getDisplayedContentSamplingAttributes(display, &outAttributes),
296 outAttributes};
297}
298
299ScopedAStatus VtsComposerClient::setDisplayedContentSamplingEnabled(
300 int64_t display, bool isEnabled, FormatColorComponent formatColorComponent,
301 int64_t maxFrames) {
302 return mComposerClient->setDisplayedContentSamplingEnabled(display, isEnabled,
303 formatColorComponent, maxFrames);
304}
305
306std::pair<ScopedAStatus, DisplayContentSample> VtsComposerClient::getDisplayedContentSample(
307 int64_t display, int64_t maxFrames, int64_t timestamp) {
308 DisplayContentSample outDisplayContentSample;
309 return {mComposerClient->getDisplayedContentSample(display, maxFrames, timestamp,
310 &outDisplayContentSample),
311 outDisplayContentSample};
312}
313
314std::pair<ScopedAStatus, DisplayConnectionType> VtsComposerClient::getDisplayConnectionType(
315 int64_t display) {
316 DisplayConnectionType outDisplayConnectionType;
317 return {mComposerClient->getDisplayConnectionType(display, &outDisplayConnectionType),
318 outDisplayConnectionType};
319}
320
321std::pair<ScopedAStatus, std::vector<int32_t>> VtsComposerClient::getDisplayConfigs(
322 int64_t display) {
323 std::vector<int32_t> outConfigs;
ramindani02fe4772023-06-30 18:04:41 -0700324 if (!getDisplayConfigurationSupported()) {
325 return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs};
326 }
327
328 auto [status, configs] = getDisplayConfigurations(display);
329 if (!status.isOk()) {
330 return {std::move(status), outConfigs};
331 }
332 for (const auto& config : configs) {
333 outConfigs.emplace_back(config.configId);
334 }
335 return {std::move(status), outConfigs};
336}
337
338std::pair<ScopedAStatus, std::vector<DisplayConfiguration>>
339VtsComposerClient::getDisplayConfigurations(int64_t display) {
340 std::vector<DisplayConfiguration> outConfigs;
ramindani2704c5f2023-07-18 20:53:24 -0700341 return {mComposerClient->getDisplayConfigurations(display, kMaxFrameIntervalNs, &outConfigs),
342 outConfigs};
343}
344
345ScopedAStatus VtsComposerClient::notifyExpectedPresent(int64_t display,
346 ClockMonotonicTimestamp expectedPresentTime,
347 int frameIntervalNs) {
348 return mComposerClient->notifyExpectedPresent(display, expectedPresentTime, frameIntervalNs);
ramindaniedf3ef92022-01-07 00:04:23 +0000349}
350
351std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayVsyncPeriod(int64_t display) {
352 int32_t outVsyncPeriodNanos;
353 return {mComposerClient->getDisplayVsyncPeriod(display, &outVsyncPeriodNanos),
354 outVsyncPeriodNanos};
355}
356
357ScopedAStatus VtsComposerClient::setAutoLowLatencyMode(int64_t display, bool isEnabled) {
358 return mComposerClient->setAutoLowLatencyMode(display, isEnabled);
359}
360
361std::pair<ScopedAStatus, std::vector<ContentType>> VtsComposerClient::getSupportedContentTypes(
362 int64_t display) {
363 std::vector<ContentType> outContentTypes;
364 return {mComposerClient->getSupportedContentTypes(display, &outContentTypes), outContentTypes};
365}
366
Leon Scroggins IIIde057582022-01-13 12:26:00 -0500367std::pair<ScopedAStatus, std::optional<DisplayDecorationSupport>>
368VtsComposerClient::getDisplayDecorationSupport(int64_t display) {
369 std::optional<DisplayDecorationSupport> outSupport;
370 return {mComposerClient->getDisplayDecorationSupport(display, &outSupport), outSupport};
371}
372
ramindaniedf3ef92022-01-07 00:04:23 +0000373std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxVirtualDisplayCount() {
374 int32_t outMaxVirtualDisplayCount;
375 return {mComposerClient->getMaxVirtualDisplayCount(&outMaxVirtualDisplayCount),
376 outMaxVirtualDisplayCount};
377}
378
379std::pair<ScopedAStatus, std::string> VtsComposerClient::getDisplayName(int64_t display) {
380 std::string outDisplayName;
381 return {mComposerClient->getDisplayName(display, &outDisplayName), outDisplayName};
382}
383
384ScopedAStatus VtsComposerClient::setClientTargetSlotCount(int64_t display,
385 int32_t bufferSlotCount) {
386 return mComposerClient->setClientTargetSlotCount(display, bufferSlotCount);
387}
388
389std::pair<ScopedAStatus, std::vector<Capability>> VtsComposerClient::getCapabilities() {
390 std::vector<Capability> outCapabilities;
391 return {mComposer->getCapabilities(&outCapabilities), outCapabilities};
392}
393
394ScopedAStatus VtsComposerClient::setBootDisplayConfig(int64_t display, int32_t config) {
395 return mComposerClient->setBootDisplayConfig(display, config);
396}
397
398ScopedAStatus VtsComposerClient::clearBootDisplayConfig(int64_t display) {
399 return mComposerClient->clearBootDisplayConfig(display);
400}
401
402std::pair<ScopedAStatus, int32_t> VtsComposerClient::getPreferredBootDisplayConfig(
403 int64_t display) {
404 int32_t outConfig;
405 return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
406}
407
Kriti Dang3793ebd2022-12-05 13:03:49 +0100408std::pair<ScopedAStatus, std::vector<common::HdrConversionCapability>>
409VtsComposerClient::getHdrConversionCapabilities() {
410 std::vector<common::HdrConversionCapability> hdrConversionCapability;
411 return {mComposerClient->getHdrConversionCapabilities(&hdrConversionCapability),
412 hdrConversionCapability};
413}
414
Kriti Dang37622762023-02-09 18:15:37 +0100415std::pair<ScopedAStatus, common::Hdr> VtsComposerClient::setHdrConversionStrategy(
Kriti Dang3793ebd2022-12-05 13:03:49 +0100416 const common::HdrConversionStrategy& conversionStrategy) {
Kriti Dang37622762023-02-09 18:15:37 +0100417 common::Hdr preferredHdrOutputType;
418 return {mComposerClient->setHdrConversionStrategy(conversionStrategy, &preferredHdrOutputType),
419 preferredHdrOutputType};
Kriti Dang3793ebd2022-12-05 13:03:49 +0100420}
421
ramindaniedf3ef92022-01-07 00:04:23 +0000422std::pair<ScopedAStatus, common::Transform> VtsComposerClient::getDisplayPhysicalOrientation(
423 int64_t display) {
424 common::Transform outDisplayOrientation;
425 return {mComposerClient->getDisplayPhysicalOrientation(display, &outDisplayOrientation),
426 outDisplayOrientation};
427}
428
Sally Qi2600d342022-08-16 12:46:17 -0700429std::pair<ScopedAStatus, composer3::OverlayProperties> VtsComposerClient::getOverlaySupport() {
430 OverlayProperties properties;
431 return {mComposerClient->getOverlaySupport(&properties), properties};
432}
433
ramindaniedf3ef92022-01-07 00:04:23 +0000434ScopedAStatus VtsComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeoutMs) {
435 return mComposerClient->setIdleTimerEnabled(display, timeoutMs);
436}
437
438int32_t VtsComposerClient::getVsyncIdleCount() {
439 return mComposerCallback->getVsyncIdleCount();
440}
441
442int64_t VtsComposerClient::getVsyncIdleTime() {
443 return mComposerCallback->getVsyncIdleTime();
444}
445
ramindani9dd8c482023-02-21 18:07:56 -0800446ndk::ScopedAStatus VtsComposerClient::setRefreshRateChangedCallbackDebugEnabled(int64_t display,
447 bool enabled) {
448 mComposerCallback->setRefreshRateChangedDebugDataEnabledCallbackAllowed(enabled);
449 return mComposerClient->setRefreshRateChangedCallbackDebugEnabled(display, enabled);
450}
451
452std::vector<RefreshRateChangedDebugData>
453VtsComposerClient::takeListOfRefreshRateChangedDebugData() {
454 return mComposerCallback->takeListOfRefreshRateChangedDebugData();
ramindani83450342023-02-03 12:52:08 -0800455}
456
ramindaniedf3ef92022-01-07 00:04:23 +0000457int64_t VtsComposerClient::getInvalidDisplayId() {
458 // returns an invalid display id (one that has not been registered to a
459 // display. Currently assuming that a device will never have close to
460 // std::numeric_limit<uint64_t>::max() displays registered while running tests
461 int64_t id = std::numeric_limits<int64_t>::max();
462 std::vector<int64_t> displays = mComposerCallback->getDisplays();
463 while (id > 0) {
464 if (std::none_of(displays.begin(), displays.end(),
465 [id](const auto& display) { return id == display; })) {
466 return id;
467 }
468 id--;
469 }
470
471 // Although 0 could be an invalid display, a return value of 0
472 // from getInvalidDisplayId means all other ids are in use, a condition which
473 // we are assuming a device will never have
474 EXPECT_NE(0, id);
475 return id;
476}
477
478std::pair<ScopedAStatus, std::vector<VtsDisplay>> VtsComposerClient::getDisplays() {
479 while (true) {
480 // Sleep for a small period of time to allow all built-in displays
481 // to post hotplug events
482 std::this_thread::sleep_for(5ms);
483 std::vector<int64_t> displays = mComposerCallback->getDisplays();
484 if (displays.empty()) {
485 continue;
486 }
487
488 std::vector<VtsDisplay> vtsDisplays;
489 vtsDisplays.reserve(displays.size());
490 for (int64_t display : displays) {
491 auto vtsDisplay = VtsDisplay{display};
ramindani02fe4772023-06-30 18:04:41 -0700492 if (getDisplayConfigurationSupported()) {
493 auto [status, configs] = getDisplayConfigurations(display);
ramindaniedf3ef92022-01-07 00:04:23 +0000494 if (!status.isOk()) {
ramindani02fe4772023-06-30 18:04:41 -0700495 ALOGE("Unable to get the displays for test, failed to get the DisplayConfigs "
ramindaniedf3ef92022-01-07 00:04:23 +0000496 "for display %" PRId64,
497 display);
498 return {std::move(status), vtsDisplays};
499 }
ramindani02fe4772023-06-30 18:04:41 -0700500 addDisplayConfigs(&vtsDisplay, configs);
501 } else {
502 auto [status, configs] = getDisplayConfigs(display);
503 if (!status.isOk()) {
504 ALOGE("Unable to get the displays for test, failed to get the configs "
505 "for display %" PRId64,
506 display);
507 return {std::move(status), vtsDisplays};
508 }
509 for (int config : configs) {
510 status = addDisplayConfigLegacy(&vtsDisplay, config);
511 if (!status.isOk()) {
512 ALOGE("Unable to get the displays for test, failed to add config "
513 "for display %" PRId64,
514 display);
515 return {std::move(status), vtsDisplays};
516 }
517 }
ramindaniedf3ef92022-01-07 00:04:23 +0000518 }
ramindani02fe4772023-06-30 18:04:41 -0700519 auto activeConfig = getActiveConfig(display);
520 if (!activeConfig.first.isOk()) {
HyunKyoung4775bdc2022-11-09 20:43:34 +0900521 ALOGE("Unable to get the displays for test, failed to get active config "
ramindani02fe4772023-06-30 18:04:41 -0700522 "for display %" PRId64,
523 display);
524 return {std::move(activeConfig.first), vtsDisplays};
HyunKyoung4775bdc2022-11-09 20:43:34 +0900525 }
ramindani02fe4772023-06-30 18:04:41 -0700526 auto status = updateDisplayProperties(&vtsDisplay, activeConfig.second);
HyunKyoung4775bdc2022-11-09 20:43:34 +0900527 if (!status.isOk()) {
528 ALOGE("Unable to get the displays for test, "
529 "failed to update the properties "
530 "for display %" PRId64,
531 display);
532 return {std::move(status), vtsDisplays};
533 }
534
ramindaniedf3ef92022-01-07 00:04:23 +0000535 vtsDisplays.emplace_back(vtsDisplay);
536 addDisplayToDisplayResources(display, /*isVirtual*/ false);
537 }
538
539 return {ScopedAStatus::ok(), vtsDisplays};
540 }
541}
542
ramindani02fe4772023-06-30 18:04:41 -0700543void VtsComposerClient::addDisplayConfigs(VtsDisplay* vtsDisplay,
544 const std::vector<DisplayConfiguration>& configs) {
545 for (const auto& config : configs) {
ramindania2a6dea2023-12-11 13:42:36 -0800546 vtsDisplay->addDisplayConfig(config.configId,
547 {config.vsyncPeriod, config.configGroup, config.vrrConfig});
ramindani02fe4772023-06-30 18:04:41 -0700548 }
549}
550
551ScopedAStatus VtsComposerClient::addDisplayConfigLegacy(VtsDisplay* vtsDisplay, int32_t config) {
ramindaniedf3ef92022-01-07 00:04:23 +0000552 const auto vsyncPeriod =
553 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::VSYNC_PERIOD);
554 const auto configGroup =
555 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::CONFIG_GROUP);
ramindani02fe4772023-06-30 18:04:41 -0700556 if (vsyncPeriod.first.isOk() && configGroup.first.isOk()) {
ramindaniedf3ef92022-01-07 00:04:23 +0000557 vtsDisplay->addDisplayConfig(config, {vsyncPeriod.second, configGroup.second});
558 return ScopedAStatus::ok();
559 }
560
ramindani02fe4772023-06-30 18:04:41 -0700561 LOG(ERROR) << "Failed to update display property vsync: " << vsyncPeriod.first.isOk()
ramindaniedf3ef92022-01-07 00:04:23 +0000562 << ", config: " << configGroup.first.isOk();
563 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
564}
565
HyunKyoung4775bdc2022-11-09 20:43:34 +0900566ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config) {
ramindani02fe4772023-06-30 18:04:41 -0700567 if (getDisplayConfigurationSupported()) {
568 auto [status, configs] = getDisplayConfigurations(vtsDisplay->getDisplayId());
569 if (status.isOk()) {
570 for (const auto& displayConfig : configs) {
571 if (displayConfig.configId == config) {
572 vtsDisplay->setDimensions(displayConfig.width, displayConfig.height);
573 return ScopedAStatus::ok();
574 }
575 }
576 }
577 LOG(ERROR) << "Failed to update display property with DisplayConfig";
578 } else {
579 const auto width =
580 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
581 const auto height =
582 getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT);
583 if (width.first.isOk() && height.first.isOk()) {
584 vtsDisplay->setDimensions(width.second, height.second);
585 return ScopedAStatus::ok();
586 }
HyunKyoung4775bdc2022-11-09 20:43:34 +0900587
ramindani02fe4772023-06-30 18:04:41 -0700588 LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
589 << ", height: " << height.first.isOk();
590 }
HyunKyoung4775bdc2022-11-09 20:43:34 +0900591 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
592}
593
ramindaniedf3ef92022-01-07 00:04:23 +0000594ScopedAStatus VtsComposerClient::addDisplayToDisplayResources(int64_t display, bool isVirtual) {
595 if (mDisplayResources.insert({display, DisplayResource(isVirtual)}).second) {
596 return ScopedAStatus::ok();
597 }
598
599 ALOGE("Duplicate display id %" PRId64, display);
600 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_DISPLAY);
601}
602
603ScopedAStatus VtsComposerClient::addLayerToDisplayResources(int64_t display, int64_t layer) {
604 auto resource = mDisplayResources.find(display);
605 if (resource == mDisplayResources.end()) {
606 resource = mDisplayResources.insert({display, DisplayResource(false)}).first;
607 }
608
609 if (!resource->second.layers.insert(layer).second) {
610 ALOGE("Duplicate layer id %" PRId64, layer);
611 return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_LAYER);
612 }
613 return ScopedAStatus::ok();
614}
615
616void VtsComposerClient::removeLayerFromDisplayResources(int64_t display, int64_t layer) {
617 auto resource = mDisplayResources.find(display);
618 if (resource != mDisplayResources.end()) {
619 resource->second.layers.erase(layer);
620 }
621}
622
623bool VtsComposerClient::verifyComposerCallbackParams() {
624 bool isValid = true;
625 if (mComposerCallback != nullptr) {
626 if (mComposerCallback->getInvalidHotplugCount() != 0) {
627 ALOGE("Invalid hotplug count");
628 isValid = false;
629 }
630 if (mComposerCallback->getInvalidRefreshCount() != 0) {
631 ALOGE("Invalid refresh count");
632 isValid = false;
633 }
634 if (mComposerCallback->getInvalidVsyncCount() != 0) {
635 ALOGE("Invalid vsync count");
636 isValid = false;
637 }
638 if (mComposerCallback->getInvalidVsyncPeriodChangeCount() != 0) {
639 ALOGE("Invalid vsync period change count");
640 isValid = false;
641 }
642 if (mComposerCallback->getInvalidSeamlessPossibleCount() != 0) {
643 ALOGE("Invalid seamless possible count");
644 isValid = false;
645 }
ramindani9dd8c482023-02-21 18:07:56 -0800646 if (mComposerCallback->getInvalidRefreshRateDebugEnabledCallbackCount() != 0) {
647 ALOGE("Invalid refresh rate debug enabled callback count");
648 isValid = false;
649 }
ramindaniedf3ef92022-01-07 00:04:23 +0000650 }
651 return isValid;
652}
653
ramindani02fe4772023-06-30 18:04:41 -0700654bool VtsComposerClient::getDisplayConfigurationSupported() const {
655 auto [status, interfaceVersion] = getInterfaceVersion();
656 EXPECT_TRUE(status.isOk());
657 // getDisplayConfigurations api is supported starting interface version 3
658 return interfaceVersion >= 3;
659}
660
Ady Abrahama00d2462023-12-26 14:21:20 -0800661bool VtsComposerClient::destroyAllLayers(ComposerClientWriter* writer) {
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800662 std::unordered_map<int64_t, DisplayResource> physicalDisplays;
663 while (!mDisplayResources.empty()) {
664 const auto& it = mDisplayResources.begin();
665 const auto& [display, resource] = *it;
ramindaniedf3ef92022-01-07 00:04:23 +0000666
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800667 while (!resource.layers.empty()) {
668 auto layer = *resource.layers.begin();
Ady Abrahama00d2462023-12-26 14:21:20 -0800669 const auto status = destroyLayer(display, layer, writer);
ramindaniedf3ef92022-01-07 00:04:23 +0000670 if (!status.isOk()) {
671 ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
672 layer, status.getDescription().c_str());
673 return false;
674 }
675 }
676
677 if (resource.isVirtual) {
678 const auto status = destroyVirtualDisplay(display);
679 if (!status.isOk()) {
680 ALOGE("Unable to destroy the display %" PRId64 " failed with error %s", display,
681 status.getDescription().c_str());
682 return false;
683 }
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800684 } else {
685 auto extractIter = mDisplayResources.extract(it);
686 physicalDisplays.insert(std::move(extractIter));
ramindaniedf3ef92022-01-07 00:04:23 +0000687 }
688 }
JihCheng Chiud0dbe4e2022-06-11 01:53:11 +0800689 mDisplayResources.swap(physicalDisplays);
ramindaniedf3ef92022-01-07 00:04:23 +0000690 mDisplayResources.clear();
691 return true;
692}
Brian Lindahl9f9d2f02024-10-24 16:23:57 -0600693
694std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxLayerPictureProfiles(int64_t display) {
695 int32_t outMaxProfiles = 0;
696 return {mComposerClient->getMaxLayerPictureProfiles(display, &outMaxProfiles), outMaxProfiles};
697}
698
Sally Qidee4de92024-11-27 11:35:36 -0800699std::pair<ScopedAStatus, std::vector<Luts>> VtsComposerClient::getLuts(
700 int64_t display, const std::vector<Buffer>& buffers) {
701 std::vector<Luts> outLuts;
702 return {mComposerClient->getLuts(display, buffers, &outLuts), std::move(outLuts)};
703}
704
Leon Scroggins IIIde057582022-01-13 12:26:00 -0500705} // namespace aidl::android::hardware::graphics::composer3::vts