blob: f1fa9389eb219ef66f4b8f9d5e8a225705c9e8c9 [file] [log] [blame]
Dan Stoza651bf312015-10-23 17:03:17 -07001/*
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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Dan Stoza651bf312015-10-23 17:03:17 -070021// #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
Dominik Laskowski4e2b71f2020-11-10 15:05:32 -080029#include <android/configuration.h>
Dominik Laskowski88096872023-12-08 15:26:04 -050030#include <common/FlagManager.h>
Dan Stoza651bf312015-10-23 17:03:17 -070031#include <ui/Fence.h>
Dan Stoza5a423ea2017-02-16 14:10:39 -080032#include <ui/FloatRect.h>
Dan Stoza651bf312015-10-23 17:03:17 -070033#include <ui/GraphicBuffer.h>
Dan Stoza651bf312015-10-23 17:03:17 -070034
Lloyd Pique3c085a02018-05-09 19:38:32 -070035#include <algorithm>
Dominik Laskowski4e2b71f2020-11-10 15:05:32 -080036#include <cinttypes>
Lloyd Pique3c085a02018-05-09 19:38:32 -070037#include <iterator>
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -070038#include <set>
Dan Stoza651bf312015-10-23 17:03:17 -070039
Ady Abraham6e60b142022-01-06 18:10:35 -080040using aidl::android::hardware::graphics::composer3::Color;
Leon Scroggins III2e1aa182021-12-01 17:33:12 -050041using aidl::android::hardware::graphics::composer3::Composition;
Ady Abrahamde549d42022-01-26 19:19:17 -080042using AidlCapability = aidl::android::hardware::graphics::composer3::Capability;
Leon Scroggins III5967aec2021-12-29 11:14:22 -050043using aidl::android::hardware::graphics::composer3::DisplayCapability;
Sally Qi11dcd582024-08-16 18:11:27 -070044using aidl::android::hardware::graphics::composer3::DisplayLuts;
Sally Qi492cec32024-06-28 14:34:47 -070045using aidl::android::hardware::graphics::composer3::Lut;
Sally Qi0cbd08b2022-08-17 12:12:28 -070046using aidl::android::hardware::graphics::composer3::OverlayProperties;
Leon Scroggins III2e1aa182021-12-01 17:33:12 -050047
Peiyong Line9d809e2020-04-14 13:10:48 -070048namespace android {
49
Dan Stoza651bf312015-10-23 17:03:17 -070050using android::Fence;
Dan Stoza5a423ea2017-02-16 14:10:39 -080051using android::FloatRect;
Dan Stoza651bf312015-10-23 17:03:17 -070052using android::GraphicBuffer;
Dan Stoza7d7ae732016-03-16 12:23:40 -070053using android::HdrCapabilities;
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -070054using android::HdrMetadata;
Dan Stoza651bf312015-10-23 17:03:17 -070055using android::Rect;
56using android::Region;
57using android::sp;
58
59namespace HWC2 {
60
Peiyong Line9d809e2020-04-14 13:10:48 -070061using namespace android::hardware::graphics::composer::hal;
62
Chia-I Wuaab99f52016-10-05 12:59:58 +080063namespace Hwc2 = android::Hwc2;
64
Steven Thomas94e35b92017-07-26 18:48:28 -070065namespace {
66
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -070067inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys,
68 const Hwc2::PerFrameMetadataKey& key) {
69 return keys.find(key) != keys.end();
70}
71
Steven Thomas94e35b92017-07-26 18:48:28 -070072} // namespace anonymous
73
Dan Stoza651bf312015-10-23 17:03:17 -070074// Display methods
Ana Krulec4593b692019-01-11 22:07:25 -080075Display::~Display() = default;
Dan Stoza651bf312015-10-23 17:03:17 -070076
Ana Krulec4593b692019-01-11 22:07:25 -080077namespace impl {
Dominik Laskowski55c85402020-01-21 16:25:47 -080078
Peiyong Lin74ca2f42019-01-14 19:36:57 -080079Display::Display(android::Hwc2::Composer& composer,
Ady Abrahamde549d42022-01-26 19:19:17 -080080 const std::unordered_set<AidlCapability>& capabilities, HWDisplayId id,
Lloyd Piquebc792092018-01-17 11:52:30 -080081 DisplayType type)
Peiyong Line9d809e2020-04-14 13:10:48 -070082 : mComposer(composer), mCapabilities(capabilities), mId(id), mType(type) {
Dan Stoza651bf312015-10-23 17:03:17 -070083 ALOGV("Created display %" PRIu64, id);
HyunKyounga264a352024-04-24 18:51:33 +090084 if (mType == hal::DisplayType::VIRTUAL) {
85 loadDisplayCapabilities();
86 }
Dan Stoza651bf312015-10-23 17:03:17 -070087}
88
Steven Thomas94e35b92017-07-26 18:48:28 -070089Display::~Display() {
Lloyd Piquea516c002021-05-07 14:36:58 -070090 // Note: The calls to onOwningDisplayDestroyed() are allowed (and expected)
91 // to call Display::onLayerDestroyed(). As that call removes entries from
92 // mLayers, we do not want to have a for loop directly over it here. Since
93 // the end goal is an empty mLayers anyway, we just go ahead and swap an
94 // initially empty local container with mLayers, and then enumerate
95 // the contents of the local container.
96 Layers destroyingLayers;
97 std::swap(mLayers, destroyingLayers);
98 for (const auto& [_, weakLayer] : destroyingLayers) {
99 if (std::shared_ptr layer = weakLayer.lock()) {
100 layer->onOwningDisplayDestroyed();
101 }
102 }
Steven Thomas94e35b92017-07-26 18:48:28 -0700103
Peiyong Line9d809e2020-04-14 13:10:48 -0700104 Error error = Error::NONE;
Dominik Laskowski55c85402020-01-21 16:25:47 -0800105 const char* msg;
106 switch (mType) {
Peiyong Line9d809e2020-04-14 13:10:48 -0700107 case DisplayType::PHYSICAL:
108 error = setVsyncEnabled(HWC2::Vsync::DISABLE);
Dominik Laskowski55c85402020-01-21 16:25:47 -0800109 msg = "disable VSYNC for";
110 break;
111
Peiyong Line9d809e2020-04-14 13:10:48 -0700112 case DisplayType::VIRTUAL:
Dominik Laskowski55c85402020-01-21 16:25:47 -0800113 error = static_cast<Error>(mComposer.destroyVirtualDisplay(mId));
114 msg = "destroy virtual";
115 break;
116
Peiyong Line9d809e2020-04-14 13:10:48 -0700117 case DisplayType::INVALID: // Used in unit tests.
Dominik Laskowski55c85402020-01-21 16:25:47 -0800118 break;
Dan Stoza651bf312015-10-23 17:03:17 -0700119 }
Dominik Laskowski55c85402020-01-21 16:25:47 -0800120
Peiyong Line9d809e2020-04-14 13:10:48 -0700121 ALOGE_IF(error != Error::NONE, "%s: Failed to %s display %" PRIu64 ": %d", __FUNCTION__, msg,
122 mId, static_cast<int32_t>(error));
Dominik Laskowski55c85402020-01-21 16:25:47 -0800123
124 ALOGV("Destroyed display %" PRIu64, mId);
Dan Stoza651bf312015-10-23 17:03:17 -0700125}
126
Dan Stoza651bf312015-10-23 17:03:17 -0700127// Required by HWC2 display
Dan Stoza651bf312015-10-23 17:03:17 -0700128Error Display::acceptChanges()
129{
Steven Thomas94e35b92017-07-26 18:48:28 -0700130 auto intError = mComposer.acceptDisplayChanges(mId);
Dan Stoza651bf312015-10-23 17:03:17 -0700131 return static_cast<Error>(intError);
132}
133
Lloyd Piquea516c002021-05-07 14:36:58 -0700134base::expected<std::shared_ptr<HWC2::Layer>, hal::Error> Display::createLayer() {
Peiyong Line9d809e2020-04-14 13:10:48 -0700135 HWLayerId layerId = 0;
Steven Thomas94e35b92017-07-26 18:48:28 -0700136 auto intError = mComposer.createLayer(mId, &layerId);
Dan Stoza651bf312015-10-23 17:03:17 -0700137 auto error = static_cast<Error>(intError);
Peiyong Line9d809e2020-04-14 13:10:48 -0700138 if (error != Error::NONE) {
Lloyd Piquea516c002021-05-07 14:36:58 -0700139 return base::unexpected(error);
Dan Stoza651bf312015-10-23 17:03:17 -0700140 }
141
Lloyd Piquea516c002021-05-07 14:36:58 -0700142 auto layer = std::make_shared<impl::Layer>(mComposer, mCapabilities, *this, layerId);
143 mLayers.emplace(layerId, layer);
144 return layer;
Steven Thomas94e35b92017-07-26 18:48:28 -0700145}
146
Lloyd Piquea516c002021-05-07 14:36:58 -0700147void Display::onLayerDestroyed(hal::HWLayerId layerId) {
148 mLayers.erase(layerId);
Dan Stoza651bf312015-10-23 17:03:17 -0700149}
150
Ady Abraham7159f572019-10-11 11:10:18 -0700151bool Display::isVsyncPeriodSwitchSupported() const {
152 ALOGV("[%" PRIu64 "] isVsyncPeriodSwitchSupported()", mId);
153
Ady Abraham4d211cf2021-12-14 16:19:03 -0800154 return mComposer.isSupported(android::Hwc2::Composer::OptionalFeature::RefreshRateSwitching);
Ady Abraham7159f572019-10-11 11:10:18 -0700155}
156
ramindani32cf0602022-03-02 02:30:29 +0000157bool Display::hasDisplayIdleTimerCapability() const {
158 bool isCapabilitySupported = false;
159 return mComposer.hasDisplayIdleTimerCapability(mId, &isCapabilitySupported) == Error::NONE &&
160 isCapabilitySupported;
161}
162
ramindani06e518e2022-03-14 18:47:53 +0000163Error Display::getPhysicalDisplayOrientation(Hwc2::AidlTransform* outTransform) const {
164 auto error = mComposer.getPhysicalDisplayOrientation(mId, outTransform);
165 return static_cast<Error>(error);
166}
167
Lloyd Pique35d58242018-12-18 16:33:25 -0800168Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800169 std::vector<Hwc2::Layer> layerIds;
Leon Scroggins III2e1aa182021-12-01 17:33:12 -0500170 std::vector<Composition> types;
Steven Thomas94e35b92017-07-26 18:48:28 -0700171 auto intError = mComposer.getChangedCompositionTypes(
172 mId, &layerIds, &types);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800173 uint32_t numElements = layerIds.size();
linkaid1bb3142023-12-20 10:18:16 +0800174 const auto error = static_cast<Error>(intError);
Peiyong Line9d809e2020-04-14 13:10:48 -0700175 if (error != Error::NONE) {
Dan Stoza651bf312015-10-23 17:03:17 -0700176 return error;
177 }
178
179 outTypes->clear();
180 outTypes->reserve(numElements);
181 for (uint32_t element = 0; element < numElements; ++element) {
182 auto layer = getLayerById(layerIds[element]);
183 if (layer) {
Peiyong Line9d809e2020-04-14 13:10:48 -0700184 auto type = types[element];
Dan Stoza651bf312015-10-23 17:03:17 -0700185 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
186 layer->getId(), to_string(type).c_str());
Lloyd Piquea516c002021-05-07 14:36:58 -0700187 outTypes->emplace(layer.get(), type);
Dan Stoza651bf312015-10-23 17:03:17 -0700188 } else {
189 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
190 " on display %" PRIu64, layerIds[element], mId);
191 }
192 }
193
Peiyong Line9d809e2020-04-14 13:10:48 -0700194 return Error::NONE;
Dan Stoza651bf312015-10-23 17:03:17 -0700195}
196
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700197Error Display::getColorModes(std::vector<ColorMode>* outModes) const
Dan Stoza076ac672016-03-14 10:47:53 -0700198{
Peiyong Linfd997e02018-03-28 15:29:00 -0700199 auto intError = mComposer.getColorModes(mId, outModes);
200 return static_cast<Error>(intError);
Dan Stoza076ac672016-03-14 10:47:53 -0700201}
202
Chia-I Wud7e01d72018-06-21 13:39:09 +0800203int32_t Display::getSupportedPerFrameMetadata() const
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700204{
Chia-I Wud7e01d72018-06-21 13:39:09 +0800205 int32_t supportedPerFrameMetadata = 0;
206
207 std::vector<Hwc2::PerFrameMetadataKey> tmpKeys = mComposer.getPerFrameMetadataKeys(mId);
208 std::set<Hwc2::PerFrameMetadataKey> keys(tmpKeys.begin(), tmpKeys.end());
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700209
210 // Check whether a specific metadata type is supported. A metadata type is considered
211 // supported if and only if all required fields are supported.
212
213 // SMPTE2086
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700214 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X) &&
215 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y) &&
216 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X) &&
217 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y) &&
218 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X) &&
219 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y) &&
220 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_X) &&
221 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_Y) &&
222 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_LUMINANCE) &&
223 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MIN_LUMINANCE)) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800224 supportedPerFrameMetadata |= HdrMetadata::Type::SMPTE2086;
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700225 }
226 // CTA861_3
227 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL) &&
228 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL)) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800229 supportedPerFrameMetadata |= HdrMetadata::Type::CTA861_3;
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700230 }
231
Valerie Haue9e843a2018-12-18 13:39:23 -0800232 // HDR10PLUS
233 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI)) {
234 supportedPerFrameMetadata |= HdrMetadata::Type::HDR10PLUS;
235 }
236
Chia-I Wud7e01d72018-06-21 13:39:09 +0800237 return supportedPerFrameMetadata;
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700238}
239
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700240Error Display::getRenderIntents(ColorMode colorMode,
241 std::vector<RenderIntent>* outRenderIntents) const
242{
243 auto intError = mComposer.getRenderIntents(mId, colorMode, outRenderIntents);
244 return static_cast<Error>(intError);
245}
246
247Error Display::getDataspaceSaturationMatrix(Dataspace dataspace, android::mat4* outMatrix)
248{
249 auto intError = mComposer.getDataspaceSaturationMatrix(dataspace, outMatrix);
250 return static_cast<Error>(intError);
251}
252
Dan Stoza651bf312015-10-23 17:03:17 -0700253Error Display::getName(std::string* outName) const
254{
Steven Thomas94e35b92017-07-26 18:48:28 -0700255 auto intError = mComposer.getDisplayName(mId, outName);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800256 return static_cast<Error>(intError);
Dan Stoza651bf312015-10-23 17:03:17 -0700257}
258
259Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
Lloyd Pique35d58242018-12-18 16:33:25 -0800260 std::unordered_map<HWC2::Layer*, LayerRequest>* outLayerRequests) {
Lloyd Piquee9eff972020-05-05 12:36:44 -0700261 uint32_t intDisplayRequests = 0;
Chia-I Wuaab99f52016-10-05 12:59:58 +0800262 std::vector<Hwc2::Layer> layerIds;
263 std::vector<uint32_t> layerRequests;
Steven Thomas94e35b92017-07-26 18:48:28 -0700264 auto intError = mComposer.getDisplayRequests(
265 mId, &intDisplayRequests, &layerIds, &layerRequests);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800266 uint32_t numElements = layerIds.size();
267 auto error = static_cast<Error>(intError);
Peiyong Line9d809e2020-04-14 13:10:48 -0700268 if (error != Error::NONE) {
Dan Stoza651bf312015-10-23 17:03:17 -0700269 return error;
270 }
271
272 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
273 outLayerRequests->clear();
274 outLayerRequests->reserve(numElements);
275 for (uint32_t element = 0; element < numElements; ++element) {
276 auto layer = getLayerById(layerIds[element]);
277 if (layer) {
278 auto layerRequest =
279 static_cast<LayerRequest>(layerRequests[element]);
Lloyd Piquea516c002021-05-07 14:36:58 -0700280 outLayerRequests->emplace(layer.get(), layerRequest);
Dan Stoza651bf312015-10-23 17:03:17 -0700281 } else {
282 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
283 PRIu64, layerIds[element], mId);
284 }
285 }
286
Peiyong Line9d809e2020-04-14 13:10:48 -0700287 return Error::NONE;
Dan Stoza651bf312015-10-23 17:03:17 -0700288}
289
Dominik Laskowski969cdcb2024-02-08 16:35:29 -0500290ftl::Expected<ui::DisplayConnectionType, hal::Error> Display::getConnectionType() const {
291 if (!mConnectionType) {
292 mConnectionType = [this]() -> decltype(mConnectionType) {
293 if (mType != DisplayType::PHYSICAL) {
294 return ftl::Unexpected(Error::BAD_DISPLAY);
295 }
Dominik Laskowski55c85402020-01-21 16:25:47 -0800296
Dominik Laskowski969cdcb2024-02-08 16:35:29 -0500297 using ConnectionType = Hwc2::IComposerClient::DisplayConnectionType;
298 ConnectionType connectionType;
299
300 if (const auto error = static_cast<Error>(
301 mComposer.getDisplayConnectionType(mId, &connectionType));
302 error != Error::NONE) {
303 return ftl::Unexpected(error);
304 }
305
306 return connectionType == ConnectionType::INTERNAL ? ui::DisplayConnectionType::Internal
307 : ui::DisplayConnectionType::External;
308 }();
Dominik Laskowski55c85402020-01-21 16:25:47 -0800309 }
310
Dominik Laskowski969cdcb2024-02-08 16:35:29 -0500311 return *mConnectionType;
Dan Stoza651bf312015-10-23 17:03:17 -0700312}
313
Leon Scroggins III5967aec2021-12-29 11:14:22 -0500314bool Display::hasCapability(DisplayCapability capability) const {
Ady Abraham27fbcc72021-09-20 14:54:57 -0700315 std::scoped_lock lock(mDisplayCapabilitiesMutex);
316 if (mDisplayCapabilities) {
317 return mDisplayCapabilities->count(capability) > 0;
318 }
319
Leon Scroggins III515f0382021-12-29 11:17:04 -0500320 ALOGW("Can't query capability %s."
Ady Abraham27fbcc72021-09-20 14:54:57 -0700321 " Display Capabilities were not queried from HWC yet",
Leon Scroggins III515f0382021-12-29 11:17:04 -0500322 to_string(capability).c_str());
Ady Abraham27fbcc72021-09-20 14:54:57 -0700323
324 return false;
325}
326
Peiyong Lined531a32018-10-26 18:27:56 -0700327Error Display::supportsDoze(bool* outSupport) const {
Leon Scroggins III689c80f2023-06-05 17:49:32 -0400328 {
329 std::scoped_lock lock(mDisplayCapabilitiesMutex);
330 if (!mDisplayCapabilities) {
331 // The display has not turned on since boot, so DOZE support is unknown.
332 ALOGW("%s: haven't queried capabilities yet!", __func__);
333 return Error::NO_RESOURCES;
334 }
335 }
Ady Abraham27fbcc72021-09-20 14:54:57 -0700336 *outSupport = hasCapability(DisplayCapability::DOZE);
Peiyong Line9d809e2020-04-14 13:10:48 -0700337 return Error::NONE;
Dan Stoza651bf312015-10-23 17:03:17 -0700338}
339
Peiyong Lin62665892018-04-16 11:07:44 -0700340Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) const
Dan Stoza7d7ae732016-03-16 12:23:40 -0700341{
Dan Stoza7d7ae732016-03-16 12:23:40 -0700342 float maxLuminance = -1.0f;
343 float maxAverageLuminance = -1.0f;
344 float minLuminance = -1.0f;
Marc Kassisbdf7e4b2022-11-04 17:26:48 +0100345 std::vector<Hwc2::Hdr> hdrTypes;
346 auto intError = mComposer.getHdrCapabilities(mId, &hdrTypes, &maxLuminance,
347 &maxAverageLuminance, &minLuminance);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800348 auto error = static_cast<HWC2::Error>(intError);
349
Peiyong Line9d809e2020-04-14 13:10:48 -0700350 if (error != Error::NONE) {
Dan Stoza7d7ae732016-03-16 12:23:40 -0700351 return error;
352 }
353
Marc Kassisbdf7e4b2022-11-04 17:26:48 +0100354 *outCapabilities =
355 HdrCapabilities(std::move(hdrTypes), maxLuminance, maxAverageLuminance, minLuminance);
Peiyong Line9d809e2020-04-14 13:10:48 -0700356 return Error::NONE;
Dan Stoza7d7ae732016-03-16 12:23:40 -0700357}
358
Sally Qibb866c12022-10-17 11:31:20 -0700359Error Display::getOverlaySupport(OverlayProperties* outProperties) const {
360 auto intError = mComposer.getOverlaySupport(outProperties);
361 return static_cast<Error>(intError);
Sally Qi0cbd08b2022-08-17 12:12:28 -0700362}
363
Peiyong Line9d809e2020-04-14 13:10:48 -0700364Error Display::getDisplayedContentSamplingAttributes(hal::PixelFormat* outFormat,
Kevin DuBois9c0a1762018-10-16 13:32:31 -0700365 Dataspace* outDataspace,
366 uint8_t* outComponentMask) const {
367 auto intError = mComposer.getDisplayedContentSamplingAttributes(mId, outFormat, outDataspace,
368 outComponentMask);
369 return static_cast<Error>(intError);
370}
371
Kevin DuBois74e53772018-11-19 10:52:38 -0800372Error Display::setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask,
373 uint64_t maxFrames) const {
374 auto intError =
375 mComposer.setDisplayContentSamplingEnabled(mId, enabled, componentMask, maxFrames);
376 return static_cast<Error>(intError);
377}
378
Kevin DuBois1d4249a2018-08-29 10:45:14 -0700379Error Display::getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp,
380 android::DisplayedFrameStats* outStats) const {
381 auto intError = mComposer.getDisplayedContentSample(mId, maxFrames, timestamp, outStats);
382 return static_cast<Error>(intError);
383}
384
Lloyd Pique35d58242018-12-18 16:33:25 -0800385Error Display::getReleaseFences(std::unordered_map<HWC2::Layer*, sp<Fence>>* outFences) const {
Chia-I Wuaab99f52016-10-05 12:59:58 +0800386 std::vector<Hwc2::Layer> layerIds;
387 std::vector<int> fenceFds;
Steven Thomas94e35b92017-07-26 18:48:28 -0700388 auto intError = mComposer.getReleaseFences(mId, &layerIds, &fenceFds);
Chia-I Wuaab99f52016-10-05 12:59:58 +0800389 auto error = static_cast<Error>(intError);
390 uint32_t numElements = layerIds.size();
Peiyong Line9d809e2020-04-14 13:10:48 -0700391 if (error != Error::NONE) {
Dan Stoza651bf312015-10-23 17:03:17 -0700392 return error;
393 }
394
Lloyd Pique35d58242018-12-18 16:33:25 -0800395 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
Dan Stoza651bf312015-10-23 17:03:17 -0700396 releaseFences.reserve(numElements);
397 for (uint32_t element = 0; element < numElements; ++element) {
398 auto layer = getLayerById(layerIds[element]);
399 if (layer) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700400 sp<Fence> fence(sp<Fence>::make(fenceFds[element]));
Lloyd Piquea516c002021-05-07 14:36:58 -0700401 releaseFences.emplace(layer.get(), fence);
Dan Stoza651bf312015-10-23 17:03:17 -0700402 } else {
403 ALOGE("getReleaseFences: invalid layer %" PRIu64
404 " found on display %" PRIu64, layerIds[element], mId);
Chia-I Wu5e74c652017-05-17 13:43:16 -0700405 for (; element < numElements; ++element) {
406 close(fenceFds[element]);
407 }
Peiyong Line9d809e2020-04-14 13:10:48 -0700408 return Error::BAD_LAYER;
Dan Stoza651bf312015-10-23 17:03:17 -0700409 }
410 }
411
412 *outFences = std::move(releaseFences);
Peiyong Line9d809e2020-04-14 13:10:48 -0700413 return Error::NONE;
Dan Stoza651bf312015-10-23 17:03:17 -0700414}
415
Fabien Sanglard11d0fc32016-12-01 15:43:01 -0800416Error Display::present(sp<Fence>* outPresentFence)
Dan Stoza651bf312015-10-23 17:03:17 -0700417{
Naseer Ahmed847650b2016-06-17 11:14:25 -0400418 int32_t presentFenceFd = -1;
Steven Thomas94e35b92017-07-26 18:48:28 -0700419 auto intError = mComposer.presentDisplay(mId, &presentFenceFd);
Dan Stoza651bf312015-10-23 17:03:17 -0700420 auto error = static_cast<Error>(intError);
Peiyong Line9d809e2020-04-14 13:10:48 -0700421 if (error != Error::NONE) {
Dan Stoza651bf312015-10-23 17:03:17 -0700422 return error;
423 }
424
Ady Abrahamd11bade2022-08-01 16:18:03 -0700425 *outPresentFence = sp<Fence>::make(presentFenceFd);
Peiyong Line9d809e2020-04-14 13:10:48 -0700426 return Error::NONE;
Dan Stoza651bf312015-10-23 17:03:17 -0700427}
428
Marin Shalamanov3ea1d602020-12-16 19:59:39 +0100429Error Display::setActiveConfigWithConstraints(hal::HWConfigId configId,
430 const VsyncPeriodChangeConstraints& constraints,
431 VsyncPeriodChangeTimeline* outTimeline) {
Ady Abraham7159f572019-10-11 11:10:18 -0700432 ALOGV("[%" PRIu64 "] setActiveConfigWithConstraints", mId);
Ady Abraham7159f572019-10-11 11:10:18 -0700433
Dominik Laskowski88096872023-12-08 15:26:04 -0500434 // FIXME (b/319505580): At least the first config set on an external display must be
435 // `setActiveConfig`, so skip over the block that calls `setActiveConfigWithConstraints`
436 // for simplicity.
Dominik Laskowski88096872023-12-08 15:26:04 -0500437 const bool connected_display = FlagManager::getInstance().connected_display();
Dominik Laskowski88096872023-12-08 15:26:04 -0500438
439 if (isVsyncPeriodSwitchSupported() &&
Dominik Laskowski969cdcb2024-02-08 16:35:29 -0500440 (!connected_display ||
441 getConnectionType().value_opt() != ui::DisplayConnectionType::External)) {
Ady Abraham7159f572019-10-11 11:10:18 -0700442 Hwc2::IComposerClient::VsyncPeriodChangeConstraints hwc2Constraints;
443 hwc2Constraints.desiredTimeNanos = constraints.desiredTimeNanos;
444 hwc2Constraints.seamlessRequired = constraints.seamlessRequired;
445
446 Hwc2::VsyncPeriodChangeTimeline vsyncPeriodChangeTimeline = {};
Marin Shalamanov3ea1d602020-12-16 19:59:39 +0100447 auto intError = mComposer.setActiveConfigWithConstraints(mId, configId, hwc2Constraints,
448 &vsyncPeriodChangeTimeline);
Ady Abraham7159f572019-10-11 11:10:18 -0700449 outTimeline->newVsyncAppliedTimeNanos = vsyncPeriodChangeTimeline.newVsyncAppliedTimeNanos;
450 outTimeline->refreshRequired = vsyncPeriodChangeTimeline.refreshRequired;
451 outTimeline->refreshTimeNanos = vsyncPeriodChangeTimeline.refreshTimeNanos;
452 return static_cast<Error>(intError);
453 }
454
455 // Use legacy setActiveConfig instead
456 ALOGV("fallback to legacy setActiveConfig");
457 const auto now = systemTime();
458 if (constraints.desiredTimeNanos > now || constraints.seamlessRequired) {
459 ALOGE("setActiveConfigWithConstraints received constraints that can't be satisfied");
460 }
461
Marin Shalamanov3ea1d602020-12-16 19:59:39 +0100462 auto intError_2_4 = mComposer.setActiveConfig(mId, configId);
Ady Abraham7159f572019-10-11 11:10:18 -0700463 outTimeline->newVsyncAppliedTimeNanos = std::max(now, constraints.desiredTimeNanos);
464 outTimeline->refreshRequired = true;
465 outTimeline->refreshTimeNanos = now;
466 return static_cast<Error>(intError_2_4);
467}
468
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400469Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target,
Alec Mourif97df4d2023-09-06 02:10:05 +0000470 const sp<Fence>& acquireFence, Dataspace dataspace,
471 float hdrSdrRatio) {
Dan Stoza5cf424b2016-05-20 14:02:39 -0700472 // TODO: Properly encode client target surface damage
Dan Stoza651bf312015-10-23 17:03:17 -0700473 int32_t fenceFd = acquireFence->dup();
Alec Mourif97df4d2023-09-06 02:10:05 +0000474 auto intError =
475 mComposer.setClientTarget(mId, slot, target, fenceFd, dataspace,
476 std::vector<Hwc2::IComposerClient::Rect>(), hdrSdrRatio);
Dan Stoza651bf312015-10-23 17:03:17 -0700477 return static_cast<Error>(intError);
478}
479
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700480Error Display::setColorMode(ColorMode mode, RenderIntent renderIntent)
Dan Stoza076ac672016-03-14 10:47:53 -0700481{
Peiyong Lin0e7a7912018-04-05 14:36:36 -0700482 auto intError = mComposer.setColorMode(mId, mode, renderIntent);
Dan Stoza076ac672016-03-14 10:47:53 -0700483 return static_cast<Error>(intError);
484}
485
Ady Abrahamdc011a92021-12-21 14:06:44 -0800486Error Display::setColorTransform(const android::mat4& matrix) {
487 auto intError = mComposer.setColorTransform(mId, matrix.asArray());
Dan Stoza5df2a862016-03-24 16:19:37 -0700488 return static_cast<Error>(intError);
489}
490
Dan Stoza651bf312015-10-23 17:03:17 -0700491Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
492 const sp<Fence>& releaseFence)
493{
494 int32_t fenceFd = releaseFence->dup();
495 auto handle = buffer->getNativeBuffer()->handle;
Steven Thomas94e35b92017-07-26 18:48:28 -0700496 auto intError = mComposer.setOutputBuffer(mId, handle, fenceFd);
Dan Stoza38628982016-07-13 15:48:58 -0700497 close(fenceFd);
Dan Stoza651bf312015-10-23 17:03:17 -0700498 return static_cast<Error>(intError);
499}
500
501Error Display::setPowerMode(PowerMode mode)
502{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800503 auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
Steven Thomas94e35b92017-07-26 18:48:28 -0700504 auto intError = mComposer.setPowerMode(mId, intMode);
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700505
Peiyong Line9d809e2020-04-14 13:10:48 -0700506 if (mode == PowerMode::ON) {
HyunKyounga264a352024-04-24 18:51:33 +0900507 loadDisplayCapabilities();
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700508 }
509
Dan Stoza651bf312015-10-23 17:03:17 -0700510 return static_cast<Error>(intError);
511}
512
513Error Display::setVsyncEnabled(Vsync enabled)
514{
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800515 auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
Steven Thomas94e35b92017-07-26 18:48:28 -0700516 auto intError = mComposer.setVsyncEnabled(mId, intEnabled);
Dan Stoza651bf312015-10-23 17:03:17 -0700517 return static_cast<Error>(intError);
518}
519
ramindani09acbb82023-11-03 09:02:38 -0700520Error Display::validate(nsecs_t expectedPresentTime, int32_t frameIntervalNs, uint32_t* outNumTypes,
Ady Abraham43065bd2021-12-10 17:22:15 -0800521 uint32_t* outNumRequests) {
Dan Stoza651bf312015-10-23 17:03:17 -0700522 uint32_t numTypes = 0;
523 uint32_t numRequests = 0;
ramindani09acbb82023-11-03 09:02:38 -0700524 auto intError = mComposer.validateDisplay(mId, expectedPresentTime, frameIntervalNs, &numTypes,
525 &numRequests);
Dan Stoza651bf312015-10-23 17:03:17 -0700526 auto error = static_cast<Error>(intError);
Peiyong Line9d809e2020-04-14 13:10:48 -0700527 if (error != Error::NONE && !hasChangesError(error)) {
Dan Stoza651bf312015-10-23 17:03:17 -0700528 return error;
529 }
530
531 *outNumTypes = numTypes;
532 *outNumRequests = numRequests;
533 return error;
534}
535
ramindani4aac32c2023-10-30 14:13:30 -0700536Error Display::presentOrValidate(nsecs_t expectedPresentTime, int32_t frameIntervalNs,
537 uint32_t* outNumTypes, uint32_t* outNumRequests,
538 sp<android::Fence>* outPresentFence, uint32_t* state) {
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700539 uint32_t numTypes = 0;
540 uint32_t numRequests = 0;
541 int32_t presentFenceFd = -1;
ramindani4aac32c2023-10-30 14:13:30 -0700542 auto intError =
543 mComposer.presentOrValidateDisplay(mId, expectedPresentTime, frameIntervalNs, &numTypes,
544 &numRequests, &presentFenceFd, state);
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700545 auto error = static_cast<Error>(intError);
Peiyong Line9d809e2020-04-14 13:10:48 -0700546 if (error != Error::NONE && !hasChangesError(error)) {
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700547 return error;
548 }
549
550 if (*state == 1) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700551 *outPresentFence = sp<Fence>::make(presentFenceFd);
Fabien Sanglard249c0ae2017-06-19 19:22:36 -0700552 }
553
554 if (*state == 0) {
555 *outNumTypes = numTypes;
556 *outNumRequests = numRequests;
557 }
558 return error;
559}
Chia-I Wu0c6ce462017-06-22 10:48:28 -0700560
Dominik Laskowskib17c6212022-05-09 09:36:19 -0700561ftl::Future<Error> Display::setDisplayBrightness(
Alec Mouri4d8a05d2022-03-23 18:14:26 +0000562 float brightness, float brightnessNits,
563 const Hwc2::Composer::DisplayBrightnessOptions& options) {
564 return ftl::defer([composer = &mComposer, id = mId, brightness, brightnessNits, options] {
565 const auto intError =
566 composer->setDisplayBrightness(id, brightness, brightnessNits, options);
Dominik Laskowski5690bde2020-04-23 19:04:22 -0700567 return static_cast<Error>(intError);
568 });
Dan Gittik57e63c52019-01-18 16:37:54 +0000569}
570
Kriti Dang7defaf32021-11-15 11:55:43 +0100571Error Display::setBootDisplayConfig(hal::HWConfigId configId) {
572 auto intError = mComposer.setBootDisplayConfig(mId, configId);
573 return static_cast<Error>(intError);
574}
575
576Error Display::clearBootDisplayConfig() {
577 auto intError = mComposer.clearBootDisplayConfig(mId);
578 return static_cast<Error>(intError);
579}
580
581Error Display::getPreferredBootDisplayConfig(hal::HWConfigId* configId) const {
582 auto intError = mComposer.getPreferredBootDisplayConfig(mId, configId);
583 return static_cast<Error>(intError);
584}
585
Dominik Laskowski5690bde2020-04-23 19:04:22 -0700586Error Display::setAutoLowLatencyMode(bool on) {
Galia Peycheva5492cb52019-10-30 14:13:16 +0100587 auto intError = mComposer.setAutoLowLatencyMode(mId, on);
588 return static_cast<Error>(intError);
589}
590
591Error Display::getSupportedContentTypes(std::vector<ContentType>* outSupportedContentTypes) const {
592 std::vector<Hwc2::IComposerClient::ContentType> tmpSupportedContentTypes;
593 auto intError = mComposer.getSupportedContentTypes(mId, &tmpSupportedContentTypes);
594 for (Hwc2::IComposerClient::ContentType contentType : tmpSupportedContentTypes) {
595 outSupportedContentTypes->push_back(static_cast<ContentType>(contentType));
596 }
597 return static_cast<Error>(intError);
598}
599
Dominik Laskowski5690bde2020-04-23 19:04:22 -0700600Error Display::setContentType(ContentType contentType) {
Peiyong Line9d809e2020-04-14 13:10:48 -0700601 auto intError = mComposer.setContentType(mId, contentType);
Galia Peycheva5492cb52019-10-30 14:13:16 +0100602 return static_cast<Error>(intError);
603}
604
Alec Mouri85065692022-03-18 00:58:26 +0000605Error Display::getClientTargetProperty(
606 aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness*
607 outClientTargetProperty) {
608 const auto error = mComposer.getClientTargetProperty(mId, outClientTargetProperty);
Peiyong Lindfc3f7c2020-05-07 20:15:50 -0700609 return static_cast<Error>(error);
610}
611
Sally Qi11dcd582024-08-16 18:11:27 -0700612Error Display::getRequestedLuts(std::vector<DisplayLuts::LayerLut>* outLayerLuts) {
613 std::vector<DisplayLuts::LayerLut> tmpLayerLuts;
614 const auto error = mComposer.getRequestedLuts(mId, &tmpLayerLuts);
615 for (DisplayLuts::LayerLut& layerLut : tmpLayerLuts) {
616 if (layerLut.lut.pfd.get() >= 0) {
617 outLayerLuts->push_back({layerLut.layer,
618 Lut{ndk::ScopedFileDescriptor(layerLut.lut.pfd.release()),
619 layerLut.lut.lutProperties}});
Sally Qi492cec32024-06-28 14:34:47 -0700620 }
621 }
622 return static_cast<Error>(error);
623}
624
Leon Scroggins IIIe7c51c62022-02-01 15:53:54 -0500625Error Display::getDisplayDecorationSupport(
626 std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
627 support) {
628 const auto error = mComposer.getDisplayDecorationSupport(mId, support);
629 return static_cast<Error>(error);
630}
631
ramindani32cf0602022-03-02 02:30:29 +0000632Error Display::setIdleTimerEnabled(std::chrono::milliseconds timeout) {
633 const auto error = mComposer.setIdleTimerEnabled(mId, timeout);
634 return static_cast<Error>(error);
635}
636
Dan Stoza651bf312015-10-23 17:03:17 -0700637// For use by Device
638
Steven Thomas94e35b92017-07-26 18:48:28 -0700639void Display::setConnected(bool connected) {
Steven Thomasb6c6ad42018-01-29 12:22:00 -0800640 if (!mIsConnected && connected) {
Steven Thomas94e35b92017-07-26 18:48:28 -0700641 mComposer.setClientTargetSlotCount(mId);
Steven Thomas94e35b92017-07-26 18:48:28 -0700642 }
643 mIsConnected = connected;
644}
645
Dan Stoza651bf312015-10-23 17:03:17 -0700646// Other Display methods
647
Lloyd Piquea516c002021-05-07 14:36:58 -0700648std::shared_ptr<HWC2::Layer> Display::getLayerById(HWLayerId id) const {
649 auto it = mLayers.find(id);
650 return it != mLayers.end() ? it->second.lock() : nullptr;
Dan Stoza651bf312015-10-23 17:03:17 -0700651}
HyunKyounga264a352024-04-24 18:51:33 +0900652
653void Display::loadDisplayCapabilities() {
654 std::call_once(mDisplayCapabilityQueryFlag, [this]() {
655 std::vector<DisplayCapability> tmpCapabilities;
656 auto error =
657 static_cast<Error>(mComposer.getDisplayCapabilities(mId, &tmpCapabilities));
658 if (error == Error::NONE) {
659 std::scoped_lock lock(mDisplayCapabilitiesMutex);
660 mDisplayCapabilities.emplace();
661 for (auto capability : tmpCapabilities) {
662 mDisplayCapabilities->emplace(capability);
663 }
664 } else if (error == Error::UNSUPPORTED) {
665 std::scoped_lock lock(mDisplayCapabilitiesMutex);
666 mDisplayCapabilities.emplace();
667 if (mCapabilities.count(AidlCapability::SKIP_CLIENT_COLOR_TRANSFORM)) {
668 mDisplayCapabilities->emplace(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
669 }
670 bool dozeSupport = false;
671 error = static_cast<Error>(mComposer.getDozeSupport(mId, &dozeSupport));
672 if (error == Error::NONE && dozeSupport) {
673 mDisplayCapabilities->emplace(DisplayCapability::DOZE);
674 }
675 }
676 });
677}
Lucas Berthou8d0a0c42024-08-27 14:32:31 +0000678
679void Display::setPhysicalSizeInMm(std::optional<ui::Size> size) {
680 mPhysicalSize = size;
681}
682
Ana Krulec4593b692019-01-11 22:07:25 -0800683} // namespace impl
Dan Stoza651bf312015-10-23 17:03:17 -0700684
685// Layer methods
686
Leon Scroggins III4459bf42022-01-04 13:58:26 -0500687namespace {
688std::vector<Hwc2::IComposerClient::Rect> convertRegionToHwcRects(const Region& region) {
689 size_t rectCount = 0;
690 Rect const* rectArray = region.getArray(&rectCount);
691
692 std::vector<Hwc2::IComposerClient::Rect> hwcRects;
693 hwcRects.reserve(rectCount);
694 for (size_t rect = 0; rect < rectCount; ++rect) {
695 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, rectArray[rect].right,
696 rectArray[rect].bottom});
697 }
698 return hwcRects;
699}
700} // namespace
701
Lloyd Pique35d58242018-12-18 16:33:25 -0800702Layer::~Layer() = default;
703
704namespace impl {
705
Ady Abrahamde549d42022-01-26 19:19:17 -0800706Layer::Layer(android::Hwc2::Composer& composer,
707 const std::unordered_set<AidlCapability>& capabilities, HWC2::Display& display,
708 HWLayerId layerId)
Lloyd Pique4603f3c2020-02-11 12:06:56 -0800709 : mComposer(composer),
710 mCapabilities(capabilities),
Lloyd Piquea516c002021-05-07 14:36:58 -0700711 mDisplay(&display),
Lloyd Pique4603f3c2020-02-11 12:06:56 -0800712 mId(layerId),
713 mColorMatrix(android::mat4()) {
Lloyd Piquea516c002021-05-07 14:36:58 -0700714 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, display.getId());
Dan Stoza651bf312015-10-23 17:03:17 -0700715}
716
717Layer::~Layer()
718{
Lloyd Piquea516c002021-05-07 14:36:58 -0700719 onOwningDisplayDestroyed();
720}
721
722void Layer::onOwningDisplayDestroyed() {
723 // Note: onOwningDisplayDestroyed() may be called to perform cleanup by
724 // either the Layer dtor or by the Display dtor and must be safe to call
725 // from either path. In particular, the call to Display::onLayerDestroyed()
726 // is expected to be safe to do,
727
728 if (CC_UNLIKELY(!mDisplay)) {
729 return;
730 }
731
732 mDisplay->onLayerDestroyed(mId);
733
734 // Note: If the HWC display was actually disconnected, these calls are will
735 // return an error. We always make them as there may be other reasons for
736 // the HWC2::Display to be destroyed.
737 auto intError = mComposer.destroyLayer(mDisplay->getId(), mId);
Steven Thomas94e35b92017-07-26 18:48:28 -0700738 auto error = static_cast<Error>(intError);
Peiyong Line9d809e2020-04-14 13:10:48 -0700739 ALOGE_IF(error != Error::NONE,
740 "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
741 " failed: %s (%d)",
Lloyd Piquea516c002021-05-07 14:36:58 -0700742 mDisplay->getId(), mId, to_string(error).c_str(), intError);
743
744 mDisplay = nullptr;
Steven Thomas94e35b92017-07-26 18:48:28 -0700745}
746
Dan Stoza651bf312015-10-23 17:03:17 -0700747Error Layer::setCursorPosition(int32_t x, int32_t y)
748{
Lloyd Piquea516c002021-05-07 14:36:58 -0700749 if (CC_UNLIKELY(!mDisplay)) {
750 return Error::BAD_DISPLAY;
751 }
752
753 auto intError = mComposer.setCursorPosition(mDisplay->getId(), mId, x, y);
Dan Stoza651bf312015-10-23 17:03:17 -0700754 return static_cast<Error>(intError);
755}
756
Daniel Nicoara1f42e3a2017-04-10 13:27:32 -0400757Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
Dan Stoza651bf312015-10-23 17:03:17 -0700758 const sp<Fence>& acquireFence)
759{
Lloyd Piquea516c002021-05-07 14:36:58 -0700760 if (CC_UNLIKELY(!mDisplay)) {
761 return Error::BAD_DISPLAY;
762 }
763
Yichi Chen8366f562019-03-25 19:44:06 +0800764 if (buffer == nullptr && mBufferSlot == slot) {
Peiyong Line9d809e2020-04-14 13:10:48 -0700765 return Error::NONE;
Yichi Chen8366f562019-03-25 19:44:06 +0800766 }
767 mBufferSlot = slot;
768
Dan Stoza651bf312015-10-23 17:03:17 -0700769 int32_t fenceFd = acquireFence->dup();
Lloyd Piquea516c002021-05-07 14:36:58 -0700770 auto intError = mComposer.setLayerBuffer(mDisplay->getId(), mId, slot, buffer, fenceFd);
Dan Stoza651bf312015-10-23 17:03:17 -0700771 return static_cast<Error>(intError);
772}
773
Brian Lindahlb158a5c2022-12-15 15:21:13 -0700774Error Layer::setBufferSlotsToClear(const std::vector<uint32_t>& slotsToClear,
775 uint32_t activeBufferSlot) {
Brian Lindahl90553da2022-12-06 13:36:30 -0700776 if (CC_UNLIKELY(!mDisplay)) {
777 return Error::BAD_DISPLAY;
778 }
Brian Lindahlb158a5c2022-12-15 15:21:13 -0700779 auto intError = mComposer.setLayerBufferSlotsToClear(mDisplay->getId(), mId, slotsToClear,
780 activeBufferSlot);
Brian Lindahl90553da2022-12-06 13:36:30 -0700781 return static_cast<Error>(intError);
782}
783
Dan Stoza651bf312015-10-23 17:03:17 -0700784Error Layer::setSurfaceDamage(const Region& damage)
785{
Lloyd Piquea516c002021-05-07 14:36:58 -0700786 if (CC_UNLIKELY(!mDisplay)) {
787 return Error::BAD_DISPLAY;
788 }
789
Yichi Chen8366f562019-03-25 19:44:06 +0800790 if (damage.isRect() && mDamageRegion.isRect() &&
791 (damage.getBounds() == mDamageRegion.getBounds())) {
Peiyong Line9d809e2020-04-14 13:10:48 -0700792 return Error::NONE;
Yichi Chen8366f562019-03-25 19:44:06 +0800793 }
794 mDamageRegion = damage;
795
Dan Stoza651bf312015-10-23 17:03:17 -0700796 // We encode default full-screen damage as INVALID_RECT upstream, but as 0
797 // rects for HWC
Chia-I Wuaab99f52016-10-05 12:59:58 +0800798 Hwc2::Error intError = Hwc2::Error::NONE;
Dan Stoza651bf312015-10-23 17:03:17 -0700799 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
Lloyd Piquea516c002021-05-07 14:36:58 -0700800 intError = mComposer.setLayerSurfaceDamage(mDisplay->getId(), mId,
801 std::vector<Hwc2::IComposerClient::Rect>());
Dan Stoza651bf312015-10-23 17:03:17 -0700802 } else {
Leon Scroggins III4459bf42022-01-04 13:58:26 -0500803 const auto hwcRects = convertRegionToHwcRects(damage);
Lloyd Piquea516c002021-05-07 14:36:58 -0700804 intError = mComposer.setLayerSurfaceDamage(mDisplay->getId(), mId, hwcRects);
Dan Stoza651bf312015-10-23 17:03:17 -0700805 }
806
807 return static_cast<Error>(intError);
808}
809
810Error Layer::setBlendMode(BlendMode mode)
811{
Lloyd Piquea516c002021-05-07 14:36:58 -0700812 if (CC_UNLIKELY(!mDisplay)) {
813 return Error::BAD_DISPLAY;
814 }
815
816 auto intError = mComposer.setLayerBlendMode(mDisplay->getId(), mId, mode);
Dan Stoza651bf312015-10-23 17:03:17 -0700817 return static_cast<Error>(intError);
818}
819
Peiyong Line9d809e2020-04-14 13:10:48 -0700820Error Layer::setColor(Color color) {
Lloyd Piquea516c002021-05-07 14:36:58 -0700821 if (CC_UNLIKELY(!mDisplay)) {
822 return Error::BAD_DISPLAY;
823 }
824
825 auto intError = mComposer.setLayerColor(mDisplay->getId(), mId, color);
Dan Stoza651bf312015-10-23 17:03:17 -0700826 return static_cast<Error>(intError);
827}
828
829Error Layer::setCompositionType(Composition type)
830{
Lloyd Piquea516c002021-05-07 14:36:58 -0700831 if (CC_UNLIKELY(!mDisplay)) {
832 return Error::BAD_DISPLAY;
833 }
834
835 auto intError = mComposer.setLayerCompositionType(mDisplay->getId(), mId, type);
Dan Stoza651bf312015-10-23 17:03:17 -0700836 return static_cast<Error>(intError);
837}
838
Peiyong Lin34beb7a2018-03-28 11:57:12 -0700839Error Layer::setDataspace(Dataspace dataspace)
Dan Stoza5df2a862016-03-24 16:19:37 -0700840{
Lloyd Piquea516c002021-05-07 14:36:58 -0700841 if (CC_UNLIKELY(!mDisplay)) {
842 return Error::BAD_DISPLAY;
843 }
844
Courtney Goeltzenleuchterc988ee42017-05-31 17:56:46 -0600845 if (dataspace == mDataSpace) {
Peiyong Line9d809e2020-04-14 13:10:48 -0700846 return Error::NONE;
Courtney Goeltzenleuchterc988ee42017-05-31 17:56:46 -0600847 }
848 mDataSpace = dataspace;
Lloyd Piquea516c002021-05-07 14:36:58 -0700849 auto intError = mComposer.setLayerDataspace(mDisplay->getId(), mId, mDataSpace);
Dan Stoza5df2a862016-03-24 16:19:37 -0700850 return static_cast<Error>(intError);
851}
852
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700853Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
854 const android::HdrMetadata& metadata)
855{
Lloyd Piquea516c002021-05-07 14:36:58 -0700856 if (CC_UNLIKELY(!mDisplay)) {
857 return Error::BAD_DISPLAY;
858 }
859
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700860 if (metadata == mHdrMetadata) {
Peiyong Line9d809e2020-04-14 13:10:48 -0700861 return Error::NONE;
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700862 }
863
864 mHdrMetadata = metadata;
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700865 int validTypes = mHdrMetadata.validTypes & supportedPerFrameMetadata;
866 std::vector<Hwc2::PerFrameMetadata> perFrameMetadatas;
867 if (validTypes & HdrMetadata::SMPTE2086) {
868 perFrameMetadatas.insert(perFrameMetadatas.end(),
869 {{Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
Valerie Haue9e843a2018-12-18 13:39:23 -0800870 mHdrMetadata.smpte2086.displayPrimaryRed.x},
871 {Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
872 mHdrMetadata.smpte2086.displayPrimaryRed.y},
873 {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
874 mHdrMetadata.smpte2086.displayPrimaryGreen.x},
875 {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
876 mHdrMetadata.smpte2086.displayPrimaryGreen.y},
877 {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
878 mHdrMetadata.smpte2086.displayPrimaryBlue.x},
879 {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
880 mHdrMetadata.smpte2086.displayPrimaryBlue.y},
881 {Hwc2::PerFrameMetadataKey::WHITE_POINT_X,
882 mHdrMetadata.smpte2086.whitePoint.x},
883 {Hwc2::PerFrameMetadataKey::WHITE_POINT_Y,
884 mHdrMetadata.smpte2086.whitePoint.y},
885 {Hwc2::PerFrameMetadataKey::MAX_LUMINANCE,
886 mHdrMetadata.smpte2086.maxLuminance},
887 {Hwc2::PerFrameMetadataKey::MIN_LUMINANCE,
888 mHdrMetadata.smpte2086.minLuminance}});
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700889 }
890
891 if (validTypes & HdrMetadata::CTA861_3) {
892 perFrameMetadatas.insert(perFrameMetadatas.end(),
893 {{Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
Valerie Haue9e843a2018-12-18 13:39:23 -0800894 mHdrMetadata.cta8613.maxContentLightLevel},
895 {Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
896 mHdrMetadata.cta8613.maxFrameAverageLightLevel}});
Peiyong Lin0ac5f4e2018-04-19 22:06:34 -0700897 }
898
Alec Mouri66d83482022-01-11 11:14:44 -0800899 const Error error = static_cast<Error>(
900 mComposer.setLayerPerFrameMetadata(mDisplay->getId(), mId, perFrameMetadatas));
901 if (error != Error::NONE) {
902 return error;
903 }
Valerie Haue9e843a2018-12-18 13:39:23 -0800904
Alec Mouri66d83482022-01-11 11:14:44 -0800905 std::vector<Hwc2::PerFrameMetadataBlob> perFrameMetadataBlobs;
Valerie Haue9e843a2018-12-18 13:39:23 -0800906 if (validTypes & HdrMetadata::HDR10PLUS) {
Yichi Chen1d5146d2020-06-12 18:50:11 +0800907 if (CC_UNLIKELY(mHdrMetadata.hdr10plus.size() == 0)) {
908 return Error::BAD_PARAMETER;
909 }
910
Valerie Haue9e843a2018-12-18 13:39:23 -0800911 perFrameMetadataBlobs.push_back(
912 {Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI, mHdrMetadata.hdr10plus});
Valerie Haue9e843a2018-12-18 13:39:23 -0800913 }
Alec Mouri66d83482022-01-11 11:14:44 -0800914
915 return static_cast<Error>(
916 mComposer.setLayerPerFrameMetadataBlobs(mDisplay->getId(), mId, perFrameMetadataBlobs));
Courtney Goeltzenleuchterf9c98e52018-02-12 07:23:17 -0700917}
918
Dan Stoza651bf312015-10-23 17:03:17 -0700919Error Layer::setDisplayFrame(const Rect& frame)
920{
Lloyd Piquea516c002021-05-07 14:36:58 -0700921 if (CC_UNLIKELY(!mDisplay)) {
922 return Error::BAD_DISPLAY;
923 }
924
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800925 Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
Chia-I Wuaab99f52016-10-05 12:59:58 +0800926 frame.right, frame.bottom};
Lloyd Piquea516c002021-05-07 14:36:58 -0700927 auto intError = mComposer.setLayerDisplayFrame(mDisplay->getId(), mId, hwcRect);
Dan Stoza651bf312015-10-23 17:03:17 -0700928 return static_cast<Error>(intError);
929}
930
931Error Layer::setPlaneAlpha(float alpha)
932{
Lloyd Piquea516c002021-05-07 14:36:58 -0700933 if (CC_UNLIKELY(!mDisplay)) {
934 return Error::BAD_DISPLAY;
935 }
936
937 auto intError = mComposer.setLayerPlaneAlpha(mDisplay->getId(), mId, alpha);
Dan Stoza651bf312015-10-23 17:03:17 -0700938 return static_cast<Error>(intError);
939}
940
941Error Layer::setSidebandStream(const native_handle_t* stream)
942{
Lloyd Piquea516c002021-05-07 14:36:58 -0700943 if (CC_UNLIKELY(!mDisplay)) {
944 return Error::BAD_DISPLAY;
945 }
946
Ady Abrahamde549d42022-01-26 19:19:17 -0800947 if (mCapabilities.count(AidlCapability::SIDEBAND_STREAM) == 0) {
Dan Stoza09e7a272016-04-14 12:31:01 -0700948 ALOGE("Attempted to call setSidebandStream without checking that the "
949 "device supports sideband streams");
Peiyong Line9d809e2020-04-14 13:10:48 -0700950 return Error::UNSUPPORTED;
Dan Stoza09e7a272016-04-14 12:31:01 -0700951 }
Lloyd Piquea516c002021-05-07 14:36:58 -0700952 auto intError = mComposer.setLayerSidebandStream(mDisplay->getId(), mId, stream);
Dan Stoza651bf312015-10-23 17:03:17 -0700953 return static_cast<Error>(intError);
954}
955
956Error Layer::setSourceCrop(const FloatRect& crop)
957{
Lloyd Piquea516c002021-05-07 14:36:58 -0700958 if (CC_UNLIKELY(!mDisplay)) {
959 return Error::BAD_DISPLAY;
960 }
961
Chia-I Wucd8d7f02016-11-16 11:02:31 +0800962 Hwc2::IComposerClient::FRect hwcRect{
Chia-I Wuaab99f52016-10-05 12:59:58 +0800963 crop.left, crop.top, crop.right, crop.bottom};
Lloyd Piquea516c002021-05-07 14:36:58 -0700964 auto intError = mComposer.setLayerSourceCrop(mDisplay->getId(), mId, hwcRect);
Dan Stoza651bf312015-10-23 17:03:17 -0700965 return static_cast<Error>(intError);
966}
967
968Error Layer::setTransform(Transform transform)
969{
Lloyd Piquea516c002021-05-07 14:36:58 -0700970 if (CC_UNLIKELY(!mDisplay)) {
971 return Error::BAD_DISPLAY;
972 }
973
Chia-I Wuaab99f52016-10-05 12:59:58 +0800974 auto intTransform = static_cast<Hwc2::Transform>(transform);
Lloyd Piquea516c002021-05-07 14:36:58 -0700975 auto intError = mComposer.setLayerTransform(mDisplay->getId(), mId, intTransform);
Dan Stoza651bf312015-10-23 17:03:17 -0700976 return static_cast<Error>(intError);
977}
978
979Error Layer::setVisibleRegion(const Region& region)
980{
Lloyd Piquea516c002021-05-07 14:36:58 -0700981 if (CC_UNLIKELY(!mDisplay)) {
982 return Error::BAD_DISPLAY;
983 }
984
Yichi Chen8366f562019-03-25 19:44:06 +0800985 if (region.isRect() && mVisibleRegion.isRect() &&
986 (region.getBounds() == mVisibleRegion.getBounds())) {
Peiyong Line9d809e2020-04-14 13:10:48 -0700987 return Error::NONE;
Yichi Chen8366f562019-03-25 19:44:06 +0800988 }
989 mVisibleRegion = region;
Leon Scroggins III4459bf42022-01-04 13:58:26 -0500990 const auto hwcRects = convertRegionToHwcRects(region);
Lloyd Piquea516c002021-05-07 14:36:58 -0700991 auto intError = mComposer.setLayerVisibleRegion(mDisplay->getId(), mId, hwcRects);
Dan Stoza651bf312015-10-23 17:03:17 -0700992 return static_cast<Error>(intError);
993}
994
995Error Layer::setZOrder(uint32_t z)
996{
Lloyd Piquea516c002021-05-07 14:36:58 -0700997 if (CC_UNLIKELY(!mDisplay)) {
998 return Error::BAD_DISPLAY;
999 }
1000
1001 auto intError = mComposer.setLayerZOrder(mDisplay->getId(), mId, z);
Dan Stoza651bf312015-10-23 17:03:17 -07001002 return static_cast<Error>(intError);
1003}
1004
Peiyong Lin698147a2018-09-14 13:27:18 -07001005// Composer HAL 2.3
1006Error Layer::setColorTransform(const android::mat4& matrix) {
Lloyd Piquea516c002021-05-07 14:36:58 -07001007 if (CC_UNLIKELY(!mDisplay)) {
1008 return Error::BAD_DISPLAY;
1009 }
1010
Peiyong Lin698147a2018-09-14 13:27:18 -07001011 if (matrix == mColorMatrix) {
Peiyong Line9d809e2020-04-14 13:10:48 -07001012 return Error::NONE;
Peiyong Lin698147a2018-09-14 13:27:18 -07001013 }
Lloyd Piquea516c002021-05-07 14:36:58 -07001014 auto intError = mComposer.setLayerColorTransform(mDisplay->getId(), mId, matrix.asArray());
Peiyong Lin04d25872019-04-18 10:26:19 -07001015 Error error = static_cast<Error>(intError);
Peiyong Line9d809e2020-04-14 13:10:48 -07001016 if (error != Error::NONE) {
Peiyong Lin04d25872019-04-18 10:26:19 -07001017 return error;
1018 }
1019 mColorMatrix = matrix;
1020 return error;
Peiyong Lin698147a2018-09-14 13:27:18 -07001021}
Lloyd Pique35d58242018-12-18 16:33:25 -08001022
Lloyd Pique4603f3c2020-02-11 12:06:56 -08001023// Composer HAL 2.4
1024Error Layer::setLayerGenericMetadata(const std::string& name, bool mandatory,
1025 const std::vector<uint8_t>& value) {
Lloyd Piquea516c002021-05-07 14:36:58 -07001026 if (CC_UNLIKELY(!mDisplay)) {
1027 return Error::BAD_DISPLAY;
1028 }
1029
1030 auto intError =
1031 mComposer.setLayerGenericMetadata(mDisplay->getId(), mId, name, mandatory, value);
Lloyd Pique4603f3c2020-02-11 12:06:56 -08001032 return static_cast<Error>(intError);
1033}
1034
Alec Mouricdf6cbc2021-11-01 17:21:15 -07001035// AIDL HAL
Alec Mouri6da0e272022-02-07 12:45:57 -08001036Error Layer::setBrightness(float brightness) {
Alec Mouricdf6cbc2021-11-01 17:21:15 -07001037 if (CC_UNLIKELY(!mDisplay)) {
1038 return Error::BAD_DISPLAY;
1039 }
1040
Alec Mouri6da0e272022-02-07 12:45:57 -08001041 auto intError = mComposer.setLayerBrightness(mDisplay->getId(), mId, brightness);
Alec Mouricdf6cbc2021-11-01 17:21:15 -07001042 return static_cast<Error>(intError);
1043}
1044
Leon Scroggins IIId77d3162022-01-05 10:42:28 -05001045Error Layer::setBlockingRegion(const Region& region) {
1046 if (CC_UNLIKELY(!mDisplay)) {
1047 return Error::BAD_DISPLAY;
1048 }
1049
1050 if (region.isRect() && mBlockingRegion.isRect() &&
1051 (region.getBounds() == mBlockingRegion.getBounds())) {
1052 return Error::NONE;
1053 }
1054 mBlockingRegion = region;
1055 const auto hwcRects = convertRegionToHwcRects(region);
1056 const auto intError = mComposer.setLayerBlockingRegion(mDisplay->getId(), mId, hwcRects);
1057 return static_cast<Error>(intError);
1058}
1059
Sally Qi11dcd582024-08-16 18:11:27 -07001060Error Layer::setLuts(std::vector<Lut>& luts) {
1061 if (CC_UNLIKELY(!mDisplay)) {
1062 return Error::BAD_DISPLAY;
1063 }
1064 const auto intError = mComposer.setLayerLuts(mDisplay->getId(), mId, luts);
1065 return static_cast<Error>(intError);
1066}
1067
Lloyd Pique35d58242018-12-18 16:33:25 -08001068} // namespace impl
Dan Stoza651bf312015-10-23 17:03:17 -07001069} // namespace HWC2
Peiyong Line9d809e2020-04-14 13:10:48 -07001070} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001071
1072// TODO(b/129481165): remove the #pragma below and fix conversion issues
1073#pragma clang diagnostic pop // ignored "-Wconversion"