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