1 /*
2 * Copyright 2015 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 // #define LOG_NDEBUG 0
22
23 #undef LOG_TAG
24 #define LOG_TAG "HWC2"
25 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
26
27 #include "HWC2.h"
28
29 #include <android/configuration.h>
30 #include <ui/Fence.h>
31 #include <ui/FloatRect.h>
32 #include <ui/GraphicBuffer.h>
33
34 #include <algorithm>
35 #include <cinttypes>
36 #include <iterator>
37 #include <set>
38
39 using aidl::android::hardware::graphics::composer3::Color;
40 using aidl::android::hardware::graphics::composer3::Composition;
41 using AidlCapability = aidl::android::hardware::graphics::composer3::Capability;
42 using aidl::android::hardware::graphics::composer3::DisplayCapability;
43 using aidl::android::hardware::graphics::composer3::OverlayProperties;
44
45 namespace android {
46
47 using android::Fence;
48 using android::FloatRect;
49 using android::GraphicBuffer;
50 using android::HdrCapabilities;
51 using android::HdrMetadata;
52 using android::Rect;
53 using android::Region;
54 using android::sp;
55
56 namespace HWC2 {
57
58 using namespace android::hardware::graphics::composer::hal;
59
60 namespace Hwc2 = android::Hwc2;
61
62 namespace {
63
hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey> & keys,const Hwc2::PerFrameMetadataKey & key)64 inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys,
65 const Hwc2::PerFrameMetadataKey& key) {
66 return keys.find(key) != keys.end();
67 }
68
69 } // namespace anonymous
70
71 // Display methods
72 Display::~Display() = default;
73
74 namespace impl {
75
Display(android::Hwc2::Composer & composer,const std::unordered_set<AidlCapability> & capabilities,HWDisplayId id,DisplayType type)76 Display::Display(android::Hwc2::Composer& composer,
77 const std::unordered_set<AidlCapability>& capabilities, HWDisplayId id,
78 DisplayType type)
79 : mComposer(composer), mCapabilities(capabilities), mId(id), mType(type) {
80 ALOGV("Created display %" PRIu64, id);
81 }
82
~Display()83 Display::~Display() {
84 // Note: The calls to onOwningDisplayDestroyed() are allowed (and expected)
85 // to call Display::onLayerDestroyed(). As that call removes entries from
86 // mLayers, we do not want to have a for loop directly over it here. Since
87 // the end goal is an empty mLayers anyway, we just go ahead and swap an
88 // initially empty local container with mLayers, and then enumerate
89 // the contents of the local container.
90 Layers destroyingLayers;
91 std::swap(mLayers, destroyingLayers);
92 for (const auto& [_, weakLayer] : destroyingLayers) {
93 if (std::shared_ptr layer = weakLayer.lock()) {
94 layer->onOwningDisplayDestroyed();
95 }
96 }
97
98 Error error = Error::NONE;
99 const char* msg;
100 switch (mType) {
101 case DisplayType::PHYSICAL:
102 error = setVsyncEnabled(HWC2::Vsync::DISABLE);
103 msg = "disable VSYNC for";
104 break;
105
106 case DisplayType::VIRTUAL:
107 error = static_cast<Error>(mComposer.destroyVirtualDisplay(mId));
108 msg = "destroy virtual";
109 break;
110
111 case DisplayType::INVALID: // Used in unit tests.
112 break;
113 }
114
115 ALOGE_IF(error != Error::NONE, "%s: Failed to %s display %" PRIu64 ": %d", __FUNCTION__, msg,
116 mId, static_cast<int32_t>(error));
117
118 ALOGV("Destroyed display %" PRIu64, mId);
119 }
120
121 // Required by HWC2 display
acceptChanges()122 Error Display::acceptChanges()
123 {
124 auto intError = mComposer.acceptDisplayChanges(mId);
125 return static_cast<Error>(intError);
126 }
127
createLayer()128 base::expected<std::shared_ptr<HWC2::Layer>, hal::Error> Display::createLayer() {
129 HWLayerId layerId = 0;
130 auto intError = mComposer.createLayer(mId, &layerId);
131 auto error = static_cast<Error>(intError);
132 if (error != Error::NONE) {
133 return base::unexpected(error);
134 }
135
136 auto layer = std::make_shared<impl::Layer>(mComposer, mCapabilities, *this, layerId);
137 mLayers.emplace(layerId, layer);
138 return layer;
139 }
140
onLayerDestroyed(hal::HWLayerId layerId)141 void Display::onLayerDestroyed(hal::HWLayerId layerId) {
142 mLayers.erase(layerId);
143 }
144
isVsyncPeriodSwitchSupported() const145 bool Display::isVsyncPeriodSwitchSupported() const {
146 ALOGV("[%" PRIu64 "] isVsyncPeriodSwitchSupported()", mId);
147
148 return mComposer.isSupported(android::Hwc2::Composer::OptionalFeature::RefreshRateSwitching);
149 }
150
hasDisplayIdleTimerCapability() const151 bool Display::hasDisplayIdleTimerCapability() const {
152 bool isCapabilitySupported = false;
153 return mComposer.hasDisplayIdleTimerCapability(mId, &isCapabilitySupported) == Error::NONE &&
154 isCapabilitySupported;
155 }
156
getPhysicalDisplayOrientation(Hwc2::AidlTransform * outTransform) const157 Error Display::getPhysicalDisplayOrientation(Hwc2::AidlTransform* outTransform) const {
158 auto error = mComposer.getPhysicalDisplayOrientation(mId, outTransform);
159 return static_cast<Error>(error);
160 }
161
getChangedCompositionTypes(std::unordered_map<HWC2::Layer *,Composition> * outTypes)162 Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) {
163 std::vector<Hwc2::Layer> layerIds;
164 std::vector<Composition> types;
165 auto intError = mComposer.getChangedCompositionTypes(
166 mId, &layerIds, &types);
167 uint32_t numElements = layerIds.size();
168 auto error = static_cast<Error>(intError);
169 error = static_cast<Error>(intError);
170 if (error != Error::NONE) {
171 return error;
172 }
173
174 outTypes->clear();
175 outTypes->reserve(numElements);
176 for (uint32_t element = 0; element < numElements; ++element) {
177 auto layer = getLayerById(layerIds[element]);
178 if (layer) {
179 auto type = types[element];
180 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
181 layer->getId(), to_string(type).c_str());
182 outTypes->emplace(layer.get(), type);
183 } else {
184 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
185 " on display %" PRIu64, layerIds[element], mId);
186 }
187 }
188
189 return Error::NONE;
190 }
191
getColorModes(std::vector<ColorMode> * outModes) const192 Error Display::getColorModes(std::vector<ColorMode>* outModes) const
193 {
194 auto intError = mComposer.getColorModes(mId, outModes);
195 return static_cast<Error>(intError);
196 }
197
getSupportedPerFrameMetadata() const198 int32_t Display::getSupportedPerFrameMetadata() const
199 {
200 int32_t supportedPerFrameMetadata = 0;
201
202 std::vector<Hwc2::PerFrameMetadataKey> tmpKeys = mComposer.getPerFrameMetadataKeys(mId);
203 std::set<Hwc2::PerFrameMetadataKey> keys(tmpKeys.begin(), tmpKeys.end());
204
205 // Check whether a specific metadata type is supported. A metadata type is considered
206 // supported if and only if all required fields are supported.
207
208 // SMPTE2086
209 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X) &&
210 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y) &&
211 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X) &&
212 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y) &&
213 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X) &&
214 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y) &&
215 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_X) &&
216 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_Y) &&
217 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_LUMINANCE) &&
218 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MIN_LUMINANCE)) {
219 supportedPerFrameMetadata |= HdrMetadata::Type::SMPTE2086;
220 }
221 // CTA861_3
222 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL) &&
223 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL)) {
224 supportedPerFrameMetadata |= HdrMetadata::Type::CTA861_3;
225 }
226
227 // HDR10PLUS
228 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI)) {
229 supportedPerFrameMetadata |= HdrMetadata::Type::HDR10PLUS;
230 }
231
232 return supportedPerFrameMetadata;
233 }
234
getRenderIntents(ColorMode colorMode,std::vector<RenderIntent> * outRenderIntents) const235 Error Display::getRenderIntents(ColorMode colorMode,
236 std::vector<RenderIntent>* outRenderIntents) const
237 {
238 auto intError = mComposer.getRenderIntents(mId, colorMode, outRenderIntents);
239 return static_cast<Error>(intError);
240 }
241
getDataspaceSaturationMatrix(Dataspace dataspace,android::mat4 * outMatrix)242 Error Display::getDataspaceSaturationMatrix(Dataspace dataspace, android::mat4* outMatrix)
243 {
244 auto intError = mComposer.getDataspaceSaturationMatrix(dataspace, outMatrix);
245 return static_cast<Error>(intError);
246 }
247
getName(std::string * outName) const248 Error Display::getName(std::string* outName) const
249 {
250 auto intError = mComposer.getDisplayName(mId, outName);
251 return static_cast<Error>(intError);
252 }
253
getRequests(HWC2::DisplayRequest * outDisplayRequests,std::unordered_map<HWC2::Layer *,LayerRequest> * outLayerRequests)254 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
255 std::unordered_map<HWC2::Layer*, LayerRequest>* outLayerRequests) {
256 uint32_t intDisplayRequests = 0;
257 std::vector<Hwc2::Layer> layerIds;
258 std::vector<uint32_t> layerRequests;
259 auto intError = mComposer.getDisplayRequests(
260 mId, &intDisplayRequests, &layerIds, &layerRequests);
261 uint32_t numElements = layerIds.size();
262 auto error = static_cast<Error>(intError);
263 if (error != Error::NONE) {
264 return error;
265 }
266
267 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
268 outLayerRequests->clear();
269 outLayerRequests->reserve(numElements);
270 for (uint32_t element = 0; element < numElements; ++element) {
271 auto layer = getLayerById(layerIds[element]);
272 if (layer) {
273 auto layerRequest =
274 static_cast<LayerRequest>(layerRequests[element]);
275 outLayerRequests->emplace(layer.get(), layerRequest);
276 } else {
277 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
278 PRIu64, layerIds[element], mId);
279 }
280 }
281
282 return Error::NONE;
283 }
284
getConnectionType(ui::DisplayConnectionType * outType) const285 Error Display::getConnectionType(ui::DisplayConnectionType* outType) const {
286 if (mType != DisplayType::PHYSICAL) return Error::BAD_DISPLAY;
287
288 using ConnectionType = Hwc2::IComposerClient::DisplayConnectionType;
289 ConnectionType connectionType;
290 const auto error = static_cast<Error>(mComposer.getDisplayConnectionType(mId, &connectionType));
291 if (error != Error::NONE) {
292 return error;
293 }
294
295 *outType = connectionType == ConnectionType::INTERNAL ? ui::DisplayConnectionType::Internal
296 : ui::DisplayConnectionType::External;
297 return Error::NONE;
298 }
299
hasCapability(DisplayCapability capability) const300 bool Display::hasCapability(DisplayCapability capability) const {
301 std::scoped_lock lock(mDisplayCapabilitiesMutex);
302 if (mDisplayCapabilities) {
303 return mDisplayCapabilities->count(capability) > 0;
304 }
305
306 ALOGW("Can't query capability %s."
307 " Display Capabilities were not queried from HWC yet",
308 to_string(capability).c_str());
309
310 return false;
311 }
312
supportsDoze(bool * outSupport) const313 Error Display::supportsDoze(bool* outSupport) const {
314 *outSupport = hasCapability(DisplayCapability::DOZE);
315 return Error::NONE;
316 }
317
getHdrCapabilities(HdrCapabilities * outCapabilities) const318 Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) const
319 {
320 float maxLuminance = -1.0f;
321 float maxAverageLuminance = -1.0f;
322 float minLuminance = -1.0f;
323 std::vector<Hwc2::Hdr> hdrTypes;
324 auto intError = mComposer.getHdrCapabilities(mId, &hdrTypes, &maxLuminance,
325 &maxAverageLuminance, &minLuminance);
326 auto error = static_cast<HWC2::Error>(intError);
327
328 if (error != Error::NONE) {
329 return error;
330 }
331
332 *outCapabilities =
333 HdrCapabilities(std::move(hdrTypes), maxLuminance, maxAverageLuminance, minLuminance);
334 return Error::NONE;
335 }
336
getOverlaySupport(OverlayProperties * outProperties) const337 Error Display::getOverlaySupport(OverlayProperties* outProperties) const {
338 auto intError = mComposer.getOverlaySupport(outProperties);
339 return static_cast<Error>(intError);
340 }
341
getDisplayedContentSamplingAttributes(hal::PixelFormat * outFormat,Dataspace * outDataspace,uint8_t * outComponentMask) const342 Error Display::getDisplayedContentSamplingAttributes(hal::PixelFormat* outFormat,
343 Dataspace* outDataspace,
344 uint8_t* outComponentMask) const {
345 auto intError = mComposer.getDisplayedContentSamplingAttributes(mId, outFormat, outDataspace,
346 outComponentMask);
347 return static_cast<Error>(intError);
348 }
349
setDisplayContentSamplingEnabled(bool enabled,uint8_t componentMask,uint64_t maxFrames) const350 Error Display::setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask,
351 uint64_t maxFrames) const {
352 auto intError =
353 mComposer.setDisplayContentSamplingEnabled(mId, enabled, componentMask, maxFrames);
354 return static_cast<Error>(intError);
355 }
356
getDisplayedContentSample(uint64_t maxFrames,uint64_t timestamp,android::DisplayedFrameStats * outStats) const357 Error Display::getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp,
358 android::DisplayedFrameStats* outStats) const {
359 auto intError = mComposer.getDisplayedContentSample(mId, maxFrames, timestamp, outStats);
360 return static_cast<Error>(intError);
361 }
362
getReleaseFences(std::unordered_map<HWC2::Layer *,sp<Fence>> * outFences) const363 Error Display::getReleaseFences(std::unordered_map<HWC2::Layer*, sp<Fence>>* outFences) const {
364 std::vector<Hwc2::Layer> layerIds;
365 std::vector<int> fenceFds;
366 auto intError = mComposer.getReleaseFences(mId, &layerIds, &fenceFds);
367 auto error = static_cast<Error>(intError);
368 uint32_t numElements = layerIds.size();
369 if (error != Error::NONE) {
370 return error;
371 }
372
373 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
374 releaseFences.reserve(numElements);
375 for (uint32_t element = 0; element < numElements; ++element) {
376 auto layer = getLayerById(layerIds[element]);
377 if (layer) {
378 sp<Fence> fence(sp<Fence>::make(fenceFds[element]));
379 releaseFences.emplace(layer.get(), fence);
380 } else {
381 ALOGE("getReleaseFences: invalid layer %" PRIu64
382 " found on display %" PRIu64, layerIds[element], mId);
383 for (; element < numElements; ++element) {
384 close(fenceFds[element]);
385 }
386 return Error::BAD_LAYER;
387 }
388 }
389
390 *outFences = std::move(releaseFences);
391 return Error::NONE;
392 }
393
present(sp<Fence> * outPresentFence)394 Error Display::present(sp<Fence>* outPresentFence)
395 {
396 int32_t presentFenceFd = -1;
397 auto intError = mComposer.presentDisplay(mId, &presentFenceFd);
398 auto error = static_cast<Error>(intError);
399 if (error != Error::NONE) {
400 return error;
401 }
402
403 *outPresentFence = sp<Fence>::make(presentFenceFd);
404 return Error::NONE;
405 }
406
setActiveConfigWithConstraints(hal::HWConfigId configId,const VsyncPeriodChangeConstraints & constraints,VsyncPeriodChangeTimeline * outTimeline)407 Error Display::setActiveConfigWithConstraints(hal::HWConfigId configId,
408 const VsyncPeriodChangeConstraints& constraints,
409 VsyncPeriodChangeTimeline* outTimeline) {
410 ALOGV("[%" PRIu64 "] setActiveConfigWithConstraints", mId);
411
412 if (isVsyncPeriodSwitchSupported()) {
413 Hwc2::IComposerClient::VsyncPeriodChangeConstraints hwc2Constraints;
414 hwc2Constraints.desiredTimeNanos = constraints.desiredTimeNanos;
415 hwc2Constraints.seamlessRequired = constraints.seamlessRequired;
416
417 Hwc2::VsyncPeriodChangeTimeline vsyncPeriodChangeTimeline = {};
418 auto intError = mComposer.setActiveConfigWithConstraints(mId, configId, hwc2Constraints,
419 &vsyncPeriodChangeTimeline);
420 outTimeline->newVsyncAppliedTimeNanos = vsyncPeriodChangeTimeline.newVsyncAppliedTimeNanos;
421 outTimeline->refreshRequired = vsyncPeriodChangeTimeline.refreshRequired;
422 outTimeline->refreshTimeNanos = vsyncPeriodChangeTimeline.refreshTimeNanos;
423 return static_cast<Error>(intError);
424 }
425
426 // Use legacy setActiveConfig instead
427 ALOGV("fallback to legacy setActiveConfig");
428 const auto now = systemTime();
429 if (constraints.desiredTimeNanos > now || constraints.seamlessRequired) {
430 ALOGE("setActiveConfigWithConstraints received constraints that can't be satisfied");
431 }
432
433 auto intError_2_4 = mComposer.setActiveConfig(mId, configId);
434 outTimeline->newVsyncAppliedTimeNanos = std::max(now, constraints.desiredTimeNanos);
435 outTimeline->refreshRequired = true;
436 outTimeline->refreshTimeNanos = now;
437 return static_cast<Error>(intError_2_4);
438 }
439
setClientTarget(uint32_t slot,const sp<GraphicBuffer> & target,const sp<Fence> & acquireFence,Dataspace dataspace)440 Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target,
441 const sp<Fence>& acquireFence, Dataspace dataspace)
442 {
443 // TODO: Properly encode client target surface damage
444 int32_t fenceFd = acquireFence->dup();
445 auto intError = mComposer.setClientTarget(mId, slot, target,
446 fenceFd, dataspace, std::vector<Hwc2::IComposerClient::Rect>());
447 return static_cast<Error>(intError);
448 }
449
setColorMode(ColorMode mode,RenderIntent renderIntent)450 Error Display::setColorMode(ColorMode mode, RenderIntent renderIntent)
451 {
452 auto intError = mComposer.setColorMode(mId, mode, renderIntent);
453 return static_cast<Error>(intError);
454 }
455
setColorTransform(const android::mat4 & matrix)456 Error Display::setColorTransform(const android::mat4& matrix) {
457 auto intError = mComposer.setColorTransform(mId, matrix.asArray());
458 return static_cast<Error>(intError);
459 }
460
setOutputBuffer(const sp<GraphicBuffer> & buffer,const sp<Fence> & releaseFence)461 Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
462 const sp<Fence>& releaseFence)
463 {
464 int32_t fenceFd = releaseFence->dup();
465 auto handle = buffer->getNativeBuffer()->handle;
466 auto intError = mComposer.setOutputBuffer(mId, handle, fenceFd);
467 close(fenceFd);
468 return static_cast<Error>(intError);
469 }
470
setPowerMode(PowerMode mode)471 Error Display::setPowerMode(PowerMode mode)
472 {
473 auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
474 auto intError = mComposer.setPowerMode(mId, intMode);
475
476 if (mode == PowerMode::ON) {
477 std::call_once(mDisplayCapabilityQueryFlag, [this]() {
478 std::vector<DisplayCapability> tmpCapabilities;
479 auto error =
480 static_cast<Error>(mComposer.getDisplayCapabilities(mId, &tmpCapabilities));
481 if (error == Error::NONE) {
482 std::scoped_lock lock(mDisplayCapabilitiesMutex);
483 mDisplayCapabilities.emplace();
484 for (auto capability : tmpCapabilities) {
485 mDisplayCapabilities->emplace(capability);
486 }
487 } else if (error == Error::UNSUPPORTED) {
488 std::scoped_lock lock(mDisplayCapabilitiesMutex);
489 mDisplayCapabilities.emplace();
490 if (mCapabilities.count(AidlCapability::SKIP_CLIENT_COLOR_TRANSFORM)) {
491 mDisplayCapabilities->emplace(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
492 }
493 bool dozeSupport = false;
494 error = static_cast<Error>(mComposer.getDozeSupport(mId, &dozeSupport));
495 if (error == Error::NONE && dozeSupport) {
496 mDisplayCapabilities->emplace(DisplayCapability::DOZE);
497 }
498 }
499 });
500 }
501
502 return static_cast<Error>(intError);
503 }
504
setVsyncEnabled(Vsync enabled)505 Error Display::setVsyncEnabled(Vsync enabled)
506 {
507 auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
508 auto intError = mComposer.setVsyncEnabled(mId, intEnabled);
509 return static_cast<Error>(intError);
510 }
511
validate(nsecs_t expectedPresentTime,uint32_t * outNumTypes,uint32_t * outNumRequests)512 Error Display::validate(nsecs_t expectedPresentTime, uint32_t* outNumTypes,
513 uint32_t* outNumRequests) {
514 uint32_t numTypes = 0;
515 uint32_t numRequests = 0;
516 auto intError = mComposer.validateDisplay(mId, expectedPresentTime, &numTypes, &numRequests);
517 auto error = static_cast<Error>(intError);
518 if (error != Error::NONE && !hasChangesError(error)) {
519 return error;
520 }
521
522 *outNumTypes = numTypes;
523 *outNumRequests = numRequests;
524 return error;
525 }
526
presentOrValidate(nsecs_t expectedPresentTime,uint32_t * outNumTypes,uint32_t * outNumRequests,sp<android::Fence> * outPresentFence,uint32_t * state)527 Error Display::presentOrValidate(nsecs_t expectedPresentTime, uint32_t* outNumTypes,
528 uint32_t* outNumRequests, sp<android::Fence>* outPresentFence,
529 uint32_t* state) {
530 uint32_t numTypes = 0;
531 uint32_t numRequests = 0;
532 int32_t presentFenceFd = -1;
533 auto intError = mComposer.presentOrValidateDisplay(mId, expectedPresentTime, &numTypes,
534 &numRequests, &presentFenceFd, state);
535 auto error = static_cast<Error>(intError);
536 if (error != Error::NONE && !hasChangesError(error)) {
537 return error;
538 }
539
540 if (*state == 1) {
541 *outPresentFence = sp<Fence>::make(presentFenceFd);
542 }
543
544 if (*state == 0) {
545 *outNumTypes = numTypes;
546 *outNumRequests = numRequests;
547 }
548 return error;
549 }
550
setDisplayBrightness(float brightness,float brightnessNits,const Hwc2::Composer::DisplayBrightnessOptions & options)551 ftl::Future<Error> Display::setDisplayBrightness(
552 float brightness, float brightnessNits,
553 const Hwc2::Composer::DisplayBrightnessOptions& options) {
554 return ftl::defer([composer = &mComposer, id = mId, brightness, brightnessNits, options] {
555 const auto intError =
556 composer->setDisplayBrightness(id, brightness, brightnessNits, options);
557 return static_cast<Error>(intError);
558 });
559 }
560
setBootDisplayConfig(hal::HWConfigId configId)561 Error Display::setBootDisplayConfig(hal::HWConfigId configId) {
562 auto intError = mComposer.setBootDisplayConfig(mId, configId);
563 return static_cast<Error>(intError);
564 }
565
clearBootDisplayConfig()566 Error Display::clearBootDisplayConfig() {
567 auto intError = mComposer.clearBootDisplayConfig(mId);
568 return static_cast<Error>(intError);
569 }
570
getPreferredBootDisplayConfig(hal::HWConfigId * configId) const571 Error Display::getPreferredBootDisplayConfig(hal::HWConfigId* configId) const {
572 auto intError = mComposer.getPreferredBootDisplayConfig(mId, configId);
573 return static_cast<Error>(intError);
574 }
575
setAutoLowLatencyMode(bool on)576 Error Display::setAutoLowLatencyMode(bool on) {
577 auto intError = mComposer.setAutoLowLatencyMode(mId, on);
578 return static_cast<Error>(intError);
579 }
580
getSupportedContentTypes(std::vector<ContentType> * outSupportedContentTypes) const581 Error Display::getSupportedContentTypes(std::vector<ContentType>* outSupportedContentTypes) const {
582 std::vector<Hwc2::IComposerClient::ContentType> tmpSupportedContentTypes;
583 auto intError = mComposer.getSupportedContentTypes(mId, &tmpSupportedContentTypes);
584 for (Hwc2::IComposerClient::ContentType contentType : tmpSupportedContentTypes) {
585 outSupportedContentTypes->push_back(static_cast<ContentType>(contentType));
586 }
587 return static_cast<Error>(intError);
588 }
589
setContentType(ContentType contentType)590 Error Display::setContentType(ContentType contentType) {
591 auto intError = mComposer.setContentType(mId, contentType);
592 return static_cast<Error>(intError);
593 }
594
getClientTargetProperty(aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness * outClientTargetProperty)595 Error Display::getClientTargetProperty(
596 aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness*
597 outClientTargetProperty) {
598 const auto error = mComposer.getClientTargetProperty(mId, outClientTargetProperty);
599 return static_cast<Error>(error);
600 }
601
getDisplayDecorationSupport(std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport> * support)602 Error Display::getDisplayDecorationSupport(
603 std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
604 support) {
605 const auto error = mComposer.getDisplayDecorationSupport(mId, support);
606 return static_cast<Error>(error);
607 }
608
setIdleTimerEnabled(std::chrono::milliseconds timeout)609 Error Display::setIdleTimerEnabled(std::chrono::milliseconds timeout) {
610 const auto error = mComposer.setIdleTimerEnabled(mId, timeout);
611 return static_cast<Error>(error);
612 }
613
614 // For use by Device
615
setConnected(bool connected)616 void Display::setConnected(bool connected) {
617 if (!mIsConnected && connected) {
618 mComposer.setClientTargetSlotCount(mId);
619 }
620 mIsConnected = connected;
621 }
622
623 // Other Display methods
624
getLayerById(HWLayerId id) const625 std::shared_ptr<HWC2::Layer> Display::getLayerById(HWLayerId id) const {
626 auto it = mLayers.find(id);
627 return it != mLayers.end() ? it->second.lock() : nullptr;
628 }
629 } // namespace impl
630
631 // Layer methods
632
633 namespace {
convertRegionToHwcRects(const Region & region)634 std::vector<Hwc2::IComposerClient::Rect> convertRegionToHwcRects(const Region& region) {
635 size_t rectCount = 0;
636 Rect const* rectArray = region.getArray(&rectCount);
637
638 std::vector<Hwc2::IComposerClient::Rect> hwcRects;
639 hwcRects.reserve(rectCount);
640 for (size_t rect = 0; rect < rectCount; ++rect) {
641 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, rectArray[rect].right,
642 rectArray[rect].bottom});
643 }
644 return hwcRects;
645 }
646 } // namespace
647
648 Layer::~Layer() = default;
649
650 namespace impl {
651
Layer(android::Hwc2::Composer & composer,const std::unordered_set<AidlCapability> & capabilities,HWC2::Display & display,HWLayerId layerId)652 Layer::Layer(android::Hwc2::Composer& composer,
653 const std::unordered_set<AidlCapability>& capabilities, HWC2::Display& display,
654 HWLayerId layerId)
655 : mComposer(composer),
656 mCapabilities(capabilities),
657 mDisplay(&display),
658 mId(layerId),
659 mColorMatrix(android::mat4()) {
660 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, display.getId());
661 }
662
~Layer()663 Layer::~Layer()
664 {
665 onOwningDisplayDestroyed();
666 }
667
onOwningDisplayDestroyed()668 void Layer::onOwningDisplayDestroyed() {
669 // Note: onOwningDisplayDestroyed() may be called to perform cleanup by
670 // either the Layer dtor or by the Display dtor and must be safe to call
671 // from either path. In particular, the call to Display::onLayerDestroyed()
672 // is expected to be safe to do,
673
674 if (CC_UNLIKELY(!mDisplay)) {
675 return;
676 }
677
678 mDisplay->onLayerDestroyed(mId);
679
680 // Note: If the HWC display was actually disconnected, these calls are will
681 // return an error. We always make them as there may be other reasons for
682 // the HWC2::Display to be destroyed.
683 auto intError = mComposer.destroyLayer(mDisplay->getId(), mId);
684 auto error = static_cast<Error>(intError);
685 ALOGE_IF(error != Error::NONE,
686 "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
687 " failed: %s (%d)",
688 mDisplay->getId(), mId, to_string(error).c_str(), intError);
689
690 mDisplay = nullptr;
691 }
692
setCursorPosition(int32_t x,int32_t y)693 Error Layer::setCursorPosition(int32_t x, int32_t y)
694 {
695 if (CC_UNLIKELY(!mDisplay)) {
696 return Error::BAD_DISPLAY;
697 }
698
699 auto intError = mComposer.setCursorPosition(mDisplay->getId(), mId, x, y);
700 return static_cast<Error>(intError);
701 }
702
setBuffer(uint32_t slot,const sp<GraphicBuffer> & buffer,const sp<Fence> & acquireFence)703 Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
704 const sp<Fence>& acquireFence)
705 {
706 if (CC_UNLIKELY(!mDisplay)) {
707 return Error::BAD_DISPLAY;
708 }
709
710 if (buffer == nullptr && mBufferSlot == slot) {
711 return Error::NONE;
712 }
713 mBufferSlot = slot;
714
715 int32_t fenceFd = acquireFence->dup();
716 auto intError = mComposer.setLayerBuffer(mDisplay->getId(), mId, slot, buffer, fenceFd);
717 return static_cast<Error>(intError);
718 }
719
setBufferSlotsToClear(const std::vector<uint32_t> & slotsToClear,uint32_t activeBufferSlot)720 Error Layer::setBufferSlotsToClear(const std::vector<uint32_t>& slotsToClear,
721 uint32_t activeBufferSlot) {
722 if (CC_UNLIKELY(!mDisplay)) {
723 return Error::BAD_DISPLAY;
724 }
725 auto intError = mComposer.setLayerBufferSlotsToClear(mDisplay->getId(), mId, slotsToClear,
726 activeBufferSlot);
727 return static_cast<Error>(intError);
728 }
729
setSurfaceDamage(const Region & damage)730 Error Layer::setSurfaceDamage(const Region& damage)
731 {
732 if (CC_UNLIKELY(!mDisplay)) {
733 return Error::BAD_DISPLAY;
734 }
735
736 if (damage.isRect() && mDamageRegion.isRect() &&
737 (damage.getBounds() == mDamageRegion.getBounds())) {
738 return Error::NONE;
739 }
740 mDamageRegion = damage;
741
742 // We encode default full-screen damage as INVALID_RECT upstream, but as 0
743 // rects for HWC
744 Hwc2::Error intError = Hwc2::Error::NONE;
745 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
746 intError = mComposer.setLayerSurfaceDamage(mDisplay->getId(), mId,
747 std::vector<Hwc2::IComposerClient::Rect>());
748 } else {
749 const auto hwcRects = convertRegionToHwcRects(damage);
750 intError = mComposer.setLayerSurfaceDamage(mDisplay->getId(), mId, hwcRects);
751 }
752
753 return static_cast<Error>(intError);
754 }
755
setBlendMode(BlendMode mode)756 Error Layer::setBlendMode(BlendMode mode)
757 {
758 if (CC_UNLIKELY(!mDisplay)) {
759 return Error::BAD_DISPLAY;
760 }
761
762 auto intError = mComposer.setLayerBlendMode(mDisplay->getId(), mId, mode);
763 return static_cast<Error>(intError);
764 }
765
setColor(Color color)766 Error Layer::setColor(Color color) {
767 if (CC_UNLIKELY(!mDisplay)) {
768 return Error::BAD_DISPLAY;
769 }
770
771 auto intError = mComposer.setLayerColor(mDisplay->getId(), mId, color);
772 return static_cast<Error>(intError);
773 }
774
setCompositionType(Composition type)775 Error Layer::setCompositionType(Composition type)
776 {
777 if (CC_UNLIKELY(!mDisplay)) {
778 return Error::BAD_DISPLAY;
779 }
780
781 auto intError = mComposer.setLayerCompositionType(mDisplay->getId(), mId, type);
782 return static_cast<Error>(intError);
783 }
784
setDataspace(Dataspace dataspace)785 Error Layer::setDataspace(Dataspace dataspace)
786 {
787 if (CC_UNLIKELY(!mDisplay)) {
788 return Error::BAD_DISPLAY;
789 }
790
791 if (dataspace == mDataSpace) {
792 return Error::NONE;
793 }
794 mDataSpace = dataspace;
795 auto intError = mComposer.setLayerDataspace(mDisplay->getId(), mId, mDataSpace);
796 return static_cast<Error>(intError);
797 }
798
setPerFrameMetadata(const int32_t supportedPerFrameMetadata,const android::HdrMetadata & metadata)799 Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
800 const android::HdrMetadata& metadata)
801 {
802 if (CC_UNLIKELY(!mDisplay)) {
803 return Error::BAD_DISPLAY;
804 }
805
806 if (metadata == mHdrMetadata) {
807 return Error::NONE;
808 }
809
810 mHdrMetadata = metadata;
811 int validTypes = mHdrMetadata.validTypes & supportedPerFrameMetadata;
812 std::vector<Hwc2::PerFrameMetadata> perFrameMetadatas;
813 if (validTypes & HdrMetadata::SMPTE2086) {
814 perFrameMetadatas.insert(perFrameMetadatas.end(),
815 {{Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
816 mHdrMetadata.smpte2086.displayPrimaryRed.x},
817 {Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
818 mHdrMetadata.smpte2086.displayPrimaryRed.y},
819 {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
820 mHdrMetadata.smpte2086.displayPrimaryGreen.x},
821 {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
822 mHdrMetadata.smpte2086.displayPrimaryGreen.y},
823 {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
824 mHdrMetadata.smpte2086.displayPrimaryBlue.x},
825 {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
826 mHdrMetadata.smpte2086.displayPrimaryBlue.y},
827 {Hwc2::PerFrameMetadataKey::WHITE_POINT_X,
828 mHdrMetadata.smpte2086.whitePoint.x},
829 {Hwc2::PerFrameMetadataKey::WHITE_POINT_Y,
830 mHdrMetadata.smpte2086.whitePoint.y},
831 {Hwc2::PerFrameMetadataKey::MAX_LUMINANCE,
832 mHdrMetadata.smpte2086.maxLuminance},
833 {Hwc2::PerFrameMetadataKey::MIN_LUMINANCE,
834 mHdrMetadata.smpte2086.minLuminance}});
835 }
836
837 if (validTypes & HdrMetadata::CTA861_3) {
838 perFrameMetadatas.insert(perFrameMetadatas.end(),
839 {{Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
840 mHdrMetadata.cta8613.maxContentLightLevel},
841 {Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
842 mHdrMetadata.cta8613.maxFrameAverageLightLevel}});
843 }
844
845 const Error error = static_cast<Error>(
846 mComposer.setLayerPerFrameMetadata(mDisplay->getId(), mId, perFrameMetadatas));
847 if (error != Error::NONE) {
848 return error;
849 }
850
851 std::vector<Hwc2::PerFrameMetadataBlob> perFrameMetadataBlobs;
852 if (validTypes & HdrMetadata::HDR10PLUS) {
853 if (CC_UNLIKELY(mHdrMetadata.hdr10plus.size() == 0)) {
854 return Error::BAD_PARAMETER;
855 }
856
857 perFrameMetadataBlobs.push_back(
858 {Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI, mHdrMetadata.hdr10plus});
859 }
860
861 return static_cast<Error>(
862 mComposer.setLayerPerFrameMetadataBlobs(mDisplay->getId(), mId, perFrameMetadataBlobs));
863 }
864
setDisplayFrame(const Rect & frame)865 Error Layer::setDisplayFrame(const Rect& frame)
866 {
867 if (CC_UNLIKELY(!mDisplay)) {
868 return Error::BAD_DISPLAY;
869 }
870
871 Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
872 frame.right, frame.bottom};
873 auto intError = mComposer.setLayerDisplayFrame(mDisplay->getId(), mId, hwcRect);
874 return static_cast<Error>(intError);
875 }
876
setPlaneAlpha(float alpha)877 Error Layer::setPlaneAlpha(float alpha)
878 {
879 if (CC_UNLIKELY(!mDisplay)) {
880 return Error::BAD_DISPLAY;
881 }
882
883 auto intError = mComposer.setLayerPlaneAlpha(mDisplay->getId(), mId, alpha);
884 return static_cast<Error>(intError);
885 }
886
setSidebandStream(const native_handle_t * stream)887 Error Layer::setSidebandStream(const native_handle_t* stream)
888 {
889 if (CC_UNLIKELY(!mDisplay)) {
890 return Error::BAD_DISPLAY;
891 }
892
893 if (mCapabilities.count(AidlCapability::SIDEBAND_STREAM) == 0) {
894 ALOGE("Attempted to call setSidebandStream without checking that the "
895 "device supports sideband streams");
896 return Error::UNSUPPORTED;
897 }
898 auto intError = mComposer.setLayerSidebandStream(mDisplay->getId(), mId, stream);
899 return static_cast<Error>(intError);
900 }
901
setSourceCrop(const FloatRect & crop)902 Error Layer::setSourceCrop(const FloatRect& crop)
903 {
904 if (CC_UNLIKELY(!mDisplay)) {
905 return Error::BAD_DISPLAY;
906 }
907
908 Hwc2::IComposerClient::FRect hwcRect{
909 crop.left, crop.top, crop.right, crop.bottom};
910 auto intError = mComposer.setLayerSourceCrop(mDisplay->getId(), mId, hwcRect);
911 return static_cast<Error>(intError);
912 }
913
setTransform(Transform transform)914 Error Layer::setTransform(Transform transform)
915 {
916 if (CC_UNLIKELY(!mDisplay)) {
917 return Error::BAD_DISPLAY;
918 }
919
920 auto intTransform = static_cast<Hwc2::Transform>(transform);
921 auto intError = mComposer.setLayerTransform(mDisplay->getId(), mId, intTransform);
922 return static_cast<Error>(intError);
923 }
924
setVisibleRegion(const Region & region)925 Error Layer::setVisibleRegion(const Region& region)
926 {
927 if (CC_UNLIKELY(!mDisplay)) {
928 return Error::BAD_DISPLAY;
929 }
930
931 if (region.isRect() && mVisibleRegion.isRect() &&
932 (region.getBounds() == mVisibleRegion.getBounds())) {
933 return Error::NONE;
934 }
935 mVisibleRegion = region;
936 const auto hwcRects = convertRegionToHwcRects(region);
937 auto intError = mComposer.setLayerVisibleRegion(mDisplay->getId(), mId, hwcRects);
938 return static_cast<Error>(intError);
939 }
940
setZOrder(uint32_t z)941 Error Layer::setZOrder(uint32_t z)
942 {
943 if (CC_UNLIKELY(!mDisplay)) {
944 return Error::BAD_DISPLAY;
945 }
946
947 auto intError = mComposer.setLayerZOrder(mDisplay->getId(), mId, z);
948 return static_cast<Error>(intError);
949 }
950
951 // Composer HAL 2.3
setColorTransform(const android::mat4 & matrix)952 Error Layer::setColorTransform(const android::mat4& matrix) {
953 if (CC_UNLIKELY(!mDisplay)) {
954 return Error::BAD_DISPLAY;
955 }
956
957 if (matrix == mColorMatrix) {
958 return Error::NONE;
959 }
960 auto intError = mComposer.setLayerColorTransform(mDisplay->getId(), mId, matrix.asArray());
961 Error error = static_cast<Error>(intError);
962 if (error != Error::NONE) {
963 return error;
964 }
965 mColorMatrix = matrix;
966 return error;
967 }
968
969 // Composer HAL 2.4
setLayerGenericMetadata(const std::string & name,bool mandatory,const std::vector<uint8_t> & value)970 Error Layer::setLayerGenericMetadata(const std::string& name, bool mandatory,
971 const std::vector<uint8_t>& value) {
972 if (CC_UNLIKELY(!mDisplay)) {
973 return Error::BAD_DISPLAY;
974 }
975
976 auto intError =
977 mComposer.setLayerGenericMetadata(mDisplay->getId(), mId, name, mandatory, value);
978 return static_cast<Error>(intError);
979 }
980
981 // AIDL HAL
setBrightness(float brightness)982 Error Layer::setBrightness(float brightness) {
983 if (CC_UNLIKELY(!mDisplay)) {
984 return Error::BAD_DISPLAY;
985 }
986
987 auto intError = mComposer.setLayerBrightness(mDisplay->getId(), mId, brightness);
988 return static_cast<Error>(intError);
989 }
990
setBlockingRegion(const Region & region)991 Error Layer::setBlockingRegion(const Region& region) {
992 if (CC_UNLIKELY(!mDisplay)) {
993 return Error::BAD_DISPLAY;
994 }
995
996 if (region.isRect() && mBlockingRegion.isRect() &&
997 (region.getBounds() == mBlockingRegion.getBounds())) {
998 return Error::NONE;
999 }
1000 mBlockingRegion = region;
1001 const auto hwcRects = convertRegionToHwcRects(region);
1002 const auto intError = mComposer.setLayerBlockingRegion(mDisplay->getId(), mId, hwcRects);
1003 return static_cast<Error>(intError);
1004 }
1005
1006 } // namespace impl
1007 } // namespace HWC2
1008 } // namespace android
1009
1010 // TODO(b/129481165): remove the #pragma below and fix conversion issues
1011 #pragma clang diagnostic pop // ignored "-Wconversion"
1012