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