blob: ac25cf6ca7e589727ec8ed6781fe759de82aa9d8 [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
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200143/* Display functions */
144
145static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
146 buffer_handle_t target, int32_t acquire_fence,
147 int32_t dataspace, hwc_region_t /*damage*/) {
148 ALOGV("SetClientTarget");
149 LOCK_COMPOSER(device);
150 GET_DISPLAY(display);
151
152 if (target == nullptr) {
153 idisplay->GetClientLayer().SwChainClearCache();
154 return 0;
155 }
156
157 HwcLayer::LayerProperties lp;
158 lp.buffer = {
159 .buffer_handle = target,
160 .acquire_fence = MakeSharedFd(acquire_fence),
161 };
162 lp.color_space = Hwc2ToColorSpace(dataspace);
163 lp.sample_range = Hwc2ToSampleRange(dataspace);
164
165 idisplay->GetClientLayer().SetLayerProperties(lp);
166
167 return 0;
168}
169
170static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
171 buffer_handle_t buffer, int32_t release_fence) {
172 ALOGV("SetOutputBuffer");
173 LOCK_COMPOSER(device);
174 GET_DISPLAY(display);
175
176 auto &writeback_layer = idisplay->GetWritebackLayer();
177 if (!writeback_layer) {
178 ALOGE("Writeback layer is not available");
179 return static_cast<int32_t>(HWC2::Error::BadLayer);
180 }
181
182 HwcLayer::LayerProperties lp;
183 lp.buffer = {
184 .buffer_handle = buffer,
185 .acquire_fence = MakeSharedFd(release_fence),
186 };
187 writeback_layer->SetLayerProperties(lp);
188
189 return 0;
190}
191
192/* Layer functions */
193
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200194static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display,
195 hwc2_layer_t layer,
196 int32_t /*hwc2_blend_mode_t*/ mode) {
197 ALOGV("SetLayerBlendMode");
198 LOCK_COMPOSER(device);
199 GET_DISPLAY(display);
200 GET_LAYER(layer);
201
202 BufferBlendMode blend_mode{};
203 switch (static_cast<HWC2::BlendMode>(mode)) {
204 case HWC2::BlendMode::None:
205 blend_mode = BufferBlendMode::kNone;
206 break;
207 case HWC2::BlendMode::Premultiplied:
208 blend_mode = BufferBlendMode::kPreMult;
209 break;
210 case HWC2::BlendMode::Coverage:
211 blend_mode = BufferBlendMode::kCoverage;
212 break;
213 default:
214 ALOGE("Unknown blending mode b=%d", mode);
215 blend_mode = BufferBlendMode::kUndefined;
216 break;
217 }
218
219 HwcLayer::LayerProperties layer_properties;
220 layer_properties.blend_mode = blend_mode;
221
222 ilayer->SetLayerProperties(layer_properties);
223
224 return 0;
225}
226
227static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display,
228 hwc2_layer_t layer, buffer_handle_t buffer,
229 int32_t acquire_fence) {
230 ALOGV("SetLayerBuffer");
231 LOCK_COMPOSER(device);
232 GET_DISPLAY(display);
233 GET_LAYER(layer);
234
235 HwcLayer::LayerProperties layer_properties;
236 layer_properties.buffer = {.buffer_handle = buffer,
237 .acquire_fence = MakeSharedFd(acquire_fence)};
238 ilayer->SetLayerProperties(layer_properties);
239
240 return 0;
241}
242
243static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display,
244 hwc2_layer_t layer,
245 int32_t /*android_dataspace_t*/ dataspace) {
246 ALOGV("SetLayerDataspace");
247 LOCK_COMPOSER(device);
248 GET_DISPLAY(display);
249 GET_LAYER(layer);
250
251 HwcLayer::LayerProperties layer_properties;
252 layer_properties.color_space = Hwc2ToColorSpace(dataspace);
253 layer_properties.sample_range = Hwc2ToSampleRange(dataspace);
254 ilayer->SetLayerProperties(layer_properties);
255 return 0;
256}
257
258static int32_t SetCursorPosition(hwc2_device_t * /*device*/,
259 hwc2_display_t /*display*/,
260 hwc2_layer_t /*layer*/, int32_t /*x*/,
261 int32_t /*y*/) {
262 ALOGV("SetCursorPosition");
263 return 0;
264}
265
266static int32_t SetLayerColor(hwc2_device_t * /*device*/,
267 hwc2_display_t /*display*/, hwc2_layer_t /*layer*/,
268 hwc_color_t /*color*/) {
269 ALOGV("SetLayerColor");
270 return 0;
271}
272
273static int32_t SetLayerCompositionType(hwc2_device_t *device,
274 hwc2_display_t display,
275 hwc2_layer_t layer,
276 int32_t /*hwc2_composition_t*/ type) {
277 ALOGV("SetLayerCompositionType");
278 LOCK_COMPOSER(device);
279 GET_DISPLAY(display);
280 GET_LAYER(layer);
281
282 HwcLayer::LayerProperties layer_properties;
283 layer_properties.composition_type = static_cast<HWC2::Composition>(type);
284 ilayer->SetLayerProperties(layer_properties);
285
286 return 0;
287}
288
289static int32_t SetLayerDisplayFrame(hwc2_device_t *device,
290 hwc2_display_t display, hwc2_layer_t layer,
291 hwc_rect_t frame) {
292 ALOGV("SetLayerDisplayFrame");
293 LOCK_COMPOSER(device);
294 GET_DISPLAY(display);
295 GET_LAYER(layer);
296
297 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200298 layer_properties.display_frame = {
299 .i_rect = DstRectInfo::IRect{.left = frame.left,
300 .top = frame.top,
301 .right = frame.right,
302 .bottom = frame.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200303 ilayer->SetLayerProperties(layer_properties);
304
305 return 0;
306}
307
308static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display,
309 hwc2_layer_t layer, float alpha) {
310 ALOGV("SetLayerPlaneAlpha");
311 LOCK_COMPOSER(device);
312 GET_DISPLAY(display);
313 GET_LAYER(layer);
314
315 HwcLayer::LayerProperties layer_properties;
316 layer_properties.alpha = alpha;
317 ilayer->SetLayerProperties(layer_properties);
318
319 return 0;
320}
321
322static int32_t SetLayerSidebandStream(hwc2_device_t * /*device*/,
323 hwc2_display_t /*display*/,
324 hwc2_layer_t /*layer*/,
325 const native_handle_t * /*stream*/) {
326 ALOGV("SetLayerSidebandStream");
327 return static_cast<int32_t>(HWC2::Error::Unsupported);
328}
329
330static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display,
331 hwc2_layer_t layer, hwc_frect_t crop) {
332 ALOGV("SetLayerSourceCrop");
333 LOCK_COMPOSER(device);
334 GET_DISPLAY(display);
335 GET_LAYER(layer);
336
337 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200338 layer_properties.source_crop = {
339 .f_rect = SrcRectInfo::FRect{.left = crop.left,
340 .top = crop.top,
341 .right = crop.right,
342 .bottom = crop.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200343 ilayer->SetLayerProperties(layer_properties);
344
345 return 0;
346}
347
348static int32_t SetLayerSurfaceDamage(hwc2_device_t * /*device*/,
349 hwc2_display_t /*display*/,
350 hwc2_layer_t /*layer*/,
351 hwc_region_t /*damage*/) {
352 ALOGV("SetLayerSurfaceDamage");
353 return 0;
354}
355
356static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display,
357 hwc2_layer_t layer, int32_t transform) {
358 ALOGV("SetLayerTransform");
359 LOCK_COMPOSER(device);
360 GET_DISPLAY(display);
361 GET_LAYER(layer);
362
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200363 HwcLayer::LayerProperties layer_properties;
Roman Stratiienkoda2fcf62025-01-23 17:47:03 +0200364 layer_properties.transform = {
365 .hflip = (transform & HAL_TRANSFORM_FLIP_H) != 0,
366 .vflip = (transform & HAL_TRANSFORM_FLIP_V) != 0,
367 .rotate90 = (transform & HAL_TRANSFORM_ROT_90) != 0,
368 };
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200369 ilayer->SetLayerProperties(layer_properties);
370
371 return 0;
372}
373
374static int32_t SetLayerVisibleRegion(hwc2_device_t * /*device*/,
375 hwc2_display_t /*display*/,
376 hwc2_layer_t /*layer*/,
377 hwc_region_t /*visible*/) {
378 ALOGV("SetLayerVisibleRegion");
379 return 0;
380}
381
382static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
383 hwc2_layer_t layer, uint32_t z) {
384 ALOGV("SetLayerZOrder");
385 LOCK_COMPOSER(device);
386 GET_DISPLAY(display);
387 GET_LAYER(layer);
388
389 HwcLayer::LayerProperties layer_properties;
390 layer_properties.z_order = z;
391 ilayer->SetLayerProperties(layer_properties);
392
393 return 0;
394}
395
396/* Entry point for the HWC2 API */
397// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
398
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200399static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
400 int32_t descriptor) {
401 auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
402 switch (func) {
403 // Device functions
404 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
405 return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
406 DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
407 &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
408 int32_t *, hwc2_display_t *>);
409 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
410 return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
411 DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
412 &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
413 case HWC2::FunctionDescriptor::Dump:
414 return ToHook<HWC2_PFN_DUMP>(
415 DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
416 uint32_t *, char *>);
417 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
418 return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
419 DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
420 &DrmHwcTwo::GetMaxVirtualDisplayCount>);
421 case HWC2::FunctionDescriptor::RegisterCallback:
422 return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
423 DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
424 &DrmHwcTwo::RegisterCallback, int32_t,
425 hwc2_callback_data_t, hwc2_function_pointer_t>);
426
427 // Display functions
428 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
429 return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200430 DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
431 &HwcDisplay::AcceptDisplayChanges>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200432 case HWC2::FunctionDescriptor::CreateLayer:
433 return ToHook<HWC2_PFN_CREATE_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200434 DisplayHook<decltype(&HwcDisplay::CreateLayer),
435 &HwcDisplay::CreateLayer, hwc2_layer_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200436 case HWC2::FunctionDescriptor::DestroyLayer:
437 return ToHook<HWC2_PFN_DESTROY_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200438 DisplayHook<decltype(&HwcDisplay::DestroyLayer),
439 &HwcDisplay::DestroyLayer, hwc2_layer_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200440 case HWC2::FunctionDescriptor::GetActiveConfig:
441 return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200442 DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
443 &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200444 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
445 return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200446 DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
447 &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
448 hwc2_layer_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200449 case HWC2::FunctionDescriptor::GetClientTargetSupport:
450 return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200451 DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport),
452 &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t,
453 int32_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200454 case HWC2::FunctionDescriptor::GetColorModes:
455 return ToHook<HWC2_PFN_GET_COLOR_MODES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200456 DisplayHook<decltype(&HwcDisplay::GetColorModes),
457 &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200458 case HWC2::FunctionDescriptor::GetDisplayAttribute:
459 return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200460 DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
461 &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
462 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200463 case HWC2::FunctionDescriptor::GetDisplayConfigs:
464 return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
Drew Davenportf7e88332024-09-06 12:54:38 -0600465 DisplayHook<decltype(&HwcDisplay::LegacyGetDisplayConfigs),
466 &HwcDisplay::LegacyGetDisplayConfigs, uint32_t *,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200467 hwc2_config_t *>);
468 case HWC2::FunctionDescriptor::GetDisplayName:
469 return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200470 DisplayHook<decltype(&HwcDisplay::GetDisplayName),
471 &HwcDisplay::GetDisplayName, uint32_t *, char *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200472 case HWC2::FunctionDescriptor::GetDisplayRequests:
473 return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200474 DisplayHook<decltype(&HwcDisplay::GetDisplayRequests),
475 &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *,
476 hwc2_layer_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200477 case HWC2::FunctionDescriptor::GetDisplayType:
478 return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200479 DisplayHook<decltype(&HwcDisplay::GetDisplayType),
480 &HwcDisplay::GetDisplayType, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200481 case HWC2::FunctionDescriptor::GetDozeSupport:
482 return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200483 DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
484 &HwcDisplay::GetDozeSupport, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200485 case HWC2::FunctionDescriptor::GetHdrCapabilities:
486 return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200487 DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
488 &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
489 float *, float *, float *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200490 case HWC2::FunctionDescriptor::GetReleaseFences:
491 return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200492 DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
493 &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
494 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200495 case HWC2::FunctionDescriptor::PresentDisplay:
496 return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200497 DisplayHook<decltype(&HwcDisplay::PresentDisplay),
498 &HwcDisplay::PresentDisplay, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200499 case HWC2::FunctionDescriptor::SetActiveConfig:
500 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200501 DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
502 &HwcDisplay::SetActiveConfig, hwc2_config_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200503 case HWC2::FunctionDescriptor::SetClientTarget:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200504 return (hwc2_function_pointer_t)SetClientTarget;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200505 case HWC2::FunctionDescriptor::SetColorMode:
506 return ToHook<HWC2_PFN_SET_COLOR_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200507 DisplayHook<decltype(&HwcDisplay::SetColorMode),
508 &HwcDisplay::SetColorMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200509 case HWC2::FunctionDescriptor::SetColorTransform:
510 return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200511 DisplayHook<decltype(&HwcDisplay::SetColorTransform),
512 &HwcDisplay::SetColorTransform, const float *, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200513 case HWC2::FunctionDescriptor::SetOutputBuffer:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200514 return (hwc2_function_pointer_t)SetOutputBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200515 case HWC2::FunctionDescriptor::SetPowerMode:
516 return ToHook<HWC2_PFN_SET_POWER_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200517 DisplayHook<decltype(&HwcDisplay::SetPowerMode),
518 &HwcDisplay::SetPowerMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200519 case HWC2::FunctionDescriptor::SetVsyncEnabled:
520 return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200521 DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
522 &HwcDisplay::SetVsyncEnabled, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200523 case HWC2::FunctionDescriptor::ValidateDisplay:
524 return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200525 DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
526 &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
Roman Stratiienko6b405052022-12-10 19:09:10 +0200527#if __ANDROID_API__ > 27
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200528 case HWC2::FunctionDescriptor::GetRenderIntents:
529 return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200530 DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
531 &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
532 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200533 case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
534 return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200535 DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
536 &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200537#endif
Roman Stratiienko6b405052022-12-10 19:09:10 +0200538#if __ANDROID_API__ > 28
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200539 case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
540 return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200541 DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
542 &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
543 uint32_t *, uint8_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200544 case HWC2::FunctionDescriptor::GetDisplayCapabilities:
545 return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200546 DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
547 &HwcDisplay::GetDisplayCapabilities, uint32_t *,
548 uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200549 case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
550 return ToHook<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200551 DisplayHook<decltype(&HwcDisplay::GetDisplayBrightnessSupport),
552 &HwcDisplay::GetDisplayBrightnessSupport, bool *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200553 case HWC2::FunctionDescriptor::SetDisplayBrightness:
554 return ToHook<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200555 DisplayHook<decltype(&HwcDisplay::SetDisplayBrightness),
556 &HwcDisplay::SetDisplayBrightness, float>);
Roman Stratiienko6b405052022-12-10 19:09:10 +0200557#endif /* __ANDROID_API__ > 28 */
558#if __ANDROID_API__ > 29
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200559 case HWC2::FunctionDescriptor::GetDisplayConnectionType:
560 return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200561 DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
562 &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200563 case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
564 return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200565 DisplayHook<decltype(&HwcDisplay::GetDisplayVsyncPeriod),
566 &HwcDisplay::GetDisplayVsyncPeriod,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200567 hwc2_vsync_period_t *>);
568 case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
569 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200570 DisplayHook<decltype(&HwcDisplay::SetActiveConfigWithConstraints),
571 &HwcDisplay::SetActiveConfigWithConstraints,
572 hwc2_config_t, hwc_vsync_period_change_constraints_t *,
573 hwc_vsync_period_change_timeline_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200574 case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
575 return ToHook<HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200576 DisplayHook<decltype(&HwcDisplay::SetAutoLowLatencyMode),
577 &HwcDisplay::SetAutoLowLatencyMode, bool>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200578 case HWC2::FunctionDescriptor::GetSupportedContentTypes:
579 return ToHook<HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200580 DisplayHook<decltype(&HwcDisplay::GetSupportedContentTypes),
581 &HwcDisplay::GetSupportedContentTypes, uint32_t *,
582 uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200583 case HWC2::FunctionDescriptor::SetContentType:
584 return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200585 DisplayHook<decltype(&HwcDisplay::SetContentType),
586 &HwcDisplay::SetContentType, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200587#endif
588 // Layer functions
589 case HWC2::FunctionDescriptor::SetCursorPosition:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200590 return (hwc2_function_pointer_t)SetCursorPosition;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200591 case HWC2::FunctionDescriptor::SetLayerBlendMode:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200592 return (hwc2_function_pointer_t)SetLayerBlendMode;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200593 case HWC2::FunctionDescriptor::SetLayerBuffer:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200594 return (hwc2_function_pointer_t)SetLayerBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200595 case HWC2::FunctionDescriptor::SetLayerColor:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200596 return (hwc2_function_pointer_t)SetLayerColor;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200597 case HWC2::FunctionDescriptor::SetLayerCompositionType:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200598 return (hwc2_function_pointer_t)SetLayerCompositionType;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200599 case HWC2::FunctionDescriptor::SetLayerDataspace:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200600 return (hwc2_function_pointer_t)SetLayerDataspace;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200601 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200602 return (hwc2_function_pointer_t)SetLayerDisplayFrame;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200603 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200604 return (hwc2_function_pointer_t)SetLayerPlaneAlpha;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200605 case HWC2::FunctionDescriptor::SetLayerSidebandStream:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200606 return (hwc2_function_pointer_t)SetLayerSidebandStream;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200607 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200608 return (hwc2_function_pointer_t)SetLayerSourceCrop;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200609 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200610 return (hwc2_function_pointer_t)SetLayerSurfaceDamage;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200611 case HWC2::FunctionDescriptor::SetLayerTransform:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200612 return (hwc2_function_pointer_t)SetLayerTransform;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200613 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200614 return (hwc2_function_pointer_t)SetLayerVisibleRegion;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200615 case HWC2::FunctionDescriptor::SetLayerZOrder:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200616 return (hwc2_function_pointer_t)SetLayerZOrder;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200617 case HWC2::FunctionDescriptor::Invalid:
618 default:
619 return nullptr;
620 }
621}
622
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200623// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
624
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200625static int HookDevOpen(const struct hw_module_t *module, const char *name,
626 struct hw_device_t **dev) {
627 if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
628 ALOGE("Invalid module name- %s", name);
629 return -EINVAL;
630 }
631
632 auto ctx = std::make_unique<Drmhwc2Device>();
633 if (!ctx) {
634 ALOGE("Failed to allocate DrmHwcTwo");
635 return -ENOMEM;
636 }
637
638 ctx->common.tag = HARDWARE_DEVICE_TAG;
639 ctx->common.version = HWC_DEVICE_API_VERSION_2_0;
640 ctx->common.close = HookDevClose;
641 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
642 ctx->common.module = (hw_module_t *)module;
643 ctx->getCapabilities = HookDevGetCapabilities;
644 ctx->getFunction = HookDevGetFunction;
645
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200646 *dev = &ctx.release()->common;
647
648 return 0;
649}
650
651} // namespace android
652
653// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
654static struct hw_module_methods_t hwc2_module_methods = {
655 .open = android::HookDevOpen,
656};
657
658// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
659hw_module_t HAL_MODULE_INFO_SYM = {
660 .tag = HARDWARE_MODULE_TAG,
661 .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
662 .id = HWC_HARDWARE_MODULE_ID,
663 .name = "DrmHwcTwo module",
664 .author = "The Android Open Source Project",
665 .methods = &hwc2_module_methods,
666 .dso = nullptr,
667 .reserved = {0},
668};