blob: 842dd9d8a4d7a1107e98e1f1be76832ec713bfed [file] [log] [blame]
Roman Stratiienko26fd2b22022-01-04 12:59:29 +02001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Roman Stratiienko13017522022-01-17 10:35:34 +020017// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
18// #define LOG_NDEBUG 0 // Uncomment to see HWC2 API calls in logcat
19
Sean Paul468a7542024-07-16 19:50:58 +000020#define LOG_TAG "drmhwc"
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020021
Roman Stratiienko13017522022-01-17 10:35:34 +020022#include <cinttypes>
23
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020024#include "DrmHwcTwo.h"
25#include "backend/Backend.h"
26#include "utils/log.h"
27
28namespace android {
29
Roman Stratiienko13017522022-01-17 10:35:34 +020030/* Converts long __PRETTY_FUNCTION__ result, e.g.:
31 * "int32_t android::LayerHook(hwc2_device_t *, hwc2_display_t, hwc2_layer_t,"
32 * "Args...) [HookType = HWC2::Error (android::HwcLayer::*)(const native_handle"
33 * "*,int), func = &android::HwcLayer::SetLayerBuffer, Args = <const
34 * "native_handle, int>"
35 * to the short "android::HwcLayer::SetLayerBuffer" for better logs readability
36 */
37static std::string GetFuncName(const char *pretty_function) {
Roman Stratiienkoa7913de2022-10-20 13:18:57 +030038 const std::string str(pretty_function);
Roman Stratiienko13017522022-01-17 10:35:34 +020039 const char *start = "func = &";
Roman Stratiienkoa7913de2022-10-20 13:18:57 +030040 auto p1 = str.find(start);
Roman Stratiienko13017522022-01-17 10:35:34 +020041 p1 += strlen(start);
Roman Stratiienkoa7913de2022-10-20 13:18:57 +030042 auto p2 = str.find(',', p1);
Roman Stratiienko13017522022-01-17 10:35:34 +020043 return str.substr(p1, p2 - p1);
44}
45
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020046struct Drmhwc2Device : hwc2_device {
47 DrmHwcTwo drmhwctwo;
48};
49
50static DrmHwcTwo *ToDrmHwcTwo(hwc2_device_t *dev) {
51 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast):
52 return &static_cast<Drmhwc2Device *>(dev)->drmhwctwo;
53}
54
55template <typename PFN, typename T>
56static hwc2_function_pointer_t ToHook(T function) {
Roman Stratiienko6275b4a2025-01-24 15:50:40 +020057 // NOLINTNEXTLINE(modernize-type-traits): ToHook is going to be removed
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020058 static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
59 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast):
60 return reinterpret_cast<hwc2_function_pointer_t>(function);
61}
62
63template <typename T, typename HookType, HookType func, typename... Args>
64static T DeviceHook(hwc2_device_t *dev, Args... args) {
Roman Stratiienko13017522022-01-17 10:35:34 +020065 ALOGV("Device hook: %s", GetFuncName(__PRETTY_FUNCTION__).c_str());
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020066 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
Roman Stratiienko9e2a2cd2022-12-28 20:47:29 +020067 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020068 return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
69}
70
71template <typename HookType, HookType func, typename... Args>
72static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
73 Args... args) {
Roman Stratiienko13017522022-01-17 10:35:34 +020074 ALOGV("Display #%" PRIu64 " hook: %s", display_handle,
75 GetFuncName(__PRETTY_FUNCTION__).c_str());
Roman Stratiienko74923582022-01-17 11:24:21 +020076 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
Roman Stratiienko9e2a2cd2022-12-28 20:47:29 +020077 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
Roman Stratiienko938a7422022-01-29 00:10:07 +020078 auto *display = hwc->GetDisplay(display_handle);
79 if (display == nullptr)
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020080 return static_cast<int32_t>(HWC2::Error::BadDisplay);
81
82 return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...));
83}
84
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020085static int HookDevClose(hw_device_t *dev) {
86 // NOLINTNEXTLINE (cppcoreguidelines-pro-type-reinterpret-cast): Safe
87 auto *hwc2_dev = reinterpret_cast<hwc2_device_t *>(dev);
Roman Stratiienkoa7913de2022-10-20 13:18:57 +030088 const std::unique_ptr<DrmHwcTwo> ctx(ToDrmHwcTwo(hwc2_dev));
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020089 return 0;
90}
91
92static void HookDevGetCapabilities(hwc2_device_t * /*dev*/, uint32_t *out_count,
93 int32_t * /*out_capabilities*/) {
94 *out_count = 0;
95}
96
Roman Stratiienko41cd9502025-01-22 16:48:58 +020097// NOLINTBEGIN(cppcoreguidelines-macro-usage)
98
99#define LOCK_COMPOSER(dev) \
100 auto *ihwc = ToDrmHwcTwo(dev); \
101 const std::unique_lock lock(ihwc->GetResMan().GetMainLock());
102
103#define GET_DISPLAY(display_id) \
104 auto *idisplay = ihwc->GetDisplay(display_id); \
105 if (!idisplay) \
106 return static_cast<int32_t>(HWC2::Error::BadDisplay);
107
108#define GET_LAYER(layer_id) \
109 auto *ilayer = idisplay->get_layer(layer_id); \
110 if (!ilayer) \
111 return static_cast<int32_t>(HWC2::Error::BadLayer);
112
113// NOLINTEND(cppcoreguidelines-macro-usage)
114
115static BufferColorSpace Hwc2ToColorSpace(int32_t dataspace) {
116 switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
117 case HAL_DATASPACE_STANDARD_BT709:
118 return BufferColorSpace::kItuRec709;
119 case HAL_DATASPACE_STANDARD_BT601_625:
120 case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
121 case HAL_DATASPACE_STANDARD_BT601_525:
122 case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
123 return BufferColorSpace::kItuRec601;
124 case HAL_DATASPACE_STANDARD_BT2020:
125 case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
126 return BufferColorSpace::kItuRec2020;
127 default:
128 return BufferColorSpace::kUndefined;
129 }
130}
131
132static BufferSampleRange Hwc2ToSampleRange(int32_t dataspace) {
133 switch (dataspace & HAL_DATASPACE_RANGE_MASK) {
134 case HAL_DATASPACE_RANGE_FULL:
135 return BufferSampleRange::kFullRange;
136 case HAL_DATASPACE_RANGE_LIMITED:
137 return BufferSampleRange::kLimitedRange;
138 default:
139 return BufferSampleRange::kUndefined;
140 }
141}
142
143static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display,
144 hwc2_layer_t layer,
145 int32_t /*hwc2_blend_mode_t*/ mode) {
146 ALOGV("SetLayerBlendMode");
147 LOCK_COMPOSER(device);
148 GET_DISPLAY(display);
149 GET_LAYER(layer);
150
151 BufferBlendMode blend_mode{};
152 switch (static_cast<HWC2::BlendMode>(mode)) {
153 case HWC2::BlendMode::None:
154 blend_mode = BufferBlendMode::kNone;
155 break;
156 case HWC2::BlendMode::Premultiplied:
157 blend_mode = BufferBlendMode::kPreMult;
158 break;
159 case HWC2::BlendMode::Coverage:
160 blend_mode = BufferBlendMode::kCoverage;
161 break;
162 default:
163 ALOGE("Unknown blending mode b=%d", mode);
164 blend_mode = BufferBlendMode::kUndefined;
165 break;
166 }
167
168 HwcLayer::LayerProperties layer_properties;
169 layer_properties.blend_mode = blend_mode;
170
171 ilayer->SetLayerProperties(layer_properties);
172
173 return 0;
174}
175
176static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display,
177 hwc2_layer_t layer, buffer_handle_t buffer,
178 int32_t acquire_fence) {
179 ALOGV("SetLayerBuffer");
180 LOCK_COMPOSER(device);
181 GET_DISPLAY(display);
182 GET_LAYER(layer);
183
184 HwcLayer::LayerProperties layer_properties;
185 layer_properties.buffer = {.buffer_handle = buffer,
186 .acquire_fence = MakeSharedFd(acquire_fence)};
187 ilayer->SetLayerProperties(layer_properties);
188
189 return 0;
190}
191
192static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display,
193 hwc2_layer_t layer,
194 int32_t /*android_dataspace_t*/ dataspace) {
195 ALOGV("SetLayerDataspace");
196 LOCK_COMPOSER(device);
197 GET_DISPLAY(display);
198 GET_LAYER(layer);
199
200 HwcLayer::LayerProperties layer_properties;
201 layer_properties.color_space = Hwc2ToColorSpace(dataspace);
202 layer_properties.sample_range = Hwc2ToSampleRange(dataspace);
203 ilayer->SetLayerProperties(layer_properties);
204 return 0;
205}
206
207static int32_t SetCursorPosition(hwc2_device_t * /*device*/,
208 hwc2_display_t /*display*/,
209 hwc2_layer_t /*layer*/, int32_t /*x*/,
210 int32_t /*y*/) {
211 ALOGV("SetCursorPosition");
212 return 0;
213}
214
215static int32_t SetLayerColor(hwc2_device_t * /*device*/,
216 hwc2_display_t /*display*/, hwc2_layer_t /*layer*/,
217 hwc_color_t /*color*/) {
218 ALOGV("SetLayerColor");
219 return 0;
220}
221
222static int32_t SetLayerCompositionType(hwc2_device_t *device,
223 hwc2_display_t display,
224 hwc2_layer_t layer,
225 int32_t /*hwc2_composition_t*/ type) {
226 ALOGV("SetLayerCompositionType");
227 LOCK_COMPOSER(device);
228 GET_DISPLAY(display);
229 GET_LAYER(layer);
230
231 HwcLayer::LayerProperties layer_properties;
232 layer_properties.composition_type = static_cast<HWC2::Composition>(type);
233 ilayer->SetLayerProperties(layer_properties);
234
235 return 0;
236}
237
238static int32_t SetLayerDisplayFrame(hwc2_device_t *device,
239 hwc2_display_t display, hwc2_layer_t layer,
240 hwc_rect_t frame) {
241 ALOGV("SetLayerDisplayFrame");
242 LOCK_COMPOSER(device);
243 GET_DISPLAY(display);
244 GET_LAYER(layer);
245
246 HwcLayer::LayerProperties layer_properties;
247 layer_properties.display_frame = frame;
248 ilayer->SetLayerProperties(layer_properties);
249
250 return 0;
251}
252
253static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display,
254 hwc2_layer_t layer, float alpha) {
255 ALOGV("SetLayerPlaneAlpha");
256 LOCK_COMPOSER(device);
257 GET_DISPLAY(display);
258 GET_LAYER(layer);
259
260 HwcLayer::LayerProperties layer_properties;
261 layer_properties.alpha = alpha;
262 ilayer->SetLayerProperties(layer_properties);
263
264 return 0;
265}
266
267static int32_t SetLayerSidebandStream(hwc2_device_t * /*device*/,
268 hwc2_display_t /*display*/,
269 hwc2_layer_t /*layer*/,
270 const native_handle_t * /*stream*/) {
271 ALOGV("SetLayerSidebandStream");
272 return static_cast<int32_t>(HWC2::Error::Unsupported);
273}
274
275static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display,
276 hwc2_layer_t layer, hwc_frect_t crop) {
277 ALOGV("SetLayerSourceCrop");
278 LOCK_COMPOSER(device);
279 GET_DISPLAY(display);
280 GET_LAYER(layer);
281
282 HwcLayer::LayerProperties layer_properties;
283 layer_properties.source_crop = crop;
284 ilayer->SetLayerProperties(layer_properties);
285
286 return 0;
287}
288
289static int32_t SetLayerSurfaceDamage(hwc2_device_t * /*device*/,
290 hwc2_display_t /*display*/,
291 hwc2_layer_t /*layer*/,
292 hwc_region_t /*damage*/) {
293 ALOGV("SetLayerSurfaceDamage");
294 return 0;
295}
296
297static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display,
298 hwc2_layer_t layer, int32_t transform) {
299 ALOGV("SetLayerTransform");
300 LOCK_COMPOSER(device);
301 GET_DISPLAY(display);
302 GET_LAYER(layer);
303
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200304 HwcLayer::LayerProperties layer_properties;
Roman Stratiienkoda2fcf62025-01-23 17:47:03 +0200305 layer_properties.transform = {
306 .hflip = (transform & HAL_TRANSFORM_FLIP_H) != 0,
307 .vflip = (transform & HAL_TRANSFORM_FLIP_V) != 0,
308 .rotate90 = (transform & HAL_TRANSFORM_ROT_90) != 0,
309 };
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200310 ilayer->SetLayerProperties(layer_properties);
311
312 return 0;
313}
314
315static int32_t SetLayerVisibleRegion(hwc2_device_t * /*device*/,
316 hwc2_display_t /*display*/,
317 hwc2_layer_t /*layer*/,
318 hwc_region_t /*visible*/) {
319 ALOGV("SetLayerVisibleRegion");
320 return 0;
321}
322
323static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
324 hwc2_layer_t layer, uint32_t z) {
325 ALOGV("SetLayerZOrder");
326 LOCK_COMPOSER(device);
327 GET_DISPLAY(display);
328 GET_LAYER(layer);
329
330 HwcLayer::LayerProperties layer_properties;
331 layer_properties.z_order = z;
332 ilayer->SetLayerProperties(layer_properties);
333
334 return 0;
335}
336
337/* Entry point for the HWC2 API */
338// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
339
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200340static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
341 int32_t descriptor) {
342 auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
343 switch (func) {
344 // Device functions
345 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
346 return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
347 DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
348 &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
349 int32_t *, hwc2_display_t *>);
350 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
351 return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
352 DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
353 &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
354 case HWC2::FunctionDescriptor::Dump:
355 return ToHook<HWC2_PFN_DUMP>(
356 DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
357 uint32_t *, char *>);
358 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
359 return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
360 DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
361 &DrmHwcTwo::GetMaxVirtualDisplayCount>);
362 case HWC2::FunctionDescriptor::RegisterCallback:
363 return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
364 DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
365 &DrmHwcTwo::RegisterCallback, int32_t,
366 hwc2_callback_data_t, hwc2_function_pointer_t>);
367
368 // Display functions
369 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
370 return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200371 DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
372 &HwcDisplay::AcceptDisplayChanges>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200373 case HWC2::FunctionDescriptor::CreateLayer:
374 return ToHook<HWC2_PFN_CREATE_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200375 DisplayHook<decltype(&HwcDisplay::CreateLayer),
376 &HwcDisplay::CreateLayer, hwc2_layer_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200377 case HWC2::FunctionDescriptor::DestroyLayer:
378 return ToHook<HWC2_PFN_DESTROY_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200379 DisplayHook<decltype(&HwcDisplay::DestroyLayer),
380 &HwcDisplay::DestroyLayer, hwc2_layer_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200381 case HWC2::FunctionDescriptor::GetActiveConfig:
382 return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200383 DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
384 &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200385 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
386 return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200387 DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
388 &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
389 hwc2_layer_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200390 case HWC2::FunctionDescriptor::GetClientTargetSupport:
391 return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200392 DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport),
393 &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t,
394 int32_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200395 case HWC2::FunctionDescriptor::GetColorModes:
396 return ToHook<HWC2_PFN_GET_COLOR_MODES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200397 DisplayHook<decltype(&HwcDisplay::GetColorModes),
398 &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200399 case HWC2::FunctionDescriptor::GetDisplayAttribute:
400 return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200401 DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
402 &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
403 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200404 case HWC2::FunctionDescriptor::GetDisplayConfigs:
405 return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
Drew Davenportf7e88332024-09-06 12:54:38 -0600406 DisplayHook<decltype(&HwcDisplay::LegacyGetDisplayConfigs),
407 &HwcDisplay::LegacyGetDisplayConfigs, uint32_t *,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200408 hwc2_config_t *>);
409 case HWC2::FunctionDescriptor::GetDisplayName:
410 return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200411 DisplayHook<decltype(&HwcDisplay::GetDisplayName),
412 &HwcDisplay::GetDisplayName, uint32_t *, char *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200413 case HWC2::FunctionDescriptor::GetDisplayRequests:
414 return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200415 DisplayHook<decltype(&HwcDisplay::GetDisplayRequests),
416 &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *,
417 hwc2_layer_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200418 case HWC2::FunctionDescriptor::GetDisplayType:
419 return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200420 DisplayHook<decltype(&HwcDisplay::GetDisplayType),
421 &HwcDisplay::GetDisplayType, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200422 case HWC2::FunctionDescriptor::GetDozeSupport:
423 return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200424 DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
425 &HwcDisplay::GetDozeSupport, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200426 case HWC2::FunctionDescriptor::GetHdrCapabilities:
427 return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200428 DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
429 &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
430 float *, float *, float *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200431 case HWC2::FunctionDescriptor::GetReleaseFences:
432 return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200433 DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
434 &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
435 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200436 case HWC2::FunctionDescriptor::PresentDisplay:
437 return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200438 DisplayHook<decltype(&HwcDisplay::PresentDisplay),
439 &HwcDisplay::PresentDisplay, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200440 case HWC2::FunctionDescriptor::SetActiveConfig:
441 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200442 DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
443 &HwcDisplay::SetActiveConfig, hwc2_config_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200444 case HWC2::FunctionDescriptor::SetClientTarget:
445 return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200446 DisplayHook<decltype(&HwcDisplay::SetClientTarget),
447 &HwcDisplay::SetClientTarget, buffer_handle_t, int32_t,
448 int32_t, hwc_region_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200449 case HWC2::FunctionDescriptor::SetColorMode:
450 return ToHook<HWC2_PFN_SET_COLOR_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200451 DisplayHook<decltype(&HwcDisplay::SetColorMode),
452 &HwcDisplay::SetColorMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200453 case HWC2::FunctionDescriptor::SetColorTransform:
454 return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200455 DisplayHook<decltype(&HwcDisplay::SetColorTransform),
456 &HwcDisplay::SetColorTransform, const float *, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200457 case HWC2::FunctionDescriptor::SetOutputBuffer:
458 return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200459 DisplayHook<decltype(&HwcDisplay::SetOutputBuffer),
460 &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200461 case HWC2::FunctionDescriptor::SetPowerMode:
462 return ToHook<HWC2_PFN_SET_POWER_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200463 DisplayHook<decltype(&HwcDisplay::SetPowerMode),
464 &HwcDisplay::SetPowerMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200465 case HWC2::FunctionDescriptor::SetVsyncEnabled:
466 return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200467 DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
468 &HwcDisplay::SetVsyncEnabled, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200469 case HWC2::FunctionDescriptor::ValidateDisplay:
470 return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200471 DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
472 &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
Roman Stratiienko6b405052022-12-10 19:09:10 +0200473#if __ANDROID_API__ > 27
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200474 case HWC2::FunctionDescriptor::GetRenderIntents:
475 return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200476 DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
477 &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
478 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200479 case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
480 return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200481 DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
482 &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200483#endif
Roman Stratiienko6b405052022-12-10 19:09:10 +0200484#if __ANDROID_API__ > 28
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200485 case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
486 return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200487 DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
488 &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
489 uint32_t *, uint8_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200490 case HWC2::FunctionDescriptor::GetDisplayCapabilities:
491 return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200492 DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
493 &HwcDisplay::GetDisplayCapabilities, uint32_t *,
494 uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200495 case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
496 return ToHook<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200497 DisplayHook<decltype(&HwcDisplay::GetDisplayBrightnessSupport),
498 &HwcDisplay::GetDisplayBrightnessSupport, bool *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200499 case HWC2::FunctionDescriptor::SetDisplayBrightness:
500 return ToHook<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200501 DisplayHook<decltype(&HwcDisplay::SetDisplayBrightness),
502 &HwcDisplay::SetDisplayBrightness, float>);
Roman Stratiienko6b405052022-12-10 19:09:10 +0200503#endif /* __ANDROID_API__ > 28 */
504#if __ANDROID_API__ > 29
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200505 case HWC2::FunctionDescriptor::GetDisplayConnectionType:
506 return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200507 DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
508 &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200509 case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
510 return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200511 DisplayHook<decltype(&HwcDisplay::GetDisplayVsyncPeriod),
512 &HwcDisplay::GetDisplayVsyncPeriod,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200513 hwc2_vsync_period_t *>);
514 case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
515 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200516 DisplayHook<decltype(&HwcDisplay::SetActiveConfigWithConstraints),
517 &HwcDisplay::SetActiveConfigWithConstraints,
518 hwc2_config_t, hwc_vsync_period_change_constraints_t *,
519 hwc_vsync_period_change_timeline_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200520 case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
521 return ToHook<HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200522 DisplayHook<decltype(&HwcDisplay::SetAutoLowLatencyMode),
523 &HwcDisplay::SetAutoLowLatencyMode, bool>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200524 case HWC2::FunctionDescriptor::GetSupportedContentTypes:
525 return ToHook<HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200526 DisplayHook<decltype(&HwcDisplay::GetSupportedContentTypes),
527 &HwcDisplay::GetSupportedContentTypes, uint32_t *,
528 uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200529 case HWC2::FunctionDescriptor::SetContentType:
530 return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200531 DisplayHook<decltype(&HwcDisplay::SetContentType),
532 &HwcDisplay::SetContentType, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200533#endif
534 // Layer functions
535 case HWC2::FunctionDescriptor::SetCursorPosition:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200536 return (hwc2_function_pointer_t)SetCursorPosition;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200537 case HWC2::FunctionDescriptor::SetLayerBlendMode:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200538 return (hwc2_function_pointer_t)SetLayerBlendMode;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200539 case HWC2::FunctionDescriptor::SetLayerBuffer:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200540 return (hwc2_function_pointer_t)SetLayerBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200541 case HWC2::FunctionDescriptor::SetLayerColor:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200542 return (hwc2_function_pointer_t)SetLayerColor;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200543 case HWC2::FunctionDescriptor::SetLayerCompositionType:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200544 return (hwc2_function_pointer_t)SetLayerCompositionType;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200545 case HWC2::FunctionDescriptor::SetLayerDataspace:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200546 return (hwc2_function_pointer_t)SetLayerDataspace;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200547 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200548 return (hwc2_function_pointer_t)SetLayerDisplayFrame;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200549 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200550 return (hwc2_function_pointer_t)SetLayerPlaneAlpha;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200551 case HWC2::FunctionDescriptor::SetLayerSidebandStream:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200552 return (hwc2_function_pointer_t)SetLayerSidebandStream;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200553 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200554 return (hwc2_function_pointer_t)SetLayerSourceCrop;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200555 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200556 return (hwc2_function_pointer_t)SetLayerSurfaceDamage;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200557 case HWC2::FunctionDescriptor::SetLayerTransform:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200558 return (hwc2_function_pointer_t)SetLayerTransform;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200559 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200560 return (hwc2_function_pointer_t)SetLayerVisibleRegion;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200561 case HWC2::FunctionDescriptor::SetLayerZOrder:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200562 return (hwc2_function_pointer_t)SetLayerZOrder;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200563 case HWC2::FunctionDescriptor::Invalid:
564 default:
565 return nullptr;
566 }
567}
568
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200569// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
570
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200571static int HookDevOpen(const struct hw_module_t *module, const char *name,
572 struct hw_device_t **dev) {
573 if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
574 ALOGE("Invalid module name- %s", name);
575 return -EINVAL;
576 }
577
578 auto ctx = std::make_unique<Drmhwc2Device>();
579 if (!ctx) {
580 ALOGE("Failed to allocate DrmHwcTwo");
581 return -ENOMEM;
582 }
583
584 ctx->common.tag = HARDWARE_DEVICE_TAG;
585 ctx->common.version = HWC_DEVICE_API_VERSION_2_0;
586 ctx->common.close = HookDevClose;
587 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
588 ctx->common.module = (hw_module_t *)module;
589 ctx->getCapabilities = HookDevGetCapabilities;
590 ctx->getFunction = HookDevGetFunction;
591
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200592 *dev = &ctx.release()->common;
593
594 return 0;
595}
596
597} // namespace android
598
599// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
600static struct hw_module_methods_t hwc2_module_methods = {
601 .open = android::HookDevOpen,
602};
603
604// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
605hw_module_t HAL_MODULE_INFO_SYM = {
606 .tag = HARDWARE_MODULE_TAG,
607 .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
608 .id = HWC_HARDWARE_MODULE_ID,
609 .name = "DrmHwcTwo module",
610 .author = "The Android Open Source Project",
611 .methods = &hwc2_module_methods,
612 .dso = nullptr,
613 .reserved = {0},
614};