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