xref: /aosp_15_r20/external/drm_hwcomposer/hwc3/ComposerClient.cpp (revision 0a9764fe0a15e71ebbeb85e87e10990c23aab47f)
1*0a9764feSAndroid Build Coastguard Worker /*
2*0a9764feSAndroid Build Coastguard Worker  * Copyright (C) 2024 The Android Open Source Project
3*0a9764feSAndroid Build Coastguard Worker  *
4*0a9764feSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*0a9764feSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*0a9764feSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*0a9764feSAndroid Build Coastguard Worker  *
8*0a9764feSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*0a9764feSAndroid Build Coastguard Worker  *
10*0a9764feSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*0a9764feSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*0a9764feSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*0a9764feSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*0a9764feSAndroid Build Coastguard Worker  * limitations under the License.
15*0a9764feSAndroid Build Coastguard Worker  */
16*0a9764feSAndroid Build Coastguard Worker 
17*0a9764feSAndroid Build Coastguard Worker #define LOG_TAG "drmhwc"
18*0a9764feSAndroid Build Coastguard Worker #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
19*0a9764feSAndroid Build Coastguard Worker 
20*0a9764feSAndroid Build Coastguard Worker #include "ComposerClient.h"
21*0a9764feSAndroid Build Coastguard Worker 
22*0a9764feSAndroid Build Coastguard Worker #include <cinttypes>
23*0a9764feSAndroid Build Coastguard Worker #include <cmath>
24*0a9764feSAndroid Build Coastguard Worker #include <memory>
25*0a9764feSAndroid Build Coastguard Worker #include <unordered_map>
26*0a9764feSAndroid Build Coastguard Worker #include <vector>
27*0a9764feSAndroid Build Coastguard Worker 
28*0a9764feSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/common/Transform.h>
29*0a9764feSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/ClientTarget.h>
30*0a9764feSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/Composition.h>
31*0a9764feSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/DisplayRequest.h>
32*0a9764feSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
33*0a9764feSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/Luts.h>
34*0a9764feSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/PowerMode.h>
35*0a9764feSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/PresentOrValidate.h>
36*0a9764feSAndroid Build Coastguard Worker #include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
37*0a9764feSAndroid Build Coastguard Worker #include <aidlcommonsupport/NativeHandle.h>
38*0a9764feSAndroid Build Coastguard Worker #include <android-base/logging.h>
39*0a9764feSAndroid Build Coastguard Worker #include <android/binder_auto_utils.h>
40*0a9764feSAndroid Build Coastguard Worker #include <android/binder_ibinder_platform.h>
41*0a9764feSAndroid Build Coastguard Worker #include <cutils/native_handle.h>
42*0a9764feSAndroid Build Coastguard Worker #include <hardware/hwcomposer2.h>
43*0a9764feSAndroid Build Coastguard Worker #include <hardware/hwcomposer_defs.h>
44*0a9764feSAndroid Build Coastguard Worker 
45*0a9764feSAndroid Build Coastguard Worker #include "bufferinfo/BufferInfo.h"
46*0a9764feSAndroid Build Coastguard Worker #include "compositor/DisplayInfo.h"
47*0a9764feSAndroid Build Coastguard Worker #include "hwc2_device/HwcDisplay.h"
48*0a9764feSAndroid Build Coastguard Worker #include "hwc2_device/HwcDisplayConfigs.h"
49*0a9764feSAndroid Build Coastguard Worker #include "hwc2_device/HwcLayer.h"
50*0a9764feSAndroid Build Coastguard Worker #include "hwc3/DrmHwcThree.h"
51*0a9764feSAndroid Build Coastguard Worker #include "hwc3/Utils.h"
52*0a9764feSAndroid Build Coastguard Worker 
53*0a9764feSAndroid Build Coastguard Worker using ::android::HwcDisplay;
54*0a9764feSAndroid Build Coastguard Worker using ::android::HwcDisplayConfig;
55*0a9764feSAndroid Build Coastguard Worker using ::android::HwcDisplayConfigs;
56*0a9764feSAndroid Build Coastguard Worker using ::android::HwcLayer;
57*0a9764feSAndroid Build Coastguard Worker using ::android::LayerTransform;
58*0a9764feSAndroid Build Coastguard Worker 
59*0a9764feSAndroid Build Coastguard Worker #include "utils/log.h"
60*0a9764feSAndroid Build Coastguard Worker 
61*0a9764feSAndroid Build Coastguard Worker namespace aidl::android::hardware::graphics::composer3::impl {
62*0a9764feSAndroid Build Coastguard Worker namespace {
63*0a9764feSAndroid Build Coastguard Worker 
64*0a9764feSAndroid Build Coastguard Worker // clang-format off
65*0a9764feSAndroid Build Coastguard Worker constexpr std::array<float, 16> kIdentityMatrix = {
66*0a9764feSAndroid Build Coastguard Worker     1.0F, 0.0F, 0.0F, 0.0F,
67*0a9764feSAndroid Build Coastguard Worker     0.0F, 1.0F, 0.0F, 0.0F,
68*0a9764feSAndroid Build Coastguard Worker     0.0F, 0.0F, 1.0F, 0.0F,
69*0a9764feSAndroid Build Coastguard Worker     0.0F, 0.0F, 0.0F, 1.0F,
70*0a9764feSAndroid Build Coastguard Worker };
71*0a9764feSAndroid Build Coastguard Worker // clang-format on
72*0a9764feSAndroid Build Coastguard Worker 
AidlToBlendMode(const std::optional<ParcelableBlendMode> & aidl_blend_mode)73*0a9764feSAndroid Build Coastguard Worker std::optional<BufferBlendMode> AidlToBlendMode(
74*0a9764feSAndroid Build Coastguard Worker     const std::optional<ParcelableBlendMode>& aidl_blend_mode) {
75*0a9764feSAndroid Build Coastguard Worker   if (!aidl_blend_mode) {
76*0a9764feSAndroid Build Coastguard Worker     return std::nullopt;
77*0a9764feSAndroid Build Coastguard Worker   }
78*0a9764feSAndroid Build Coastguard Worker 
79*0a9764feSAndroid Build Coastguard Worker   switch (aidl_blend_mode->blendMode) {
80*0a9764feSAndroid Build Coastguard Worker     case common::BlendMode::NONE:
81*0a9764feSAndroid Build Coastguard Worker       return BufferBlendMode::kNone;
82*0a9764feSAndroid Build Coastguard Worker     case common::BlendMode::PREMULTIPLIED:
83*0a9764feSAndroid Build Coastguard Worker       return BufferBlendMode::kPreMult;
84*0a9764feSAndroid Build Coastguard Worker     case common::BlendMode::COVERAGE:
85*0a9764feSAndroid Build Coastguard Worker       return BufferBlendMode::kCoverage;
86*0a9764feSAndroid Build Coastguard Worker     case common::BlendMode::INVALID:
87*0a9764feSAndroid Build Coastguard Worker       ALOGE("Invalid BlendMode");
88*0a9764feSAndroid Build Coastguard Worker       return std::nullopt;
89*0a9764feSAndroid Build Coastguard Worker   }
90*0a9764feSAndroid Build Coastguard Worker }
91*0a9764feSAndroid Build Coastguard Worker 
AidlToColorSpace(const std::optional<ParcelableDataspace> & dataspace)92*0a9764feSAndroid Build Coastguard Worker std::optional<BufferColorSpace> AidlToColorSpace(
93*0a9764feSAndroid Build Coastguard Worker     const std::optional<ParcelableDataspace>& dataspace) {
94*0a9764feSAndroid Build Coastguard Worker   if (!dataspace) {
95*0a9764feSAndroid Build Coastguard Worker     return std::nullopt;
96*0a9764feSAndroid Build Coastguard Worker   }
97*0a9764feSAndroid Build Coastguard Worker 
98*0a9764feSAndroid Build Coastguard Worker   int32_t standard = static_cast<int32_t>(dataspace->dataspace) &
99*0a9764feSAndroid Build Coastguard Worker                      static_cast<int32_t>(common::Dataspace::STANDARD_MASK);
100*0a9764feSAndroid Build Coastguard Worker   switch (standard) {
101*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::STANDARD_BT709):
102*0a9764feSAndroid Build Coastguard Worker       return BufferColorSpace::kItuRec709;
103*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::STANDARD_BT601_625):
104*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::STANDARD_BT601_625_UNADJUSTED):
105*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::STANDARD_BT601_525):
106*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::STANDARD_BT601_525_UNADJUSTED):
107*0a9764feSAndroid Build Coastguard Worker       return BufferColorSpace::kItuRec601;
108*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::STANDARD_BT2020):
109*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(
110*0a9764feSAndroid Build Coastguard Worker         common::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE):
111*0a9764feSAndroid Build Coastguard Worker       return BufferColorSpace::kItuRec2020;
112*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::UNKNOWN):
113*0a9764feSAndroid Build Coastguard Worker       return BufferColorSpace::kUndefined;
114*0a9764feSAndroid Build Coastguard Worker     default:
115*0a9764feSAndroid Build Coastguard Worker       ALOGE("Unsupported standard: %d", standard);
116*0a9764feSAndroid Build Coastguard Worker       return std::nullopt;
117*0a9764feSAndroid Build Coastguard Worker   }
118*0a9764feSAndroid Build Coastguard Worker }
119*0a9764feSAndroid Build Coastguard Worker 
AidlToSampleRange(const std::optional<ParcelableDataspace> & dataspace)120*0a9764feSAndroid Build Coastguard Worker std::optional<BufferSampleRange> AidlToSampleRange(
121*0a9764feSAndroid Build Coastguard Worker     const std::optional<ParcelableDataspace>& dataspace) {
122*0a9764feSAndroid Build Coastguard Worker   if (!dataspace) {
123*0a9764feSAndroid Build Coastguard Worker     return std::nullopt;
124*0a9764feSAndroid Build Coastguard Worker   }
125*0a9764feSAndroid Build Coastguard Worker 
126*0a9764feSAndroid Build Coastguard Worker   int32_t sample_range = static_cast<int32_t>(dataspace->dataspace) &
127*0a9764feSAndroid Build Coastguard Worker                          static_cast<int32_t>(common::Dataspace::RANGE_MASK);
128*0a9764feSAndroid Build Coastguard Worker   switch (sample_range) {
129*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::RANGE_FULL):
130*0a9764feSAndroid Build Coastguard Worker       return BufferSampleRange::kFullRange;
131*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::RANGE_LIMITED):
132*0a9764feSAndroid Build Coastguard Worker       return BufferSampleRange::kLimitedRange;
133*0a9764feSAndroid Build Coastguard Worker     case static_cast<int32_t>(common::Dataspace::UNKNOWN):
134*0a9764feSAndroid Build Coastguard Worker       return BufferSampleRange::kUndefined;
135*0a9764feSAndroid Build Coastguard Worker     default:
136*0a9764feSAndroid Build Coastguard Worker       ALOGE("Unsupported sample range: %d", sample_range);
137*0a9764feSAndroid Build Coastguard Worker       return std::nullopt;
138*0a9764feSAndroid Build Coastguard Worker   }
139*0a9764feSAndroid Build Coastguard Worker }
140*0a9764feSAndroid Build Coastguard Worker 
IsSupportedCompositionType(const std::optional<ParcelableComposition> composition)141*0a9764feSAndroid Build Coastguard Worker bool IsSupportedCompositionType(
142*0a9764feSAndroid Build Coastguard Worker     const std::optional<ParcelableComposition> composition) {
143*0a9764feSAndroid Build Coastguard Worker   if (!composition) {
144*0a9764feSAndroid Build Coastguard Worker     return true;
145*0a9764feSAndroid Build Coastguard Worker   }
146*0a9764feSAndroid Build Coastguard Worker   switch (composition->composition) {
147*0a9764feSAndroid Build Coastguard Worker     case Composition::INVALID:
148*0a9764feSAndroid Build Coastguard Worker     case Composition::CLIENT:
149*0a9764feSAndroid Build Coastguard Worker     case Composition::DEVICE:
150*0a9764feSAndroid Build Coastguard Worker     case Composition::SOLID_COLOR:
151*0a9764feSAndroid Build Coastguard Worker     case Composition::CURSOR:
152*0a9764feSAndroid Build Coastguard Worker       return true;
153*0a9764feSAndroid Build Coastguard Worker 
154*0a9764feSAndroid Build Coastguard Worker     // Unsupported composition types. Set an error for the current
155*0a9764feSAndroid Build Coastguard Worker     // DisplayCommand and return.
156*0a9764feSAndroid Build Coastguard Worker     case Composition::DISPLAY_DECORATION:
157*0a9764feSAndroid Build Coastguard Worker     case Composition::SIDEBAND:
158*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ >= 34
159*0a9764feSAndroid Build Coastguard Worker     case Composition::REFRESH_RATE_INDICATOR:
160*0a9764feSAndroid Build Coastguard Worker #endif
161*0a9764feSAndroid Build Coastguard Worker       return false;
162*0a9764feSAndroid Build Coastguard Worker   }
163*0a9764feSAndroid Build Coastguard Worker }
164*0a9764feSAndroid Build Coastguard Worker 
ValidateLayerBrightness(const std::optional<LayerBrightness> & brightness)165*0a9764feSAndroid Build Coastguard Worker bool ValidateLayerBrightness(const std::optional<LayerBrightness>& brightness) {
166*0a9764feSAndroid Build Coastguard Worker   if (!brightness) {
167*0a9764feSAndroid Build Coastguard Worker     return true;
168*0a9764feSAndroid Build Coastguard Worker   }
169*0a9764feSAndroid Build Coastguard Worker   return !(std::signbit(brightness->brightness) ||
170*0a9764feSAndroid Build Coastguard Worker            std::isnan(brightness->brightness));
171*0a9764feSAndroid Build Coastguard Worker }
172*0a9764feSAndroid Build Coastguard Worker 
AidlToCompositionType(const std::optional<ParcelableComposition> composition)173*0a9764feSAndroid Build Coastguard Worker std::optional<HWC2::Composition> AidlToCompositionType(
174*0a9764feSAndroid Build Coastguard Worker     const std::optional<ParcelableComposition> composition) {
175*0a9764feSAndroid Build Coastguard Worker   if (!composition) {
176*0a9764feSAndroid Build Coastguard Worker     return std::nullopt;
177*0a9764feSAndroid Build Coastguard Worker   }
178*0a9764feSAndroid Build Coastguard Worker 
179*0a9764feSAndroid Build Coastguard Worker   switch (composition->composition) {
180*0a9764feSAndroid Build Coastguard Worker     case Composition::INVALID:
181*0a9764feSAndroid Build Coastguard Worker       return HWC2::Composition::Invalid;
182*0a9764feSAndroid Build Coastguard Worker     case Composition::CLIENT:
183*0a9764feSAndroid Build Coastguard Worker       return HWC2::Composition::Client;
184*0a9764feSAndroid Build Coastguard Worker     case Composition::DEVICE:
185*0a9764feSAndroid Build Coastguard Worker       return HWC2::Composition::Device;
186*0a9764feSAndroid Build Coastguard Worker     case Composition::SOLID_COLOR:
187*0a9764feSAndroid Build Coastguard Worker       return HWC2::Composition::SolidColor;
188*0a9764feSAndroid Build Coastguard Worker     case Composition::CURSOR:
189*0a9764feSAndroid Build Coastguard Worker       return HWC2::Composition::Cursor;
190*0a9764feSAndroid Build Coastguard Worker 
191*0a9764feSAndroid Build Coastguard Worker     // Unsupported composition types.
192*0a9764feSAndroid Build Coastguard Worker     case Composition::DISPLAY_DECORATION:
193*0a9764feSAndroid Build Coastguard Worker     case Composition::SIDEBAND:
194*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ >= 34
195*0a9764feSAndroid Build Coastguard Worker     case Composition::REFRESH_RATE_INDICATOR:
196*0a9764feSAndroid Build Coastguard Worker #endif
197*0a9764feSAndroid Build Coastguard Worker       ALOGE("Unsupported composition type: %s",
198*0a9764feSAndroid Build Coastguard Worker             toString(composition->composition).c_str());
199*0a9764feSAndroid Build Coastguard Worker       return std::nullopt;
200*0a9764feSAndroid Build Coastguard Worker   }
201*0a9764feSAndroid Build Coastguard Worker }
202*0a9764feSAndroid Build Coastguard Worker 
203*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ < 35
204*0a9764feSAndroid Build Coastguard Worker 
205*0a9764feSAndroid Build Coastguard Worker class DisplayConfiguration {
206*0a9764feSAndroid Build Coastguard Worker  public:
207*0a9764feSAndroid Build Coastguard Worker   class Dpi {
208*0a9764feSAndroid Build Coastguard Worker    public:
209*0a9764feSAndroid Build Coastguard Worker     float x = 0.000000F;
210*0a9764feSAndroid Build Coastguard Worker     float y = 0.000000F;
211*0a9764feSAndroid Build Coastguard Worker   };
212*0a9764feSAndroid Build Coastguard Worker   // NOLINTNEXTLINE(readability-identifier-naming)
213*0a9764feSAndroid Build Coastguard Worker   int32_t configId = 0;
214*0a9764feSAndroid Build Coastguard Worker   int32_t width = 0;
215*0a9764feSAndroid Build Coastguard Worker   int32_t height = 0;
216*0a9764feSAndroid Build Coastguard Worker   std::optional<Dpi> dpi;
217*0a9764feSAndroid Build Coastguard Worker   // NOLINTNEXTLINE(readability-identifier-naming)
218*0a9764feSAndroid Build Coastguard Worker   int32_t configGroup = 0;
219*0a9764feSAndroid Build Coastguard Worker   // NOLINTNEXTLINE(readability-identifier-naming)
220*0a9764feSAndroid Build Coastguard Worker   int32_t vsyncPeriod = 0;
221*0a9764feSAndroid Build Coastguard Worker };
222*0a9764feSAndroid Build Coastguard Worker 
223*0a9764feSAndroid Build Coastguard Worker #endif
224*0a9764feSAndroid Build Coastguard Worker 
HwcDisplayConfigToAidlConfiguration(const HwcDisplayConfigs & configs,const HwcDisplayConfig & config)225*0a9764feSAndroid Build Coastguard Worker DisplayConfiguration HwcDisplayConfigToAidlConfiguration(
226*0a9764feSAndroid Build Coastguard Worker     const HwcDisplayConfigs& configs, const HwcDisplayConfig& config) {
227*0a9764feSAndroid Build Coastguard Worker   DisplayConfiguration aidl_configuration =
228*0a9764feSAndroid Build Coastguard Worker       {.configId = static_cast<int32_t>(config.id),
229*0a9764feSAndroid Build Coastguard Worker        .width = config.mode.GetRawMode().hdisplay,
230*0a9764feSAndroid Build Coastguard Worker        .height = config.mode.GetRawMode().vdisplay,
231*0a9764feSAndroid Build Coastguard Worker        .configGroup = static_cast<int32_t>(config.group_id),
232*0a9764feSAndroid Build Coastguard Worker        .vsyncPeriod = config.mode.GetVSyncPeriodNs()};
233*0a9764feSAndroid Build Coastguard Worker 
234*0a9764feSAndroid Build Coastguard Worker   if (configs.mm_width != 0) {
235*0a9764feSAndroid Build Coastguard Worker     // ideally this should be vdisplay/mm_heigth, however mm_height
236*0a9764feSAndroid Build Coastguard Worker     // comes from edid parsing and is highly unreliable. Viewing the
237*0a9764feSAndroid Build Coastguard Worker     // rarity of anisotropic displays, falling back to a single value
238*0a9764feSAndroid Build Coastguard Worker     // for dpi yield more correct output.
239*0a9764feSAndroid Build Coastguard Worker     static const float kMmPerInch = 25.4;
240*0a9764feSAndroid Build Coastguard Worker     float dpi = float(config.mode.GetRawMode().hdisplay) * kMmPerInch /
241*0a9764feSAndroid Build Coastguard Worker                 float(configs.mm_width);
242*0a9764feSAndroid Build Coastguard Worker     aidl_configuration.dpi = {.x = dpi, .y = dpi};
243*0a9764feSAndroid Build Coastguard Worker   }
244*0a9764feSAndroid Build Coastguard Worker   // TODO: Populate vrrConfig.
245*0a9764feSAndroid Build Coastguard Worker   return aidl_configuration;
246*0a9764feSAndroid Build Coastguard Worker }
247*0a9764feSAndroid Build Coastguard Worker 
AidlToRect(const std::optional<common::Rect> & rect)248*0a9764feSAndroid Build Coastguard Worker std::optional<hwc_rect> AidlToRect(const std::optional<common::Rect>& rect) {
249*0a9764feSAndroid Build Coastguard Worker   if (!rect) {
250*0a9764feSAndroid Build Coastguard Worker     return std::nullopt;
251*0a9764feSAndroid Build Coastguard Worker   }
252*0a9764feSAndroid Build Coastguard Worker   return hwc_rect{rect->left, rect->top, rect->right, rect->bottom};
253*0a9764feSAndroid Build Coastguard Worker }
254*0a9764feSAndroid Build Coastguard Worker 
AidlToFRect(const std::optional<common::FRect> & rect)255*0a9764feSAndroid Build Coastguard Worker std::optional<hwc_frect> AidlToFRect(const std::optional<common::FRect>& rect) {
256*0a9764feSAndroid Build Coastguard Worker   if (!rect) {
257*0a9764feSAndroid Build Coastguard Worker     return std::nullopt;
258*0a9764feSAndroid Build Coastguard Worker   }
259*0a9764feSAndroid Build Coastguard Worker   return hwc_frect{rect->left, rect->top, rect->right, rect->bottom};
260*0a9764feSAndroid Build Coastguard Worker }
261*0a9764feSAndroid Build Coastguard Worker 
AidlToAlpha(const std::optional<PlaneAlpha> & alpha)262*0a9764feSAndroid Build Coastguard Worker std::optional<float> AidlToAlpha(const std::optional<PlaneAlpha>& alpha) {
263*0a9764feSAndroid Build Coastguard Worker   if (!alpha) {
264*0a9764feSAndroid Build Coastguard Worker     return std::nullopt;
265*0a9764feSAndroid Build Coastguard Worker   }
266*0a9764feSAndroid Build Coastguard Worker   return alpha->alpha;
267*0a9764feSAndroid Build Coastguard Worker }
268*0a9764feSAndroid Build Coastguard Worker 
AidlToZOrder(const std::optional<ZOrder> & z_order)269*0a9764feSAndroid Build Coastguard Worker std::optional<uint32_t> AidlToZOrder(const std::optional<ZOrder>& z_order) {
270*0a9764feSAndroid Build Coastguard Worker   if (!z_order) {
271*0a9764feSAndroid Build Coastguard Worker     return std::nullopt;
272*0a9764feSAndroid Build Coastguard Worker   }
273*0a9764feSAndroid Build Coastguard Worker   return z_order->z;
274*0a9764feSAndroid Build Coastguard Worker }
275*0a9764feSAndroid Build Coastguard Worker 
AidlToLayerTransform(const std::optional<ParcelableTransform> & aidl_transform)276*0a9764feSAndroid Build Coastguard Worker std::optional<LayerTransform> AidlToLayerTransform(
277*0a9764feSAndroid Build Coastguard Worker     const std::optional<ParcelableTransform>& aidl_transform) {
278*0a9764feSAndroid Build Coastguard Worker   if (!aidl_transform) {
279*0a9764feSAndroid Build Coastguard Worker     return std::nullopt;
280*0a9764feSAndroid Build Coastguard Worker   }
281*0a9764feSAndroid Build Coastguard Worker 
282*0a9764feSAndroid Build Coastguard Worker   uint32_t transform = LayerTransform::kIdentity;
283*0a9764feSAndroid Build Coastguard Worker   // 270* and 180* cannot be combined with flips. More specifically, they
284*0a9764feSAndroid Build Coastguard Worker   // already contain both horizontal and vertical flips, so those fields are
285*0a9764feSAndroid Build Coastguard Worker   // redundant in this case. 90* rotation can be combined with either horizontal
286*0a9764feSAndroid Build Coastguard Worker   // flip or vertical flip, so treat it differently
287*0a9764feSAndroid Build Coastguard Worker   if (aidl_transform->transform == common::Transform::ROT_270) {
288*0a9764feSAndroid Build Coastguard Worker     transform = LayerTransform::kRotate270;
289*0a9764feSAndroid Build Coastguard Worker   } else if (aidl_transform->transform == common::Transform::ROT_180) {
290*0a9764feSAndroid Build Coastguard Worker     transform = LayerTransform::kRotate180;
291*0a9764feSAndroid Build Coastguard Worker   } else {
292*0a9764feSAndroid Build Coastguard Worker     auto aidl_transform_bits = static_cast<uint32_t>(aidl_transform->transform);
293*0a9764feSAndroid Build Coastguard Worker     if ((aidl_transform_bits &
294*0a9764feSAndroid Build Coastguard Worker          static_cast<uint32_t>(common::Transform::FLIP_H)) != 0)
295*0a9764feSAndroid Build Coastguard Worker       transform |= LayerTransform::kFlipH;
296*0a9764feSAndroid Build Coastguard Worker     if ((aidl_transform_bits &
297*0a9764feSAndroid Build Coastguard Worker          static_cast<uint32_t>(common::Transform::FLIP_V)) != 0)
298*0a9764feSAndroid Build Coastguard Worker       transform |= LayerTransform::kFlipV;
299*0a9764feSAndroid Build Coastguard Worker     if ((aidl_transform_bits &
300*0a9764feSAndroid Build Coastguard Worker          static_cast<uint32_t>(common::Transform::ROT_90)) != 0)
301*0a9764feSAndroid Build Coastguard Worker       transform |= LayerTransform::kRotate90;
302*0a9764feSAndroid Build Coastguard Worker   }
303*0a9764feSAndroid Build Coastguard Worker   return static_cast<LayerTransform>(transform);
304*0a9764feSAndroid Build Coastguard Worker }
305*0a9764feSAndroid Build Coastguard Worker 
306*0a9764feSAndroid Build Coastguard Worker }  // namespace
307*0a9764feSAndroid Build Coastguard Worker 
ComposerClient()308*0a9764feSAndroid Build Coastguard Worker ComposerClient::ComposerClient() {
309*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
310*0a9764feSAndroid Build Coastguard Worker }
311*0a9764feSAndroid Build Coastguard Worker 
Init()312*0a9764feSAndroid Build Coastguard Worker bool ComposerClient::Init() {
313*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
314*0a9764feSAndroid Build Coastguard Worker   composer_resources_ = ComposerResources::Create();
315*0a9764feSAndroid Build Coastguard Worker   if (composer_resources_) {
316*0a9764feSAndroid Build Coastguard Worker     hwc_ = std::make_unique<DrmHwcThree>(composer_resources_.get());
317*0a9764feSAndroid Build Coastguard Worker   }
318*0a9764feSAndroid Build Coastguard Worker   return composer_resources_ != nullptr;
319*0a9764feSAndroid Build Coastguard Worker }
320*0a9764feSAndroid Build Coastguard Worker 
~ComposerClient()321*0a9764feSAndroid Build Coastguard Worker ComposerClient::~ComposerClient() {
322*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
323*0a9764feSAndroid Build Coastguard Worker   {
324*0a9764feSAndroid Build Coastguard Worker     // First Deinit the displays to start shutting down the Display's dependent
325*0a9764feSAndroid Build Coastguard Worker     // threads such as VSyncWorker.
326*0a9764feSAndroid Build Coastguard Worker     const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
327*0a9764feSAndroid Build Coastguard Worker     hwc_->DeinitDisplays();
328*0a9764feSAndroid Build Coastguard Worker   }
329*0a9764feSAndroid Build Coastguard Worker   // Sleep to wait for threads to complete and exit.
330*0a9764feSAndroid Build Coastguard Worker   const int time_for_threads_to_exit_us = 200000;
331*0a9764feSAndroid Build Coastguard Worker   usleep(time_for_threads_to_exit_us);
332*0a9764feSAndroid Build Coastguard Worker   {
333*0a9764feSAndroid Build Coastguard Worker     // Hold the lock while destructing the hwc_ and the objects that it owns.
334*0a9764feSAndroid Build Coastguard Worker     const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
335*0a9764feSAndroid Build Coastguard Worker     hwc_.reset();
336*0a9764feSAndroid Build Coastguard Worker   }
337*0a9764feSAndroid Build Coastguard Worker   LOG(DEBUG) << "removed composer client";
338*0a9764feSAndroid Build Coastguard Worker }
339*0a9764feSAndroid Build Coastguard Worker 
createLayer(int64_t display_id,int32_t buffer_slot_count,int64_t * layer_id)340*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::createLayer(int64_t display_id,
341*0a9764feSAndroid Build Coastguard Worker                                                int32_t buffer_slot_count,
342*0a9764feSAndroid Build Coastguard Worker                                                int64_t* layer_id) {
343*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
344*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
345*0a9764feSAndroid Build Coastguard Worker 
346*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
347*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
348*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
349*0a9764feSAndroid Build Coastguard Worker   }
350*0a9764feSAndroid Build Coastguard Worker 
351*0a9764feSAndroid Build Coastguard Worker   hwc2_layer_t hwc2_layer_id = 0;
352*0a9764feSAndroid Build Coastguard Worker   auto err = Hwc2toHwc3Error(display->CreateLayer(&hwc2_layer_id));
353*0a9764feSAndroid Build Coastguard Worker   if (err != hwc3::Error::kNone) {
354*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(err);
355*0a9764feSAndroid Build Coastguard Worker   }
356*0a9764feSAndroid Build Coastguard Worker 
357*0a9764feSAndroid Build Coastguard Worker   const int64_t created_layer_id = Hwc2LayerToHwc3(hwc2_layer_id);
358*0a9764feSAndroid Build Coastguard Worker   err = composer_resources_->AddLayer(display_id, created_layer_id,
359*0a9764feSAndroid Build Coastguard Worker                                       buffer_slot_count);
360*0a9764feSAndroid Build Coastguard Worker   if (err != hwc3::Error::kNone) {
361*0a9764feSAndroid Build Coastguard Worker     destroyLayer(display_id, created_layer_id);
362*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(err);
363*0a9764feSAndroid Build Coastguard Worker   }
364*0a9764feSAndroid Build Coastguard Worker 
365*0a9764feSAndroid Build Coastguard Worker   *layer_id = created_layer_id;
366*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
367*0a9764feSAndroid Build Coastguard Worker }
368*0a9764feSAndroid Build Coastguard Worker 
createVirtualDisplay(int32_t width,int32_t height,AidlPixelFormat format_hint,int32_t output_buffer_slot_count,VirtualDisplay * out_display)369*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::createVirtualDisplay(
370*0a9764feSAndroid Build Coastguard Worker     int32_t width, int32_t height, AidlPixelFormat format_hint,
371*0a9764feSAndroid Build Coastguard Worker     int32_t output_buffer_slot_count, VirtualDisplay* out_display) {
372*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
373*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
374*0a9764feSAndroid Build Coastguard Worker 
375*0a9764feSAndroid Build Coastguard Worker   hwc2_display_t hwc2_display_id = 0;
376*0a9764feSAndroid Build Coastguard Worker   // TODO: Format is currently not used in drm_hwcomposer.
377*0a9764feSAndroid Build Coastguard Worker   int32_t hwc2_format = 0;
378*0a9764feSAndroid Build Coastguard Worker   auto err = Hwc2toHwc3Error(hwc_->CreateVirtualDisplay(width, height,
379*0a9764feSAndroid Build Coastguard Worker                                                         &hwc2_format,
380*0a9764feSAndroid Build Coastguard Worker                                                         &hwc2_display_id));
381*0a9764feSAndroid Build Coastguard Worker   if (err != hwc3::Error::kNone) {
382*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(err);
383*0a9764feSAndroid Build Coastguard Worker   }
384*0a9764feSAndroid Build Coastguard Worker 
385*0a9764feSAndroid Build Coastguard Worker   const int64_t created_display_id = Hwc2DisplayToHwc3(hwc2_display_id);
386*0a9764feSAndroid Build Coastguard Worker   err = composer_resources_->AddVirtualDisplay(hwc2_display_id,
387*0a9764feSAndroid Build Coastguard Worker                                                output_buffer_slot_count);
388*0a9764feSAndroid Build Coastguard Worker   if (err != hwc3::Error::kNone) {
389*0a9764feSAndroid Build Coastguard Worker     hwc_->DestroyVirtualDisplay(hwc2_display_id);
390*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(err);
391*0a9764feSAndroid Build Coastguard Worker   }
392*0a9764feSAndroid Build Coastguard Worker 
393*0a9764feSAndroid Build Coastguard Worker   out_display->display = created_display_id;
394*0a9764feSAndroid Build Coastguard Worker   out_display->format = format_hint;
395*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
396*0a9764feSAndroid Build Coastguard Worker }
397*0a9764feSAndroid Build Coastguard Worker 
destroyLayer(int64_t display_id,int64_t layer_id)398*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t display_id,
399*0a9764feSAndroid Build Coastguard Worker                                                 int64_t layer_id) {
400*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
401*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
402*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
403*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
404*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
405*0a9764feSAndroid Build Coastguard Worker   }
406*0a9764feSAndroid Build Coastguard Worker 
407*0a9764feSAndroid Build Coastguard Worker   auto err = Hwc2toHwc3Error(display->DestroyLayer(Hwc3LayerToHwc2(layer_id)));
408*0a9764feSAndroid Build Coastguard Worker   if (err != hwc3::Error::kNone) {
409*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(err);
410*0a9764feSAndroid Build Coastguard Worker   }
411*0a9764feSAndroid Build Coastguard Worker 
412*0a9764feSAndroid Build Coastguard Worker   err = composer_resources_->RemoveLayer(display_id, layer_id);
413*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(err);
414*0a9764feSAndroid Build Coastguard Worker }
415*0a9764feSAndroid Build Coastguard Worker 
destroyVirtualDisplay(int64_t display_id)416*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t display_id) {
417*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
418*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
419*0a9764feSAndroid Build Coastguard Worker   auto err = Hwc2toHwc3Error(hwc_->DestroyVirtualDisplay(display_id));
420*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(err);
421*0a9764feSAndroid Build Coastguard Worker }
422*0a9764feSAndroid Build Coastguard Worker 
ValidateDisplayInternal(HwcDisplay & display,std::vector<int64_t> * out_changed_layers,std::vector<Composition> * out_composition_types,int32_t * out_display_request_mask,std::vector<int64_t> * out_requested_layers,std::vector<int32_t> * out_request_masks,ClientTargetProperty *,DimmingStage *)423*0a9764feSAndroid Build Coastguard Worker hwc3::Error ComposerClient::ValidateDisplayInternal(
424*0a9764feSAndroid Build Coastguard Worker     HwcDisplay& display, std::vector<int64_t>* out_changed_layers,
425*0a9764feSAndroid Build Coastguard Worker     std::vector<Composition>* out_composition_types,
426*0a9764feSAndroid Build Coastguard Worker     int32_t* out_display_request_mask,
427*0a9764feSAndroid Build Coastguard Worker     std::vector<int64_t>* out_requested_layers,
428*0a9764feSAndroid Build Coastguard Worker     std::vector<int32_t>* out_request_masks,
429*0a9764feSAndroid Build Coastguard Worker     ClientTargetProperty* /*out_client_target_property*/,
430*0a9764feSAndroid Build Coastguard Worker     DimmingStage* /*out_dimming_stage*/) {
431*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
432*0a9764feSAndroid Build Coastguard Worker 
433*0a9764feSAndroid Build Coastguard Worker   uint32_t num_types = 0;
434*0a9764feSAndroid Build Coastguard Worker   uint32_t num_requests = 0;
435*0a9764feSAndroid Build Coastguard Worker   const HWC2::Error hwc2_error = display.ValidateDisplay(&num_types,
436*0a9764feSAndroid Build Coastguard Worker                                                          &num_requests);
437*0a9764feSAndroid Build Coastguard Worker 
438*0a9764feSAndroid Build Coastguard Worker   /* Check if display has pending changes and no errors */
439*0a9764feSAndroid Build Coastguard Worker   if (hwc2_error != HWC2::Error::None &&
440*0a9764feSAndroid Build Coastguard Worker       hwc2_error != HWC2::Error::HasChanges) {
441*0a9764feSAndroid Build Coastguard Worker     return Hwc2toHwc3Error(hwc2_error);
442*0a9764feSAndroid Build Coastguard Worker   }
443*0a9764feSAndroid Build Coastguard Worker 
444*0a9764feSAndroid Build Coastguard Worker   hwc3::Error error = Hwc2toHwc3Error(
445*0a9764feSAndroid Build Coastguard Worker       display.GetChangedCompositionTypes(&num_types, nullptr, nullptr));
446*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
447*0a9764feSAndroid Build Coastguard Worker     return error;
448*0a9764feSAndroid Build Coastguard Worker   }
449*0a9764feSAndroid Build Coastguard Worker 
450*0a9764feSAndroid Build Coastguard Worker   std::vector<hwc2_layer_t> hwc_changed_layers(num_types);
451*0a9764feSAndroid Build Coastguard Worker   std::vector<int32_t> hwc_composition_types(num_types);
452*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(
453*0a9764feSAndroid Build Coastguard Worker       display.GetChangedCompositionTypes(&num_types, hwc_changed_layers.data(),
454*0a9764feSAndroid Build Coastguard Worker                                          hwc_composition_types.data()));
455*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
456*0a9764feSAndroid Build Coastguard Worker     return error;
457*0a9764feSAndroid Build Coastguard Worker   }
458*0a9764feSAndroid Build Coastguard Worker 
459*0a9764feSAndroid Build Coastguard Worker   int32_t display_reqs = 0;
460*0a9764feSAndroid Build Coastguard Worker   out_request_masks->resize(num_requests);
461*0a9764feSAndroid Build Coastguard Worker   std::vector<hwc2_layer_t> hwc_requested_layers(num_requests);
462*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(
463*0a9764feSAndroid Build Coastguard Worker       display.GetDisplayRequests(&display_reqs, &num_requests,
464*0a9764feSAndroid Build Coastguard Worker                                  hwc_requested_layers.data(),
465*0a9764feSAndroid Build Coastguard Worker                                  out_request_masks->data()));
466*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
467*0a9764feSAndroid Build Coastguard Worker     return error;
468*0a9764feSAndroid Build Coastguard Worker   }
469*0a9764feSAndroid Build Coastguard Worker 
470*0a9764feSAndroid Build Coastguard Worker   for (const auto& layer : hwc_changed_layers) {
471*0a9764feSAndroid Build Coastguard Worker     out_changed_layers->emplace_back(Hwc2LayerToHwc3(layer));
472*0a9764feSAndroid Build Coastguard Worker   }
473*0a9764feSAndroid Build Coastguard Worker   for (const auto& type : hwc_composition_types) {
474*0a9764feSAndroid Build Coastguard Worker     out_composition_types->emplace_back(Hwc2CompositionTypeToHwc3(type));
475*0a9764feSAndroid Build Coastguard Worker   }
476*0a9764feSAndroid Build Coastguard Worker   for (const auto& layer : hwc_requested_layers) {
477*0a9764feSAndroid Build Coastguard Worker     out_requested_layers->emplace_back(Hwc2LayerToHwc3(layer));
478*0a9764feSAndroid Build Coastguard Worker   }
479*0a9764feSAndroid Build Coastguard Worker   *out_display_request_mask = display_reqs;
480*0a9764feSAndroid Build Coastguard Worker 
481*0a9764feSAndroid Build Coastguard Worker   /* Client target property/dimming stage unsupported */
482*0a9764feSAndroid Build Coastguard Worker   return hwc3::Error::kNone;
483*0a9764feSAndroid Build Coastguard Worker }
484*0a9764feSAndroid Build Coastguard Worker 
PresentDisplayInternal(uint64_t display_id,::android::base::unique_fd & out_display_fence,std::unordered_map<int64_t,::android::base::unique_fd> & out_release_fences)485*0a9764feSAndroid Build Coastguard Worker hwc3::Error ComposerClient::PresentDisplayInternal(
486*0a9764feSAndroid Build Coastguard Worker     uint64_t display_id, ::android::base::unique_fd& out_display_fence,
487*0a9764feSAndroid Build Coastguard Worker     std::unordered_map<int64_t, ::android::base::unique_fd>&
488*0a9764feSAndroid Build Coastguard Worker         out_release_fences) {
489*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
490*0a9764feSAndroid Build Coastguard Worker   auto* display = GetDisplay(display_id);
491*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
492*0a9764feSAndroid Build Coastguard Worker     return hwc3::Error::kBadDisplay;
493*0a9764feSAndroid Build Coastguard Worker   }
494*0a9764feSAndroid Build Coastguard Worker 
495*0a9764feSAndroid Build Coastguard Worker   if (composer_resources_->MustValidateDisplay(display_id)) {
496*0a9764feSAndroid Build Coastguard Worker     return hwc3::Error::kNotValidated;
497*0a9764feSAndroid Build Coastguard Worker   }
498*0a9764feSAndroid Build Coastguard Worker 
499*0a9764feSAndroid Build Coastguard Worker   int32_t present_fence = -1;
500*0a9764feSAndroid Build Coastguard Worker   auto error = Hwc2toHwc3Error(display->PresentDisplay(&present_fence));
501*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
502*0a9764feSAndroid Build Coastguard Worker     return error;
503*0a9764feSAndroid Build Coastguard Worker   }
504*0a9764feSAndroid Build Coastguard Worker   out_display_fence.reset(present_fence);
505*0a9764feSAndroid Build Coastguard Worker 
506*0a9764feSAndroid Build Coastguard Worker   uint32_t release_fence_count = 0;
507*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(
508*0a9764feSAndroid Build Coastguard Worker       display->GetReleaseFences(&release_fence_count, nullptr, nullptr));
509*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
510*0a9764feSAndroid Build Coastguard Worker     return error;
511*0a9764feSAndroid Build Coastguard Worker   }
512*0a9764feSAndroid Build Coastguard Worker 
513*0a9764feSAndroid Build Coastguard Worker   std::vector<hwc2_layer_t> hwc_layers(release_fence_count);
514*0a9764feSAndroid Build Coastguard Worker   std::vector<int32_t> hwc_fences(release_fence_count);
515*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(display->GetReleaseFences(&release_fence_count,
516*0a9764feSAndroid Build Coastguard Worker                                                     hwc_layers.data(),
517*0a9764feSAndroid Build Coastguard Worker                                                     hwc_fences.data()));
518*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
519*0a9764feSAndroid Build Coastguard Worker     return error;
520*0a9764feSAndroid Build Coastguard Worker   }
521*0a9764feSAndroid Build Coastguard Worker 
522*0a9764feSAndroid Build Coastguard Worker   for (size_t i = 0; i < hwc_layers.size(); i++) {
523*0a9764feSAndroid Build Coastguard Worker     auto layer = Hwc2LayerToHwc3(hwc_layers[i]);
524*0a9764feSAndroid Build Coastguard Worker     out_release_fences[layer] = ::android::base::unique_fd{hwc_fences[i]};
525*0a9764feSAndroid Build Coastguard Worker   }
526*0a9764feSAndroid Build Coastguard Worker 
527*0a9764feSAndroid Build Coastguard Worker   return hwc3::Error::kNone;
528*0a9764feSAndroid Build Coastguard Worker }
529*0a9764feSAndroid Build Coastguard Worker 
GetDisplay(uint64_t display_id)530*0a9764feSAndroid Build Coastguard Worker ::android::HwcDisplay* ComposerClient::GetDisplay(uint64_t display_id) {
531*0a9764feSAndroid Build Coastguard Worker   return hwc_->GetDisplay(display_id);
532*0a9764feSAndroid Build Coastguard Worker }
533*0a9764feSAndroid Build Coastguard Worker 
DispatchLayerCommand(int64_t display_id,const LayerCommand & command)534*0a9764feSAndroid Build Coastguard Worker void ComposerClient::DispatchLayerCommand(int64_t display_id,
535*0a9764feSAndroid Build Coastguard Worker                                           const LayerCommand& command) {
536*0a9764feSAndroid Build Coastguard Worker   auto* display = GetDisplay(display_id);
537*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
538*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
539*0a9764feSAndroid Build Coastguard Worker     return;
540*0a9764feSAndroid Build Coastguard Worker   }
541*0a9764feSAndroid Build Coastguard Worker 
542*0a9764feSAndroid Build Coastguard Worker   auto* layer = display->get_layer(command.layer);
543*0a9764feSAndroid Build Coastguard Worker   if (layer == nullptr) {
544*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadLayer);
545*0a9764feSAndroid Build Coastguard Worker     return;
546*0a9764feSAndroid Build Coastguard Worker   }
547*0a9764feSAndroid Build Coastguard Worker 
548*0a9764feSAndroid Build Coastguard Worker   // If the requested composition type is not supported, the HWC should return
549*0a9764feSAndroid Build Coastguard Worker   // an error and not process any further commands.
550*0a9764feSAndroid Build Coastguard Worker   if (!IsSupportedCompositionType(command.composition)) {
551*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kUnsupported);
552*0a9764feSAndroid Build Coastguard Worker     return;
553*0a9764feSAndroid Build Coastguard Worker   }
554*0a9764feSAndroid Build Coastguard Worker 
555*0a9764feSAndroid Build Coastguard Worker   // For some invalid parameters, the HWC should return an error and not process
556*0a9764feSAndroid Build Coastguard Worker   // any further commands.
557*0a9764feSAndroid Build Coastguard Worker   if (!ValidateLayerBrightness(command.brightness)) {
558*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadParameter);
559*0a9764feSAndroid Build Coastguard Worker     return;
560*0a9764feSAndroid Build Coastguard Worker   }
561*0a9764feSAndroid Build Coastguard Worker 
562*0a9764feSAndroid Build Coastguard Worker   HwcLayer::LayerProperties properties;
563*0a9764feSAndroid Build Coastguard Worker   if (command.buffer) {
564*0a9764feSAndroid Build Coastguard Worker     HwcLayer::Buffer buffer;
565*0a9764feSAndroid Build Coastguard Worker     auto err = ImportLayerBuffer(display_id, command.layer, *command.buffer,
566*0a9764feSAndroid Build Coastguard Worker                                  &buffer.buffer_handle);
567*0a9764feSAndroid Build Coastguard Worker     if (err != hwc3::Error::kNone) {
568*0a9764feSAndroid Build Coastguard Worker       cmd_result_writer_->AddError(err);
569*0a9764feSAndroid Build Coastguard Worker       return;
570*0a9764feSAndroid Build Coastguard Worker     }
571*0a9764feSAndroid Build Coastguard Worker     buffer.acquire_fence = ::android::MakeSharedFd(
572*0a9764feSAndroid Build Coastguard Worker         command.buffer->fence.dup().release());
573*0a9764feSAndroid Build Coastguard Worker     properties.buffer.emplace(buffer);
574*0a9764feSAndroid Build Coastguard Worker   }
575*0a9764feSAndroid Build Coastguard Worker 
576*0a9764feSAndroid Build Coastguard Worker   properties.blend_mode = AidlToBlendMode(command.blendMode);
577*0a9764feSAndroid Build Coastguard Worker   properties.color_space = AidlToColorSpace(command.dataspace);
578*0a9764feSAndroid Build Coastguard Worker   properties.sample_range = AidlToSampleRange(command.dataspace);
579*0a9764feSAndroid Build Coastguard Worker   properties.composition_type = AidlToCompositionType(command.composition);
580*0a9764feSAndroid Build Coastguard Worker   properties.display_frame = AidlToRect(command.displayFrame);
581*0a9764feSAndroid Build Coastguard Worker   properties.alpha = AidlToAlpha(command.planeAlpha);
582*0a9764feSAndroid Build Coastguard Worker   properties.source_crop = AidlToFRect(command.sourceCrop);
583*0a9764feSAndroid Build Coastguard Worker   properties.transform = AidlToLayerTransform(command.transform);
584*0a9764feSAndroid Build Coastguard Worker   properties.z_order = AidlToZOrder(command.z);
585*0a9764feSAndroid Build Coastguard Worker 
586*0a9764feSAndroid Build Coastguard Worker   layer->SetLayerProperties(properties);
587*0a9764feSAndroid Build Coastguard Worker 
588*0a9764feSAndroid Build Coastguard Worker   // Some unsupported functionality returns kUnsupported, and others
589*0a9764feSAndroid Build Coastguard Worker   // are just a no-op.
590*0a9764feSAndroid Build Coastguard Worker   // TODO: Audit whether some of these should actually return kUnsupported
591*0a9764feSAndroid Build Coastguard Worker   // instead.
592*0a9764feSAndroid Build Coastguard Worker   if (command.sidebandStream) {
593*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kUnsupported);
594*0a9764feSAndroid Build Coastguard Worker   }
595*0a9764feSAndroid Build Coastguard Worker   if (command.luts) {
596*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kUnsupported);
597*0a9764feSAndroid Build Coastguard Worker   }
598*0a9764feSAndroid Build Coastguard Worker   // TODO: Blocking region handling missing.
599*0a9764feSAndroid Build Coastguard Worker   // TODO: Layer surface damage.
600*0a9764feSAndroid Build Coastguard Worker   // TODO: Layer visible region.
601*0a9764feSAndroid Build Coastguard Worker   // TODO: Per-frame metadata.
602*0a9764feSAndroid Build Coastguard Worker   // TODO: Layer color transform.
603*0a9764feSAndroid Build Coastguard Worker   // TODO: Layer cursor position.
604*0a9764feSAndroid Build Coastguard Worker   // TODO: Layer color.
605*0a9764feSAndroid Build Coastguard Worker }
606*0a9764feSAndroid Build Coastguard Worker 
ExecuteDisplayCommand(const DisplayCommand & command)607*0a9764feSAndroid Build Coastguard Worker void ComposerClient::ExecuteDisplayCommand(const DisplayCommand& command) {
608*0a9764feSAndroid Build Coastguard Worker   const int64_t display_id = command.display;
609*0a9764feSAndroid Build Coastguard Worker   if (hwc_->GetDisplay(display_id) == nullptr) {
610*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
611*0a9764feSAndroid Build Coastguard Worker     return;
612*0a9764feSAndroid Build Coastguard Worker   }
613*0a9764feSAndroid Build Coastguard Worker 
614*0a9764feSAndroid Build Coastguard Worker   if (command.brightness) {
615*0a9764feSAndroid Build Coastguard Worker     // TODO: Implement support for display brightness.
616*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kUnsupported);
617*0a9764feSAndroid Build Coastguard Worker     return;
618*0a9764feSAndroid Build Coastguard Worker   }
619*0a9764feSAndroid Build Coastguard Worker 
620*0a9764feSAndroid Build Coastguard Worker   for (const auto& layer_cmd : command.layers) {
621*0a9764feSAndroid Build Coastguard Worker     DispatchLayerCommand(command.display, layer_cmd);
622*0a9764feSAndroid Build Coastguard Worker   }
623*0a9764feSAndroid Build Coastguard Worker 
624*0a9764feSAndroid Build Coastguard Worker   if (command.colorTransformMatrix) {
625*0a9764feSAndroid Build Coastguard Worker     ExecuteSetDisplayColorTransform(command.display,
626*0a9764feSAndroid Build Coastguard Worker                                     *command.colorTransformMatrix);
627*0a9764feSAndroid Build Coastguard Worker   }
628*0a9764feSAndroid Build Coastguard Worker   if (command.clientTarget) {
629*0a9764feSAndroid Build Coastguard Worker     ExecuteSetDisplayClientTarget(command.display, *command.clientTarget);
630*0a9764feSAndroid Build Coastguard Worker   }
631*0a9764feSAndroid Build Coastguard Worker   if (command.virtualDisplayOutputBuffer) {
632*0a9764feSAndroid Build Coastguard Worker     ExecuteSetDisplayOutputBuffer(command.display,
633*0a9764feSAndroid Build Coastguard Worker                                   *command.virtualDisplayOutputBuffer);
634*0a9764feSAndroid Build Coastguard Worker   }
635*0a9764feSAndroid Build Coastguard Worker   if (command.validateDisplay) {
636*0a9764feSAndroid Build Coastguard Worker     ExecuteValidateDisplay(command.display, command.expectedPresentTime);
637*0a9764feSAndroid Build Coastguard Worker   }
638*0a9764feSAndroid Build Coastguard Worker   if (command.acceptDisplayChanges) {
639*0a9764feSAndroid Build Coastguard Worker     ExecuteAcceptDisplayChanges(command.display);
640*0a9764feSAndroid Build Coastguard Worker   }
641*0a9764feSAndroid Build Coastguard Worker   if (command.presentDisplay) {
642*0a9764feSAndroid Build Coastguard Worker     ExecutePresentDisplay(command.display);
643*0a9764feSAndroid Build Coastguard Worker   }
644*0a9764feSAndroid Build Coastguard Worker   if (command.presentOrValidateDisplay) {
645*0a9764feSAndroid Build Coastguard Worker     ExecutePresentOrValidateDisplay(command.display,
646*0a9764feSAndroid Build Coastguard Worker                                     command.expectedPresentTime);
647*0a9764feSAndroid Build Coastguard Worker   }
648*0a9764feSAndroid Build Coastguard Worker }
649*0a9764feSAndroid Build Coastguard Worker 
executeCommands(const std::vector<DisplayCommand> & commands,std::vector<CommandResultPayload> * results)650*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::executeCommands(
651*0a9764feSAndroid Build Coastguard Worker     const std::vector<DisplayCommand>& commands,
652*0a9764feSAndroid Build Coastguard Worker     std::vector<CommandResultPayload>* results) {
653*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
654*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
655*0a9764feSAndroid Build Coastguard Worker   cmd_result_writer_ = std::make_unique<CommandResultWriter>(results);
656*0a9764feSAndroid Build Coastguard Worker   for (const auto& cmd : commands) {
657*0a9764feSAndroid Build Coastguard Worker     ExecuteDisplayCommand(cmd);
658*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->IncrementCommand();
659*0a9764feSAndroid Build Coastguard Worker   }
660*0a9764feSAndroid Build Coastguard Worker   cmd_result_writer_.reset();
661*0a9764feSAndroid Build Coastguard Worker 
662*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
663*0a9764feSAndroid Build Coastguard Worker }
664*0a9764feSAndroid Build Coastguard Worker 
getActiveConfig(int64_t display_id,int32_t * config_id)665*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t display_id,
666*0a9764feSAndroid Build Coastguard Worker                                                    int32_t* config_id) {
667*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
668*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
669*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
670*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
671*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
672*0a9764feSAndroid Build Coastguard Worker   }
673*0a9764feSAndroid Build Coastguard Worker 
674*0a9764feSAndroid Build Coastguard Worker   const HwcDisplayConfig* config = display->GetLastRequestedConfig();
675*0a9764feSAndroid Build Coastguard Worker   if (config == nullptr) {
676*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadConfig);
677*0a9764feSAndroid Build Coastguard Worker   }
678*0a9764feSAndroid Build Coastguard Worker 
679*0a9764feSAndroid Build Coastguard Worker   *config_id = Hwc2ConfigIdToHwc3(config->id);
680*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
681*0a9764feSAndroid Build Coastguard Worker }
682*0a9764feSAndroid Build Coastguard Worker 
getColorModes(int64_t display_id,std::vector<ColorMode> * color_modes)683*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getColorModes(
684*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, std::vector<ColorMode>* color_modes) {
685*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
686*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
687*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
688*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
689*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
690*0a9764feSAndroid Build Coastguard Worker   }
691*0a9764feSAndroid Build Coastguard Worker 
692*0a9764feSAndroid Build Coastguard Worker   uint32_t num_modes = 0;
693*0a9764feSAndroid Build Coastguard Worker   auto error = Hwc2toHwc3Error(display->GetColorModes(&num_modes, nullptr));
694*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
695*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
696*0a9764feSAndroid Build Coastguard Worker   }
697*0a9764feSAndroid Build Coastguard Worker 
698*0a9764feSAndroid Build Coastguard Worker   std::vector<int32_t> hwc2_color_modes(num_modes);
699*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(
700*0a9764feSAndroid Build Coastguard Worker       display->GetColorModes(&num_modes, hwc2_color_modes.data()));
701*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
702*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
703*0a9764feSAndroid Build Coastguard Worker   }
704*0a9764feSAndroid Build Coastguard Worker 
705*0a9764feSAndroid Build Coastguard Worker   for (const auto& mode : hwc2_color_modes) {
706*0a9764feSAndroid Build Coastguard Worker     color_modes->push_back(Hwc2ColorModeToHwc3(mode));
707*0a9764feSAndroid Build Coastguard Worker   }
708*0a9764feSAndroid Build Coastguard Worker 
709*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
710*0a9764feSAndroid Build Coastguard Worker }
711*0a9764feSAndroid Build Coastguard Worker 
getDataspaceSaturationMatrix(common::Dataspace dataspace,std::vector<float> * matrix)712*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDataspaceSaturationMatrix(
713*0a9764feSAndroid Build Coastguard Worker     common::Dataspace dataspace, std::vector<float>* matrix) {
714*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
715*0a9764feSAndroid Build Coastguard Worker   if (dataspace != common::Dataspace::SRGB_LINEAR) {
716*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadParameter);
717*0a9764feSAndroid Build Coastguard Worker   }
718*0a9764feSAndroid Build Coastguard Worker 
719*0a9764feSAndroid Build Coastguard Worker   matrix->clear();
720*0a9764feSAndroid Build Coastguard Worker   matrix->insert(matrix->begin(), kIdentityMatrix.begin(),
721*0a9764feSAndroid Build Coastguard Worker                  kIdentityMatrix.end());
722*0a9764feSAndroid Build Coastguard Worker 
723*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
724*0a9764feSAndroid Build Coastguard Worker }
725*0a9764feSAndroid Build Coastguard Worker 
getDisplayAttribute(int64_t display_id,int32_t config_id,DisplayAttribute attribute,int32_t * value)726*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayAttribute(
727*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, int32_t config_id, DisplayAttribute attribute,
728*0a9764feSAndroid Build Coastguard Worker     int32_t* value) {
729*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
730*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
731*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
732*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
733*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
734*0a9764feSAndroid Build Coastguard Worker   }
735*0a9764feSAndroid Build Coastguard Worker 
736*0a9764feSAndroid Build Coastguard Worker   const HwcDisplayConfigs& configs = display->GetDisplayConfigs();
737*0a9764feSAndroid Build Coastguard Worker   auto config = configs.hwc_configs.find(config_id);
738*0a9764feSAndroid Build Coastguard Worker   if (config == configs.hwc_configs.end()) {
739*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadConfig);
740*0a9764feSAndroid Build Coastguard Worker   }
741*0a9764feSAndroid Build Coastguard Worker 
742*0a9764feSAndroid Build Coastguard Worker   DisplayConfiguration
743*0a9764feSAndroid Build Coastguard Worker       aidl_configuration = HwcDisplayConfigToAidlConfiguration(configs,
744*0a9764feSAndroid Build Coastguard Worker                                                                config->second);
745*0a9764feSAndroid Build Coastguard Worker   // Legacy API for querying DPI uses units of dots per 1000 inches.
746*0a9764feSAndroid Build Coastguard Worker   static const int kLegacyDpiUnit = 1000;
747*0a9764feSAndroid Build Coastguard Worker   switch (attribute) {
748*0a9764feSAndroid Build Coastguard Worker     case DisplayAttribute::WIDTH:
749*0a9764feSAndroid Build Coastguard Worker       *value = aidl_configuration.width;
750*0a9764feSAndroid Build Coastguard Worker       break;
751*0a9764feSAndroid Build Coastguard Worker     case DisplayAttribute::HEIGHT:
752*0a9764feSAndroid Build Coastguard Worker       *value = aidl_configuration.height;
753*0a9764feSAndroid Build Coastguard Worker       break;
754*0a9764feSAndroid Build Coastguard Worker     case DisplayAttribute::VSYNC_PERIOD:
755*0a9764feSAndroid Build Coastguard Worker       *value = aidl_configuration.vsyncPeriod;
756*0a9764feSAndroid Build Coastguard Worker       break;
757*0a9764feSAndroid Build Coastguard Worker     case DisplayAttribute::DPI_X:
758*0a9764feSAndroid Build Coastguard Worker       *value = aidl_configuration.dpi
759*0a9764feSAndroid Build Coastguard Worker                    ? static_cast<int>(aidl_configuration.dpi->x *
760*0a9764feSAndroid Build Coastguard Worker                                       kLegacyDpiUnit)
761*0a9764feSAndroid Build Coastguard Worker                    : -1;
762*0a9764feSAndroid Build Coastguard Worker       break;
763*0a9764feSAndroid Build Coastguard Worker     case DisplayAttribute::DPI_Y:
764*0a9764feSAndroid Build Coastguard Worker       *value = aidl_configuration.dpi
765*0a9764feSAndroid Build Coastguard Worker                    ? static_cast<int>(aidl_configuration.dpi->y *
766*0a9764feSAndroid Build Coastguard Worker                                       kLegacyDpiUnit)
767*0a9764feSAndroid Build Coastguard Worker                    : -1;
768*0a9764feSAndroid Build Coastguard Worker       break;
769*0a9764feSAndroid Build Coastguard Worker     case DisplayAttribute::CONFIG_GROUP:
770*0a9764feSAndroid Build Coastguard Worker       *value = aidl_configuration.configGroup;
771*0a9764feSAndroid Build Coastguard Worker       break;
772*0a9764feSAndroid Build Coastguard Worker     case DisplayAttribute::INVALID:
773*0a9764feSAndroid Build Coastguard Worker       return ToBinderStatus(hwc3::Error::kUnsupported);
774*0a9764feSAndroid Build Coastguard Worker   }
775*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
776*0a9764feSAndroid Build Coastguard Worker }
777*0a9764feSAndroid Build Coastguard Worker 
getDisplayCapabilities(int64_t display_id,std::vector<DisplayCapability> * caps)778*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(
779*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, std::vector<DisplayCapability>* caps) {
780*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
781*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
782*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
783*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
784*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
785*0a9764feSAndroid Build Coastguard Worker   }
786*0a9764feSAndroid Build Coastguard Worker 
787*0a9764feSAndroid Build Coastguard Worker   uint32_t num_capabilities = 0;
788*0a9764feSAndroid Build Coastguard Worker   hwc3::Error error = Hwc2toHwc3Error(
789*0a9764feSAndroid Build Coastguard Worker       display->GetDisplayCapabilities(&num_capabilities, nullptr));
790*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
791*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
792*0a9764feSAndroid Build Coastguard Worker   }
793*0a9764feSAndroid Build Coastguard Worker 
794*0a9764feSAndroid Build Coastguard Worker   std::vector<uint32_t> out_caps(num_capabilities);
795*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(
796*0a9764feSAndroid Build Coastguard Worker       display->GetDisplayCapabilities(&num_capabilities, out_caps.data()));
797*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
798*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
799*0a9764feSAndroid Build Coastguard Worker   }
800*0a9764feSAndroid Build Coastguard Worker 
801*0a9764feSAndroid Build Coastguard Worker   caps->reserve(num_capabilities);
802*0a9764feSAndroid Build Coastguard Worker   for (const auto cap : out_caps) {
803*0a9764feSAndroid Build Coastguard Worker     caps->emplace_back(Hwc2DisplayCapabilityToHwc3(cap));
804*0a9764feSAndroid Build Coastguard Worker   }
805*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
806*0a9764feSAndroid Build Coastguard Worker }
807*0a9764feSAndroid Build Coastguard Worker 
getDisplayConfigs(int64_t display_id,std::vector<int32_t> * out_configs)808*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayConfigs(
809*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, std::vector<int32_t>* out_configs) {
810*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
811*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
812*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
813*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
814*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
815*0a9764feSAndroid Build Coastguard Worker   }
816*0a9764feSAndroid Build Coastguard Worker 
817*0a9764feSAndroid Build Coastguard Worker   const HwcDisplayConfigs& configs = display->GetDisplayConfigs();
818*0a9764feSAndroid Build Coastguard Worker   for (const auto& [id, config] : configs.hwc_configs) {
819*0a9764feSAndroid Build Coastguard Worker     out_configs->push_back(static_cast<int32_t>(id));
820*0a9764feSAndroid Build Coastguard Worker   }
821*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
822*0a9764feSAndroid Build Coastguard Worker }
823*0a9764feSAndroid Build Coastguard Worker 
getDisplayConnectionType(int64_t display_id,DisplayConnectionType * type)824*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(
825*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, DisplayConnectionType* type) {
826*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
827*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
828*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
829*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
830*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
831*0a9764feSAndroid Build Coastguard Worker   }
832*0a9764feSAndroid Build Coastguard Worker 
833*0a9764feSAndroid Build Coastguard Worker   uint32_t out_type = 0;
834*0a9764feSAndroid Build Coastguard Worker   const hwc3::Error error = Hwc2toHwc3Error(
835*0a9764feSAndroid Build Coastguard Worker       display->GetDisplayConnectionType(&out_type));
836*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
837*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
838*0a9764feSAndroid Build Coastguard Worker   }
839*0a9764feSAndroid Build Coastguard Worker 
840*0a9764feSAndroid Build Coastguard Worker   *type = Hwc2DisplayConnectionTypeToHwc3(out_type);
841*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
842*0a9764feSAndroid Build Coastguard Worker }
843*0a9764feSAndroid Build Coastguard Worker 
getDisplayIdentificationData(int64_t display_id,DisplayIdentification * id)844*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData(
845*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, DisplayIdentification* id) {
846*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
847*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
848*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
849*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
850*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
851*0a9764feSAndroid Build Coastguard Worker   }
852*0a9764feSAndroid Build Coastguard Worker 
853*0a9764feSAndroid Build Coastguard Worker   uint8_t port = 0;
854*0a9764feSAndroid Build Coastguard Worker   uint32_t data_size = 0;
855*0a9764feSAndroid Build Coastguard Worker   hwc3::Error error = Hwc2toHwc3Error(
856*0a9764feSAndroid Build Coastguard Worker       display->GetDisplayIdentificationData(&port, &data_size, nullptr));
857*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
858*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
859*0a9764feSAndroid Build Coastguard Worker   }
860*0a9764feSAndroid Build Coastguard Worker 
861*0a9764feSAndroid Build Coastguard Worker   id->data.resize(data_size);
862*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(
863*0a9764feSAndroid Build Coastguard Worker       display->GetDisplayIdentificationData(&port, &data_size,
864*0a9764feSAndroid Build Coastguard Worker                                             id->data.data()));
865*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
866*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
867*0a9764feSAndroid Build Coastguard Worker   }
868*0a9764feSAndroid Build Coastguard Worker 
869*0a9764feSAndroid Build Coastguard Worker   id->port = static_cast<int8_t>(port);
870*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
871*0a9764feSAndroid Build Coastguard Worker }
872*0a9764feSAndroid Build Coastguard Worker 
getDisplayName(int64_t display_id,std::string * name)873*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t display_id,
874*0a9764feSAndroid Build Coastguard Worker                                                   std::string* name) {
875*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
876*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
877*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
878*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
879*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
880*0a9764feSAndroid Build Coastguard Worker   }
881*0a9764feSAndroid Build Coastguard Worker 
882*0a9764feSAndroid Build Coastguard Worker   uint32_t size = 0;
883*0a9764feSAndroid Build Coastguard Worker   auto error = Hwc2toHwc3Error(display->GetDisplayName(&size, nullptr));
884*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
885*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
886*0a9764feSAndroid Build Coastguard Worker   }
887*0a9764feSAndroid Build Coastguard Worker 
888*0a9764feSAndroid Build Coastguard Worker   name->resize(size);
889*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(display->GetDisplayName(&size, name->data()));
890*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(error);
891*0a9764feSAndroid Build Coastguard Worker }
892*0a9764feSAndroid Build Coastguard Worker 
getDisplayVsyncPeriod(int64_t display_id,int32_t * vsync_period)893*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(
894*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, int32_t* vsync_period) {
895*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
896*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
897*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
898*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
899*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
900*0a9764feSAndroid Build Coastguard Worker   }
901*0a9764feSAndroid Build Coastguard Worker 
902*0a9764feSAndroid Build Coastguard Worker   // getDisplayVsyncPeriod should return the vsync period of the config that
903*0a9764feSAndroid Build Coastguard Worker   // is currently committed to the kernel. If a config change is pending due to
904*0a9764feSAndroid Build Coastguard Worker   // setActiveConfigWithConstraints, return the pre-change vsync period.
905*0a9764feSAndroid Build Coastguard Worker   const HwcDisplayConfig* config = display->GetCurrentConfig();
906*0a9764feSAndroid Build Coastguard Worker   if (config == nullptr) {
907*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadConfig);
908*0a9764feSAndroid Build Coastguard Worker   }
909*0a9764feSAndroid Build Coastguard Worker 
910*0a9764feSAndroid Build Coastguard Worker   *vsync_period = config->mode.GetVSyncPeriodNs();
911*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
912*0a9764feSAndroid Build Coastguard Worker }
913*0a9764feSAndroid Build Coastguard Worker 
getDisplayedContentSample(int64_t,int64_t,int64_t,DisplayContentSample *)914*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(
915*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/, int64_t /*max_frames*/, int64_t /*timestamp*/,
916*0a9764feSAndroid Build Coastguard Worker     DisplayContentSample* /*samples*/) {
917*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
918*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
919*0a9764feSAndroid Build Coastguard Worker }
920*0a9764feSAndroid Build Coastguard Worker 
getDisplayedContentSamplingAttributes(int64_t,DisplayContentSamplingAttributes *)921*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes(
922*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/, DisplayContentSamplingAttributes* /*attrs*/) {
923*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
924*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
925*0a9764feSAndroid Build Coastguard Worker }
926*0a9764feSAndroid Build Coastguard Worker 
getDisplayPhysicalOrientation(int64_t display_id,common::Transform * orientation)927*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation(
928*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, common::Transform* orientation) {
929*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
930*0a9764feSAndroid Build Coastguard Worker 
931*0a9764feSAndroid Build Coastguard Worker   if (orientation == nullptr) {
932*0a9764feSAndroid Build Coastguard Worker     ALOGE("Invalid 'orientation' pointer.");
933*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadParameter);
934*0a9764feSAndroid Build Coastguard Worker   }
935*0a9764feSAndroid Build Coastguard Worker 
936*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
937*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
938*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
939*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
940*0a9764feSAndroid Build Coastguard Worker   }
941*0a9764feSAndroid Build Coastguard Worker 
942*0a9764feSAndroid Build Coastguard Worker   PanelOrientation
943*0a9764feSAndroid Build Coastguard Worker       drm_orientation = display->getDisplayPhysicalOrientation().value_or(
944*0a9764feSAndroid Build Coastguard Worker           PanelOrientation::kModePanelOrientationNormal);
945*0a9764feSAndroid Build Coastguard Worker 
946*0a9764feSAndroid Build Coastguard Worker   switch (drm_orientation) {
947*0a9764feSAndroid Build Coastguard Worker     case PanelOrientation::kModePanelOrientationNormal:
948*0a9764feSAndroid Build Coastguard Worker       *orientation = common::Transform::NONE;
949*0a9764feSAndroid Build Coastguard Worker       break;
950*0a9764feSAndroid Build Coastguard Worker     case PanelOrientation::kModePanelOrientationBottomUp:
951*0a9764feSAndroid Build Coastguard Worker       *orientation = common::Transform::ROT_180;
952*0a9764feSAndroid Build Coastguard Worker       break;
953*0a9764feSAndroid Build Coastguard Worker     case PanelOrientation::kModePanelOrientationLeftUp:
954*0a9764feSAndroid Build Coastguard Worker       *orientation = common::Transform::ROT_270;
955*0a9764feSAndroid Build Coastguard Worker       break;
956*0a9764feSAndroid Build Coastguard Worker     case PanelOrientation::kModePanelOrientationRightUp:
957*0a9764feSAndroid Build Coastguard Worker       *orientation = common::Transform::ROT_90;
958*0a9764feSAndroid Build Coastguard Worker       break;
959*0a9764feSAndroid Build Coastguard Worker     default:
960*0a9764feSAndroid Build Coastguard Worker       ALOGE("Unknown panel orientation value: %d", drm_orientation);
961*0a9764feSAndroid Build Coastguard Worker       return ToBinderStatus(hwc3::Error::kBadDisplay);
962*0a9764feSAndroid Build Coastguard Worker   }
963*0a9764feSAndroid Build Coastguard Worker 
964*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
965*0a9764feSAndroid Build Coastguard Worker }
966*0a9764feSAndroid Build Coastguard Worker 
getHdrCapabilities(int64_t display_id,HdrCapabilities * caps)967*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t display_id,
968*0a9764feSAndroid Build Coastguard Worker                                                       HdrCapabilities* caps) {
969*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
970*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
971*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
972*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
973*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
974*0a9764feSAndroid Build Coastguard Worker   }
975*0a9764feSAndroid Build Coastguard Worker 
976*0a9764feSAndroid Build Coastguard Worker   /* No HDR capabilities */
977*0a9764feSAndroid Build Coastguard Worker   caps->types.clear();
978*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
979*0a9764feSAndroid Build Coastguard Worker }
980*0a9764feSAndroid Build Coastguard Worker 
getMaxVirtualDisplayCount(int32_t * count)981*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(int32_t* count) {
982*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
983*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
984*0a9764feSAndroid Build Coastguard Worker   *count = static_cast<int32_t>(hwc_->GetMaxVirtualDisplayCount());
985*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
986*0a9764feSAndroid Build Coastguard Worker }
987*0a9764feSAndroid Build Coastguard Worker 
getPerFrameMetadataKeys(int64_t,std::vector<PerFrameMetadataKey> *)988*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys(
989*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/, std::vector<PerFrameMetadataKey>* /*keys*/) {
990*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
991*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
992*0a9764feSAndroid Build Coastguard Worker }
993*0a9764feSAndroid Build Coastguard Worker 
getReadbackBufferAttributes(int64_t,ReadbackBufferAttributes *)994*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes(
995*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/, ReadbackBufferAttributes* /*attrs*/) {
996*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
997*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
998*0a9764feSAndroid Build Coastguard Worker }
999*0a9764feSAndroid Build Coastguard Worker 
getReadbackBufferFence(int64_t,ndk::ScopedFileDescriptor *)1000*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getReadbackBufferFence(
1001*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/, ndk::ScopedFileDescriptor* /*acquireFence*/) {
1002*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1003*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1004*0a9764feSAndroid Build Coastguard Worker }
1005*0a9764feSAndroid Build Coastguard Worker 
getRenderIntents(int64_t display_id,ColorMode mode,std::vector<RenderIntent> * intents)1006*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getRenderIntents(
1007*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, ColorMode mode, std::vector<RenderIntent>* intents) {
1008*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1009*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1010*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
1011*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1012*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
1013*0a9764feSAndroid Build Coastguard Worker   }
1014*0a9764feSAndroid Build Coastguard Worker 
1015*0a9764feSAndroid Build Coastguard Worker   const int32_t hwc2_color_mode = Hwc3ColorModeToHwc2(mode);
1016*0a9764feSAndroid Build Coastguard Worker   uint32_t out_num_intents = 0;
1017*0a9764feSAndroid Build Coastguard Worker   auto error = Hwc2toHwc3Error(
1018*0a9764feSAndroid Build Coastguard Worker       display->GetRenderIntents(hwc2_color_mode, &out_num_intents, nullptr));
1019*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1020*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
1021*0a9764feSAndroid Build Coastguard Worker   }
1022*0a9764feSAndroid Build Coastguard Worker 
1023*0a9764feSAndroid Build Coastguard Worker   std::vector<int32_t> out_intents(out_num_intents);
1024*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(display->GetRenderIntents(hwc2_color_mode,
1025*0a9764feSAndroid Build Coastguard Worker                                                     &out_num_intents,
1026*0a9764feSAndroid Build Coastguard Worker                                                     out_intents.data()));
1027*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1028*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(error);
1029*0a9764feSAndroid Build Coastguard Worker   }
1030*0a9764feSAndroid Build Coastguard Worker 
1031*0a9764feSAndroid Build Coastguard Worker   intents->reserve(out_num_intents);
1032*0a9764feSAndroid Build Coastguard Worker   for (const auto intent : out_intents) {
1033*0a9764feSAndroid Build Coastguard Worker     intents->emplace_back(Hwc2RenderIntentToHwc3(intent));
1034*0a9764feSAndroid Build Coastguard Worker   }
1035*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
1036*0a9764feSAndroid Build Coastguard Worker }
1037*0a9764feSAndroid Build Coastguard Worker 
getSupportedContentTypes(int64_t display_id,std::vector<ContentType> * types)1038*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(
1039*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, std::vector<ContentType>* types) {
1040*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1041*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1042*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
1043*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1044*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
1045*0a9764feSAndroid Build Coastguard Worker   }
1046*0a9764feSAndroid Build Coastguard Worker 
1047*0a9764feSAndroid Build Coastguard Worker   // Support for ContentType is not implemented.
1048*0a9764feSAndroid Build Coastguard Worker   types->clear();
1049*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
1050*0a9764feSAndroid Build Coastguard Worker }
1051*0a9764feSAndroid Build Coastguard Worker 
getDisplayDecorationSupport(int64_t,std::optional<common::DisplayDecorationSupport> *)1052*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport(
1053*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/,
1054*0a9764feSAndroid Build Coastguard Worker     std::optional<common::DisplayDecorationSupport>* /*support_struct*/) {
1055*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1056*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1057*0a9764feSAndroid Build Coastguard Worker }
1058*0a9764feSAndroid Build Coastguard Worker 
registerCallback(const std::shared_ptr<IComposerCallback> & callback)1059*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::registerCallback(
1060*0a9764feSAndroid Build Coastguard Worker     const std::shared_ptr<IComposerCallback>& callback) {
1061*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1062*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1063*0a9764feSAndroid Build Coastguard Worker   // This function is specified to be called exactly once.
1064*0a9764feSAndroid Build Coastguard Worker   hwc_->Init(callback);
1065*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
1066*0a9764feSAndroid Build Coastguard Worker }
1067*0a9764feSAndroid Build Coastguard Worker 
setActiveConfig(int64_t display_id,int32_t config)1068*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t display_id,
1069*0a9764feSAndroid Build Coastguard Worker                                                    int32_t config) {
1070*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1071*0a9764feSAndroid Build Coastguard Worker 
1072*0a9764feSAndroid Build Coastguard Worker   VsyncPeriodChangeTimeline timeline;
1073*0a9764feSAndroid Build Coastguard Worker   VsyncPeriodChangeConstraints constraints = {
1074*0a9764feSAndroid Build Coastguard Worker       .desiredTimeNanos = ::android::ResourceManager::GetTimeMonotonicNs(),
1075*0a9764feSAndroid Build Coastguard Worker       .seamlessRequired = false,
1076*0a9764feSAndroid Build Coastguard Worker   };
1077*0a9764feSAndroid Build Coastguard Worker   return setActiveConfigWithConstraints(display_id, config, constraints,
1078*0a9764feSAndroid Build Coastguard Worker                                         &timeline);
1079*0a9764feSAndroid Build Coastguard Worker }
1080*0a9764feSAndroid Build Coastguard Worker 
setActiveConfigWithConstraints(int64_t display_id,int32_t config,const VsyncPeriodChangeConstraints & constraints,VsyncPeriodChangeTimeline * timeline)1081*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints(
1082*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, int32_t config,
1083*0a9764feSAndroid Build Coastguard Worker     const VsyncPeriodChangeConstraints& constraints,
1084*0a9764feSAndroid Build Coastguard Worker     VsyncPeriodChangeTimeline* timeline) {
1085*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1086*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1087*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
1088*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1089*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
1090*0a9764feSAndroid Build Coastguard Worker   }
1091*0a9764feSAndroid Build Coastguard Worker 
1092*0a9764feSAndroid Build Coastguard Worker   if (constraints.seamlessRequired) {
1093*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kSeamlessNotAllowed);
1094*0a9764feSAndroid Build Coastguard Worker   }
1095*0a9764feSAndroid Build Coastguard Worker 
1096*0a9764feSAndroid Build Coastguard Worker   const bool future_config = constraints.desiredTimeNanos >
1097*0a9764feSAndroid Build Coastguard Worker                              ::android::ResourceManager::GetTimeMonotonicNs();
1098*0a9764feSAndroid Build Coastguard Worker   const HwcDisplayConfig* current_config = display->GetCurrentConfig();
1099*0a9764feSAndroid Build Coastguard Worker   const HwcDisplayConfig* next_config = display->GetConfig(config);
1100*0a9764feSAndroid Build Coastguard Worker   const bool same_config_group = current_config != nullptr &&
1101*0a9764feSAndroid Build Coastguard Worker                                  next_config != nullptr &&
1102*0a9764feSAndroid Build Coastguard Worker                                  current_config->group_id ==
1103*0a9764feSAndroid Build Coastguard Worker                                      next_config->group_id;
1104*0a9764feSAndroid Build Coastguard Worker   // If the contraints dictate that this is to be applied in the future, it
1105*0a9764feSAndroid Build Coastguard Worker   // must be queued. If the new config is in the same config group as the
1106*0a9764feSAndroid Build Coastguard Worker   // current one, then queue it to reduce jank.
1107*0a9764feSAndroid Build Coastguard Worker   HwcDisplay::ConfigError result{};
1108*0a9764feSAndroid Build Coastguard Worker   if (future_config || same_config_group) {
1109*0a9764feSAndroid Build Coastguard Worker     QueuedConfigTiming timing = {};
1110*0a9764feSAndroid Build Coastguard Worker     result = display->QueueConfig(config, constraints.desiredTimeNanos,
1111*0a9764feSAndroid Build Coastguard Worker                                   constraints.seamlessRequired, &timing);
1112*0a9764feSAndroid Build Coastguard Worker     timeline->newVsyncAppliedTimeNanos = timing.new_vsync_time_ns;
1113*0a9764feSAndroid Build Coastguard Worker     timeline->refreshTimeNanos = timing.refresh_time_ns;
1114*0a9764feSAndroid Build Coastguard Worker     timeline->refreshRequired = true;
1115*0a9764feSAndroid Build Coastguard Worker   } else {
1116*0a9764feSAndroid Build Coastguard Worker     // Fall back to a blocking commit, which may modeset.
1117*0a9764feSAndroid Build Coastguard Worker     result = display->SetConfig(config);
1118*0a9764feSAndroid Build Coastguard Worker     timeline->newVsyncAppliedTimeNanos = ::android::ResourceManager::
1119*0a9764feSAndroid Build Coastguard Worker         GetTimeMonotonicNs();
1120*0a9764feSAndroid Build Coastguard Worker     timeline->refreshRequired = false;
1121*0a9764feSAndroid Build Coastguard Worker   }
1122*0a9764feSAndroid Build Coastguard Worker 
1123*0a9764feSAndroid Build Coastguard Worker   switch (result) {
1124*0a9764feSAndroid Build Coastguard Worker     case HwcDisplay::ConfigError::kBadConfig:
1125*0a9764feSAndroid Build Coastguard Worker       return ToBinderStatus(hwc3::Error::kBadConfig);
1126*0a9764feSAndroid Build Coastguard Worker     case HwcDisplay::ConfigError::kSeamlessNotAllowed:
1127*0a9764feSAndroid Build Coastguard Worker       return ToBinderStatus(hwc3::Error::kSeamlessNotAllowed);
1128*0a9764feSAndroid Build Coastguard Worker     case HwcDisplay::ConfigError::kSeamlessNotPossible:
1129*0a9764feSAndroid Build Coastguard Worker       return ToBinderStatus(hwc3::Error::kSeamlessNotPossible);
1130*0a9764feSAndroid Build Coastguard Worker     case HwcDisplay::ConfigError::kNone:
1131*0a9764feSAndroid Build Coastguard Worker       return ndk::ScopedAStatus::ok();
1132*0a9764feSAndroid Build Coastguard Worker   }
1133*0a9764feSAndroid Build Coastguard Worker }
1134*0a9764feSAndroid Build Coastguard Worker 
setBootDisplayConfig(int64_t,int32_t)1135*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t /*display_id*/,
1136*0a9764feSAndroid Build Coastguard Worker                                                         int32_t /*config*/) {
1137*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1138*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1139*0a9764feSAndroid Build Coastguard Worker }
1140*0a9764feSAndroid Build Coastguard Worker 
clearBootDisplayConfig(int64_t)1141*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(
1142*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/) {
1143*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1144*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1145*0a9764feSAndroid Build Coastguard Worker }
1146*0a9764feSAndroid Build Coastguard Worker 
getPreferredBootDisplayConfig(int64_t,int32_t *)1147*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(
1148*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/, int32_t* /*config*/) {
1149*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1150*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1151*0a9764feSAndroid Build Coastguard Worker }
1152*0a9764feSAndroid Build Coastguard Worker 
setAutoLowLatencyMode(int64_t display_id,bool on)1153*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t display_id,
1154*0a9764feSAndroid Build Coastguard Worker                                                          bool on) {
1155*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1156*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1157*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
1158*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1159*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
1160*0a9764feSAndroid Build Coastguard Worker   }
1161*0a9764feSAndroid Build Coastguard Worker 
1162*0a9764feSAndroid Build Coastguard Worker   auto error = Hwc2toHwc3Error(display->SetAutoLowLatencyMode(on));
1163*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(error);
1164*0a9764feSAndroid Build Coastguard Worker }
1165*0a9764feSAndroid Build Coastguard Worker 
setClientTargetSlotCount(int64_t display_id,int32_t count)1166*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t display_id,
1167*0a9764feSAndroid Build Coastguard Worker                                                             int32_t count) {
1168*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1169*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(
1170*0a9764feSAndroid Build Coastguard Worker       composer_resources_->SetDisplayClientTargetCacheSize(display_id, count));
1171*0a9764feSAndroid Build Coastguard Worker }
1172*0a9764feSAndroid Build Coastguard Worker 
setColorMode(int64_t display_id,ColorMode mode,RenderIntent intent)1173*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setColorMode(int64_t display_id,
1174*0a9764feSAndroid Build Coastguard Worker                                                 ColorMode mode,
1175*0a9764feSAndroid Build Coastguard Worker                                                 RenderIntent intent) {
1176*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1177*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1178*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
1179*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1180*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
1181*0a9764feSAndroid Build Coastguard Worker   }
1182*0a9764feSAndroid Build Coastguard Worker 
1183*0a9764feSAndroid Build Coastguard Worker   auto error = display->SetColorModeWithIntent(Hwc3ColorModeToHwc2(mode),
1184*0a9764feSAndroid Build Coastguard Worker                                                Hwc3RenderIntentToHwc2(intent));
1185*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(Hwc2toHwc3Error(error));
1186*0a9764feSAndroid Build Coastguard Worker }
1187*0a9764feSAndroid Build Coastguard Worker 
setContentType(int64_t display_id,ContentType type)1188*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setContentType(int64_t display_id,
1189*0a9764feSAndroid Build Coastguard Worker                                                   ContentType type) {
1190*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1191*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1192*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
1193*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1194*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
1195*0a9764feSAndroid Build Coastguard Worker   }
1196*0a9764feSAndroid Build Coastguard Worker 
1197*0a9764feSAndroid Build Coastguard Worker   if (type == ContentType::NONE) {
1198*0a9764feSAndroid Build Coastguard Worker     return ndk::ScopedAStatus::ok();
1199*0a9764feSAndroid Build Coastguard Worker   }
1200*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1201*0a9764feSAndroid Build Coastguard Worker }
1202*0a9764feSAndroid Build Coastguard Worker 
setDisplayedContentSamplingEnabled(int64_t,bool,FormatColorComponent,int64_t)1203*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled(
1204*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/, bool /*enable*/,
1205*0a9764feSAndroid Build Coastguard Worker     FormatColorComponent /*componentMask*/, int64_t /*maxFrames*/) {
1206*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1207*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1208*0a9764feSAndroid Build Coastguard Worker }
1209*0a9764feSAndroid Build Coastguard Worker 
setPowerMode(int64_t display_id,PowerMode mode)1210*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t display_id,
1211*0a9764feSAndroid Build Coastguard Worker                                                 PowerMode mode) {
1212*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1213*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1214*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
1215*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1216*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
1217*0a9764feSAndroid Build Coastguard Worker   }
1218*0a9764feSAndroid Build Coastguard Worker 
1219*0a9764feSAndroid Build Coastguard Worker   if (mode == PowerMode::ON_SUSPEND) {
1220*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kUnsupported);
1221*0a9764feSAndroid Build Coastguard Worker   }
1222*0a9764feSAndroid Build Coastguard Worker 
1223*0a9764feSAndroid Build Coastguard Worker   auto error = display->SetPowerMode(Hwc3PowerModeToHwc2(mode));
1224*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(Hwc2toHwc3Error(error));
1225*0a9764feSAndroid Build Coastguard Worker }
1226*0a9764feSAndroid Build Coastguard Worker 
setReadbackBuffer(int64_t,const AidlNativeHandle &,const ndk::ScopedFileDescriptor &)1227*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setReadbackBuffer(
1228*0a9764feSAndroid Build Coastguard Worker     int64_t /*display_id*/, const AidlNativeHandle& /*aidlBuffer*/,
1229*0a9764feSAndroid Build Coastguard Worker     const ndk::ScopedFileDescriptor& /*releaseFence*/) {
1230*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1231*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1232*0a9764feSAndroid Build Coastguard Worker }
1233*0a9764feSAndroid Build Coastguard Worker 
setVsyncEnabled(int64_t display_id,bool enabled)1234*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t display_id,
1235*0a9764feSAndroid Build Coastguard Worker                                                    bool enabled) {
1236*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1237*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1238*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
1239*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1240*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
1241*0a9764feSAndroid Build Coastguard Worker   }
1242*0a9764feSAndroid Build Coastguard Worker 
1243*0a9764feSAndroid Build Coastguard Worker   auto error = display->SetVsyncEnabled(static_cast<int32_t>(enabled));
1244*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(Hwc2toHwc3Error(error));
1245*0a9764feSAndroid Build Coastguard Worker }
1246*0a9764feSAndroid Build Coastguard Worker 
setIdleTimerEnabled(int64_t,int32_t)1247*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t /*display_id*/,
1248*0a9764feSAndroid Build Coastguard Worker                                                        int32_t /*timeout*/) {
1249*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1250*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1251*0a9764feSAndroid Build Coastguard Worker }
1252*0a9764feSAndroid Build Coastguard Worker 
1253*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ >= 34
1254*0a9764feSAndroid Build Coastguard Worker 
getOverlaySupport(OverlayProperties *)1255*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getOverlaySupport(
1256*0a9764feSAndroid Build Coastguard Worker     OverlayProperties* /*out_overlay_properties*/) {
1257*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1258*0a9764feSAndroid Build Coastguard Worker }
1259*0a9764feSAndroid Build Coastguard Worker 
getHdrConversionCapabilities(std::vector<common::HdrConversionCapability> *)1260*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getHdrConversionCapabilities(
1261*0a9764feSAndroid Build Coastguard Worker     std::vector<common::HdrConversionCapability>* /*out_capabilities*/) {
1262*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1263*0a9764feSAndroid Build Coastguard Worker }
1264*0a9764feSAndroid Build Coastguard Worker 
setHdrConversionStrategy(const common::HdrConversionStrategy &,common::Hdr *)1265*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setHdrConversionStrategy(
1266*0a9764feSAndroid Build Coastguard Worker     const common::HdrConversionStrategy& /*conversion_strategy*/,
1267*0a9764feSAndroid Build Coastguard Worker     common::Hdr* /*out_hdr*/) {
1268*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1269*0a9764feSAndroid Build Coastguard Worker }
1270*0a9764feSAndroid Build Coastguard Worker 
setRefreshRateChangedCallbackDebugEnabled(int64_t,bool)1271*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::setRefreshRateChangedCallbackDebugEnabled(
1272*0a9764feSAndroid Build Coastguard Worker     int64_t /*display*/, bool /*enabled*/) {
1273*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1274*0a9764feSAndroid Build Coastguard Worker }
1275*0a9764feSAndroid Build Coastguard Worker 
1276*0a9764feSAndroid Build Coastguard Worker #endif
1277*0a9764feSAndroid Build Coastguard Worker 
1278*0a9764feSAndroid Build Coastguard Worker #if __ANDROID_API__ >= 35
1279*0a9764feSAndroid Build Coastguard Worker 
getDisplayConfigurations(int64_t display_id,int32_t,std::vector<DisplayConfiguration> * configurations)1280*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getDisplayConfigurations(
1281*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, int32_t /*max_frame_interval_ns*/,
1282*0a9764feSAndroid Build Coastguard Worker     std::vector<DisplayConfiguration>* configurations) {
1283*0a9764feSAndroid Build Coastguard Worker   DEBUG_FUNC();
1284*0a9764feSAndroid Build Coastguard Worker   const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
1285*0a9764feSAndroid Build Coastguard Worker   HwcDisplay* display = GetDisplay(display_id);
1286*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1287*0a9764feSAndroid Build Coastguard Worker     return ToBinderStatus(hwc3::Error::kBadDisplay);
1288*0a9764feSAndroid Build Coastguard Worker   }
1289*0a9764feSAndroid Build Coastguard Worker 
1290*0a9764feSAndroid Build Coastguard Worker   const HwcDisplayConfigs& configs = display->GetDisplayConfigs();
1291*0a9764feSAndroid Build Coastguard Worker   for (const auto& [id, config] : configs.hwc_configs) {
1292*0a9764feSAndroid Build Coastguard Worker     configurations->push_back(
1293*0a9764feSAndroid Build Coastguard Worker         HwcDisplayConfigToAidlConfiguration(configs, config));
1294*0a9764feSAndroid Build Coastguard Worker   }
1295*0a9764feSAndroid Build Coastguard Worker   return ndk::ScopedAStatus::ok();
1296*0a9764feSAndroid Build Coastguard Worker }
1297*0a9764feSAndroid Build Coastguard Worker 
notifyExpectedPresent(int64_t,const ClockMonotonicTimestamp &,int32_t)1298*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::notifyExpectedPresent(
1299*0a9764feSAndroid Build Coastguard Worker     int64_t /*display*/, const ClockMonotonicTimestamp& /*expected_present_time*/,
1300*0a9764feSAndroid Build Coastguard Worker     int32_t /*frame_interval_ns*/) {
1301*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1302*0a9764feSAndroid Build Coastguard Worker }
1303*0a9764feSAndroid Build Coastguard Worker 
startHdcpNegotiation(int64_t,const AidlHdcpLevels &)1304*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::startHdcpNegotiation(
1305*0a9764feSAndroid Build Coastguard Worker     int64_t /*display*/, const AidlHdcpLevels& /*levels*/) {
1306*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1307*0a9764feSAndroid Build Coastguard Worker }
1308*0a9764feSAndroid Build Coastguard Worker 
1309*0a9764feSAndroid Build Coastguard Worker #endif
1310*0a9764feSAndroid Build Coastguard Worker 
getMaxLayerPictureProfiles(int64_t,int32_t *)1311*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getMaxLayerPictureProfiles(int64_t, int32_t*) {
1312*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1313*0a9764feSAndroid Build Coastguard Worker }
1314*0a9764feSAndroid Build Coastguard Worker 
getLuts(int64_t,const std::vector<Buffer> &,std::vector<Luts> *)1315*0a9764feSAndroid Build Coastguard Worker ndk::ScopedAStatus ComposerClient::getLuts(int64_t, const std::vector<Buffer>&,
1316*0a9764feSAndroid Build Coastguard Worker     std::vector<Luts>*) {
1317*0a9764feSAndroid Build Coastguard Worker   return ToBinderStatus(hwc3::Error::kUnsupported);
1318*0a9764feSAndroid Build Coastguard Worker }
1319*0a9764feSAndroid Build Coastguard Worker 
Dump()1320*0a9764feSAndroid Build Coastguard Worker std::string ComposerClient::Dump() {
1321*0a9764feSAndroid Build Coastguard Worker   uint32_t size = 0;
1322*0a9764feSAndroid Build Coastguard Worker   hwc_->Dump(&size, nullptr);
1323*0a9764feSAndroid Build Coastguard Worker 
1324*0a9764feSAndroid Build Coastguard Worker   std::string buffer(size, '\0');
1325*0a9764feSAndroid Build Coastguard Worker   hwc_->Dump(&size, &buffer.front());
1326*0a9764feSAndroid Build Coastguard Worker   return buffer;
1327*0a9764feSAndroid Build Coastguard Worker }
1328*0a9764feSAndroid Build Coastguard Worker 
createBinder()1329*0a9764feSAndroid Build Coastguard Worker ::ndk::SpAIBinder ComposerClient::createBinder() {
1330*0a9764feSAndroid Build Coastguard Worker   auto binder = BnComposerClient::createBinder();
1331*0a9764feSAndroid Build Coastguard Worker   AIBinder_setInheritRt(binder.get(), true);
1332*0a9764feSAndroid Build Coastguard Worker   return binder;
1333*0a9764feSAndroid Build Coastguard Worker }
1334*0a9764feSAndroid Build Coastguard Worker 
ImportLayerBuffer(int64_t display_id,int64_t layer_id,const Buffer & buffer,buffer_handle_t * out_imported_buffer)1335*0a9764feSAndroid Build Coastguard Worker hwc3::Error ComposerClient::ImportLayerBuffer(
1336*0a9764feSAndroid Build Coastguard Worker     int64_t display_id, int64_t layer_id, const Buffer& buffer,
1337*0a9764feSAndroid Build Coastguard Worker     buffer_handle_t* out_imported_buffer) {
1338*0a9764feSAndroid Build Coastguard Worker   *out_imported_buffer = nullptr;
1339*0a9764feSAndroid Build Coastguard Worker 
1340*0a9764feSAndroid Build Coastguard Worker   auto releaser = composer_resources_->CreateResourceReleaser(true);
1341*0a9764feSAndroid Build Coastguard Worker   auto err = composer_resources_->GetLayerBuffer(display_id, layer_id, buffer,
1342*0a9764feSAndroid Build Coastguard Worker                                                  out_imported_buffer,
1343*0a9764feSAndroid Build Coastguard Worker                                                  releaser.get());
1344*0a9764feSAndroid Build Coastguard Worker   return err;
1345*0a9764feSAndroid Build Coastguard Worker }
1346*0a9764feSAndroid Build Coastguard Worker 
ExecuteSetDisplayColorTransform(uint64_t display_id,const std::vector<float> & matrix)1347*0a9764feSAndroid Build Coastguard Worker void ComposerClient::ExecuteSetDisplayColorTransform(
1348*0a9764feSAndroid Build Coastguard Worker     uint64_t display_id, const std::vector<float>& matrix) {
1349*0a9764feSAndroid Build Coastguard Worker   auto* display = GetDisplay(display_id);
1350*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1351*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1352*0a9764feSAndroid Build Coastguard Worker     return;
1353*0a9764feSAndroid Build Coastguard Worker   }
1354*0a9764feSAndroid Build Coastguard Worker 
1355*0a9764feSAndroid Build Coastguard Worker   auto almost_equal = [](auto a, auto b) {
1356*0a9764feSAndroid Build Coastguard Worker     const float epsilon = 0.001F;
1357*0a9764feSAndroid Build Coastguard Worker     return std::abs(a - b) < epsilon;
1358*0a9764feSAndroid Build Coastguard Worker   };
1359*0a9764feSAndroid Build Coastguard Worker   const bool is_identity = std::equal(matrix.begin(), matrix.end(),
1360*0a9764feSAndroid Build Coastguard Worker                                       kIdentityMatrix.begin(), almost_equal);
1361*0a9764feSAndroid Build Coastguard Worker 
1362*0a9764feSAndroid Build Coastguard Worker   const int32_t hint = is_identity ? HAL_COLOR_TRANSFORM_IDENTITY
1363*0a9764feSAndroid Build Coastguard Worker                                    : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
1364*0a9764feSAndroid Build Coastguard Worker 
1365*0a9764feSAndroid Build Coastguard Worker   auto error = Hwc2toHwc3Error(display->SetColorTransform(matrix.data(), hint));
1366*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1367*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(error);
1368*0a9764feSAndroid Build Coastguard Worker   }
1369*0a9764feSAndroid Build Coastguard Worker }
ExecuteSetDisplayClientTarget(uint64_t display_id,const ClientTarget & command)1370*0a9764feSAndroid Build Coastguard Worker void ComposerClient::ExecuteSetDisplayClientTarget(
1371*0a9764feSAndroid Build Coastguard Worker     uint64_t display_id, const ClientTarget& command) {
1372*0a9764feSAndroid Build Coastguard Worker   auto* display = GetDisplay(display_id);
1373*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1374*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1375*0a9764feSAndroid Build Coastguard Worker     return;
1376*0a9764feSAndroid Build Coastguard Worker   }
1377*0a9764feSAndroid Build Coastguard Worker 
1378*0a9764feSAndroid Build Coastguard Worker   hwc_region_t damage_regions;
1379*0a9764feSAndroid Build Coastguard Worker   damage_regions.numRects = command.damage.size();
1380*0a9764feSAndroid Build Coastguard Worker 
1381*0a9764feSAndroid Build Coastguard Worker   std::vector<hwc_rect_t> regions(command.damage.size());
1382*0a9764feSAndroid Build Coastguard Worker   for (const auto& region : command.damage) {
1383*0a9764feSAndroid Build Coastguard Worker     regions.push_back({region.left, region.top, region.right, region.bottom});
1384*0a9764feSAndroid Build Coastguard Worker   }
1385*0a9764feSAndroid Build Coastguard Worker   damage_regions.rects = regions.data();
1386*0a9764feSAndroid Build Coastguard Worker 
1387*0a9764feSAndroid Build Coastguard Worker   buffer_handle_t imported_buffer = nullptr;
1388*0a9764feSAndroid Build Coastguard Worker   auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
1389*0a9764feSAndroid Build Coastguard Worker 
1390*0a9764feSAndroid Build Coastguard Worker   auto error = composer_resources_->GetDisplayClientTarget(display_id,
1391*0a9764feSAndroid Build Coastguard Worker                                                            command.buffer,
1392*0a9764feSAndroid Build Coastguard Worker                                                            &imported_buffer,
1393*0a9764feSAndroid Build Coastguard Worker                                                            buf_releaser.get());
1394*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1395*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(error);
1396*0a9764feSAndroid Build Coastguard Worker     return;
1397*0a9764feSAndroid Build Coastguard Worker   }
1398*0a9764feSAndroid Build Coastguard Worker 
1399*0a9764feSAndroid Build Coastguard Worker   // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
1400*0a9764feSAndroid Build Coastguard Worker   auto fence = const_cast<::ndk::ScopedFileDescriptor&>(command.buffer.fence)
1401*0a9764feSAndroid Build Coastguard Worker                    .release();
1402*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(
1403*0a9764feSAndroid Build Coastguard Worker       display->SetClientTarget(imported_buffer, fence,
1404*0a9764feSAndroid Build Coastguard Worker                                Hwc3DataspaceToHwc2(command.dataspace),
1405*0a9764feSAndroid Build Coastguard Worker                                damage_regions));
1406*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1407*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(error);
1408*0a9764feSAndroid Build Coastguard Worker   }
1409*0a9764feSAndroid Build Coastguard Worker }
1410*0a9764feSAndroid Build Coastguard Worker 
ExecuteSetDisplayOutputBuffer(uint64_t display_id,const Buffer & buffer)1411*0a9764feSAndroid Build Coastguard Worker void ComposerClient::ExecuteSetDisplayOutputBuffer(uint64_t display_id,
1412*0a9764feSAndroid Build Coastguard Worker                                                    const Buffer& buffer) {
1413*0a9764feSAndroid Build Coastguard Worker   auto* display = GetDisplay(display_id);
1414*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1415*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1416*0a9764feSAndroid Build Coastguard Worker     return;
1417*0a9764feSAndroid Build Coastguard Worker   }
1418*0a9764feSAndroid Build Coastguard Worker 
1419*0a9764feSAndroid Build Coastguard Worker   buffer_handle_t imported_buffer = nullptr;
1420*0a9764feSAndroid Build Coastguard Worker   auto buf_releaser = composer_resources_->CreateResourceReleaser(true);
1421*0a9764feSAndroid Build Coastguard Worker 
1422*0a9764feSAndroid Build Coastguard Worker   auto error = composer_resources_->GetDisplayOutputBuffer(display_id, buffer,
1423*0a9764feSAndroid Build Coastguard Worker                                                            &imported_buffer,
1424*0a9764feSAndroid Build Coastguard Worker                                                            buf_releaser.get());
1425*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1426*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(error);
1427*0a9764feSAndroid Build Coastguard Worker     return;
1428*0a9764feSAndroid Build Coastguard Worker   }
1429*0a9764feSAndroid Build Coastguard Worker 
1430*0a9764feSAndroid Build Coastguard Worker   // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
1431*0a9764feSAndroid Build Coastguard Worker   auto fence = const_cast<::ndk::ScopedFileDescriptor&>(buffer.fence).release();
1432*0a9764feSAndroid Build Coastguard Worker   error = Hwc2toHwc3Error(display->SetOutputBuffer(imported_buffer, fence));
1433*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1434*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(error);
1435*0a9764feSAndroid Build Coastguard Worker     return;
1436*0a9764feSAndroid Build Coastguard Worker   }
1437*0a9764feSAndroid Build Coastguard Worker }
ExecuteValidateDisplay(int64_t display_id,std::optional<ClockMonotonicTimestamp>)1438*0a9764feSAndroid Build Coastguard Worker void ComposerClient::ExecuteValidateDisplay(
1439*0a9764feSAndroid Build Coastguard Worker     int64_t display_id,
1440*0a9764feSAndroid Build Coastguard Worker     std::optional<ClockMonotonicTimestamp> /*expected_present_time*/
1441*0a9764feSAndroid Build Coastguard Worker ) {
1442*0a9764feSAndroid Build Coastguard Worker   auto* display = GetDisplay(display_id);
1443*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1444*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1445*0a9764feSAndroid Build Coastguard Worker     return;
1446*0a9764feSAndroid Build Coastguard Worker   }
1447*0a9764feSAndroid Build Coastguard Worker 
1448*0a9764feSAndroid Build Coastguard Worker   /* TODO: Handle expectedPresentTime */
1449*0a9764feSAndroid Build Coastguard Worker   /* This can be implemented in multiple ways. For example, the expected present
1450*0a9764feSAndroid Build Coastguard Worker    * time property can be implemented by the DRM driver directly as a CRTC
1451*0a9764feSAndroid Build Coastguard Worker    * property. See:
1452*0a9764feSAndroid Build Coastguard Worker    * https://cs.android.com/android/platform/superproject/main/+/b8b3b1646e64d0235f77b9e717a3e4082e26f2a8:hardware/google/graphics/common/libhwc2.1/libdrmresource/drm/drmcrtc.cpp;drc=468f6172546ab98983de18210222f231f16b21e1;l=88
1453*0a9764feSAndroid Build Coastguard Worker    * Unfortunately there doesn't seem to be a standardised way of delaying
1454*0a9764feSAndroid Build Coastguard Worker    * presentation with a timestamp in the DRM API. What we can do alternatively
1455*0a9764feSAndroid Build Coastguard Worker    * is to spawn a separate presentation thread that could handle the VBlank
1456*0a9764feSAndroid Build Coastguard Worker    * events by using DRM_MODE_PAGE_FLIP_EVENT and schedule them appropriately.
1457*0a9764feSAndroid Build Coastguard Worker    */
1458*0a9764feSAndroid Build Coastguard Worker 
1459*0a9764feSAndroid Build Coastguard Worker   std::vector<int64_t> changed_layers;
1460*0a9764feSAndroid Build Coastguard Worker   std::vector<Composition> composition_types;
1461*0a9764feSAndroid Build Coastguard Worker   int32_t display_request_mask = 0;
1462*0a9764feSAndroid Build Coastguard Worker   std::vector<int64_t> requested_layers;
1463*0a9764feSAndroid Build Coastguard Worker   std::vector<int32_t> request_masks;
1464*0a9764feSAndroid Build Coastguard Worker 
1465*0a9764feSAndroid Build Coastguard Worker   const hwc3::Error error = ValidateDisplayInternal(*display, &changed_layers,
1466*0a9764feSAndroid Build Coastguard Worker                                                     &composition_types,
1467*0a9764feSAndroid Build Coastguard Worker                                                     &display_request_mask,
1468*0a9764feSAndroid Build Coastguard Worker                                                     &requested_layers,
1469*0a9764feSAndroid Build Coastguard Worker                                                     &request_masks, nullptr,
1470*0a9764feSAndroid Build Coastguard Worker                                                     nullptr);
1471*0a9764feSAndroid Build Coastguard Worker 
1472*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1473*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(error);
1474*0a9764feSAndroid Build Coastguard Worker   }
1475*0a9764feSAndroid Build Coastguard Worker 
1476*0a9764feSAndroid Build Coastguard Worker   // If a CommandError has been been set for the current DisplayCommand, then
1477*0a9764feSAndroid Build Coastguard Worker   // no other results should be returned besides the error.
1478*0a9764feSAndroid Build Coastguard Worker   if (cmd_result_writer_->HasError()) {
1479*0a9764feSAndroid Build Coastguard Worker     return;
1480*0a9764feSAndroid Build Coastguard Worker   }
1481*0a9764feSAndroid Build Coastguard Worker 
1482*0a9764feSAndroid Build Coastguard Worker   DisplayChanges changes{};
1483*0a9764feSAndroid Build Coastguard Worker   for (size_t i = 0; i < composition_types.size(); i++) {
1484*0a9764feSAndroid Build Coastguard Worker     changes.AddLayerCompositionChange(display_id, changed_layers[i],
1485*0a9764feSAndroid Build Coastguard Worker                                       composition_types[i]);
1486*0a9764feSAndroid Build Coastguard Worker   }
1487*0a9764feSAndroid Build Coastguard Worker 
1488*0a9764feSAndroid Build Coastguard Worker   std::vector<DisplayRequest::LayerRequest> layer_requests;
1489*0a9764feSAndroid Build Coastguard Worker   for (size_t i = 0; i < requested_layers.size(); i++) {
1490*0a9764feSAndroid Build Coastguard Worker     layer_requests.push_back({requested_layers[i], request_masks[i]});
1491*0a9764feSAndroid Build Coastguard Worker   }
1492*0a9764feSAndroid Build Coastguard Worker 
1493*0a9764feSAndroid Build Coastguard Worker   const DisplayRequest request_changes{display_id, display_request_mask,
1494*0a9764feSAndroid Build Coastguard Worker                                        layer_requests};
1495*0a9764feSAndroid Build Coastguard Worker   changes.display_request_changes = request_changes;
1496*0a9764feSAndroid Build Coastguard Worker 
1497*0a9764feSAndroid Build Coastguard Worker   cmd_result_writer_->AddChanges(changes);
1498*0a9764feSAndroid Build Coastguard Worker   composer_resources_->SetDisplayMustValidateState(display_id, false);
1499*0a9764feSAndroid Build Coastguard Worker }
1500*0a9764feSAndroid Build Coastguard Worker 
ExecuteAcceptDisplayChanges(int64_t display_id)1501*0a9764feSAndroid Build Coastguard Worker void ComposerClient::ExecuteAcceptDisplayChanges(int64_t display_id) {
1502*0a9764feSAndroid Build Coastguard Worker   auto* display = GetDisplay(display_id);
1503*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1504*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1505*0a9764feSAndroid Build Coastguard Worker     return;
1506*0a9764feSAndroid Build Coastguard Worker   }
1507*0a9764feSAndroid Build Coastguard Worker 
1508*0a9764feSAndroid Build Coastguard Worker   auto error = Hwc2toHwc3Error(display->AcceptDisplayChanges());
1509*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1510*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(error);
1511*0a9764feSAndroid Build Coastguard Worker     return;
1512*0a9764feSAndroid Build Coastguard Worker   }
1513*0a9764feSAndroid Build Coastguard Worker }
1514*0a9764feSAndroid Build Coastguard Worker 
ExecutePresentDisplay(int64_t display_id)1515*0a9764feSAndroid Build Coastguard Worker void ComposerClient::ExecutePresentDisplay(int64_t display_id) {
1516*0a9764feSAndroid Build Coastguard Worker   auto* display = GetDisplay(display_id);
1517*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1518*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1519*0a9764feSAndroid Build Coastguard Worker     return;
1520*0a9764feSAndroid Build Coastguard Worker   }
1521*0a9764feSAndroid Build Coastguard Worker 
1522*0a9764feSAndroid Build Coastguard Worker   ::android::base::unique_fd display_fence;
1523*0a9764feSAndroid Build Coastguard Worker   std::unordered_map<int64_t, ::android::base::unique_fd> release_fences;
1524*0a9764feSAndroid Build Coastguard Worker   auto error = PresentDisplayInternal(display_id, display_fence,
1525*0a9764feSAndroid Build Coastguard Worker                                       release_fences);
1526*0a9764feSAndroid Build Coastguard Worker   if (error != hwc3::Error::kNone) {
1527*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(error);
1528*0a9764feSAndroid Build Coastguard Worker   }
1529*0a9764feSAndroid Build Coastguard Worker   if (cmd_result_writer_->HasError()) {
1530*0a9764feSAndroid Build Coastguard Worker     return;
1531*0a9764feSAndroid Build Coastguard Worker   }
1532*0a9764feSAndroid Build Coastguard Worker 
1533*0a9764feSAndroid Build Coastguard Worker   cmd_result_writer_->AddPresentFence(display_id, std::move(display_fence));
1534*0a9764feSAndroid Build Coastguard Worker   cmd_result_writer_->AddReleaseFence(display_id, release_fences);
1535*0a9764feSAndroid Build Coastguard Worker }
1536*0a9764feSAndroid Build Coastguard Worker 
ExecutePresentOrValidateDisplay(int64_t display_id,std::optional<ClockMonotonicTimestamp> expected_present_time)1537*0a9764feSAndroid Build Coastguard Worker void ComposerClient::ExecutePresentOrValidateDisplay(
1538*0a9764feSAndroid Build Coastguard Worker     int64_t display_id,
1539*0a9764feSAndroid Build Coastguard Worker     std::optional<ClockMonotonicTimestamp> expected_present_time) {
1540*0a9764feSAndroid Build Coastguard Worker   auto* display = GetDisplay(display_id);
1541*0a9764feSAndroid Build Coastguard Worker   if (display == nullptr) {
1542*0a9764feSAndroid Build Coastguard Worker     cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
1543*0a9764feSAndroid Build Coastguard Worker     return;
1544*0a9764feSAndroid Build Coastguard Worker   }
1545*0a9764feSAndroid Build Coastguard Worker 
1546*0a9764feSAndroid Build Coastguard Worker   /* TODO: Handle expectedPresentTime */
1547*0a9764feSAndroid Build Coastguard Worker   /* This can be implemented in multiple ways. For example, the expected present
1548*0a9764feSAndroid Build Coastguard Worker    * time property can be implemented by the DRM driver directly as a CRTC
1549*0a9764feSAndroid Build Coastguard Worker    * property. See:
1550*0a9764feSAndroid Build Coastguard Worker    * https://cs.android.com/android/platform/superproject/main/+/b8b3b1646e64d0235f77b9e717a3e4082e26f2a8:hardware/google/graphics/common/libhwc2.1/libdrmresource/drm/drmcrtc.cpp;drc=468f6172546ab98983de18210222f231f16b21e1;l=88
1551*0a9764feSAndroid Build Coastguard Worker    * Unfortunately there doesn't seem to be a standardised way of delaying
1552*0a9764feSAndroid Build Coastguard Worker    * presentation with a timestamp in the DRM API. What we can do alternatively
1553*0a9764feSAndroid Build Coastguard Worker    * is to spawn a separate presentation thread that could handle the VBlank
1554*0a9764feSAndroid Build Coastguard Worker    * events by using DRM_MODE_PAGE_FLIP_EVENT and schedule them appropriately.
1555*0a9764feSAndroid Build Coastguard Worker    */
1556*0a9764feSAndroid Build Coastguard Worker 
1557*0a9764feSAndroid Build Coastguard Worker   /* TODO: Add check if it's possible to skip display validation */
1558*0a9764feSAndroid Build Coastguard Worker   ExecuteValidateDisplay(display_id, expected_present_time);
1559*0a9764feSAndroid Build Coastguard Worker   cmd_result_writer_
1560*0a9764feSAndroid Build Coastguard Worker       ->AddPresentOrValidateResult(display_id,
1561*0a9764feSAndroid Build Coastguard Worker                                    PresentOrValidate::Result::Validated);
1562*0a9764feSAndroid Build Coastguard Worker }
1563*0a9764feSAndroid Build Coastguard Worker 
1564*0a9764feSAndroid Build Coastguard Worker }  // namespace aidl::android::hardware::graphics::composer3::impl
1565