blob: 10e1608ab60705c705a59931ed829cfcb7a0c4fa [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 Stratiienko7c8cc4e2025-01-25 22:41:53 +020022#include <cassert>
Roman Stratiienko13017522022-01-17 10:35:34 +020023#include <cinttypes>
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +020024#include <memory>
25#include <optional>
26
27#include <cutils/native_handle.h>
Roman Stratiienko13017522022-01-17 10:35:34 +020028
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020029#include "DrmHwcTwo.h"
30#include "backend/Backend.h"
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +020031#include "hwc2_device/HwcLayer.h"
Roman Stratiienko26fd2b22022-01-04 12:59:29 +020032#include "utils/log.h"
33
34namespace android {
35
Roman Stratiienko13017522022-01-17 10:35:34 +020036/* Converts long __PRETTY_FUNCTION__ result, e.g.:
37 * "int32_t android::LayerHook(hwc2_device_t *, hwc2_display_t, hwc2_layer_t,"
38 * "Args...) [HookType = HWC2::Error (android::HwcLayer::*)(const native_handle"
39 * "*,int), func = &android::HwcLayer::SetLayerBuffer, Args = <const
40 * "native_handle, int>"
41 * to the short "android::HwcLayer::SetLayerBuffer" for better logs readability
42 */
43static std::string GetFuncName(const char *pretty_function) {
Roman Stratiienkoa7913de2022-10-20 13:18:57 +030044 const std::string str(pretty_function);
Roman Stratiienko13017522022-01-17 10:35:34 +020045 const char *start = "func = &";
Roman Stratiienkoa7913de2022-10-20 13:18:57 +030046 auto p1 = str.find(start);
Roman Stratiienko13017522022-01-17 10:35:34 +020047 p1 += strlen(start);
Roman Stratiienkoa7913de2022-10-20 13:18:57 +030048 auto p2 = str.find(',', p1);
Roman Stratiienko13017522022-01-17 10:35:34 +020049 return str.substr(p1, p2 - p1);
50}
51
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +020052class Hwc2DeviceLayer : public FrontendLayerBase {
53 public:
54 auto HandleNextBuffer(buffer_handle_t buffer_handle, int32_t fence_fd)
55 -> std::pair<std::optional<HwcLayer::LayerProperties>,
56 bool /* not a swapchain */> {
57 auto slot = GetSlotNumber(buffer_handle);
58
59 if (invalid_) {
60 return std::make_pair(std::nullopt, true);
61 }
62
63 bool buffer_provided = false;
64 bool not_a_swapchain = true;
65 int32_t slot_id = 0;
66
67 if (slot.has_value()) {
68 buffer_provided = swchain_slots_[slot.value()];
69 slot_id = slot.value();
70 not_a_swapchain = true;
71 }
72
73 HwcLayer::LayerProperties lp;
74 if (!buffer_provided) {
75 auto bo_info = BufferInfoGetter::GetInstance()->GetBoInfo(buffer_handle);
76 if (!bo_info) {
77 invalid_ = true;
78 return std::make_pair(std::nullopt, true);
79 }
80
81 lp.slot_buffer = {
82 .slot_id = slot_id,
83 .bi = bo_info,
84 };
85 }
86 lp.active_slot = {
87 .slot_id = slot_id,
88 .fence = MakeSharedFd(fence_fd),
89 };
90
91 return std::make_pair(lp, not_a_swapchain);
92 }
93
94 void SwChainClearCache() {
95 swchain_lookup_table_.clear();
96 swchain_slots_.clear();
97 swchain_reassembled_ = false;
98 }
99
100 private:
101 auto GetSlotNumber(buffer_handle_t buffer_handle) -> std::optional<int32_t> {
102 auto unique_id = BufferInfoGetter::GetInstance()->GetUniqueId(
103 buffer_handle);
104 if (!unique_id) {
105 ALOGE("Failed to get unique id for buffer handle %p", buffer_handle);
106 return std::nullopt;
107 }
108
109 if (swchain_lookup_table_.count(*unique_id) == 0) {
110 SwChainReassemble(*unique_id);
111 return std::nullopt;
112 }
113
114 if (!swchain_reassembled_) {
115 return std::nullopt;
116 }
117
118 return swchain_lookup_table_[*unique_id];
119 }
120
121 void SwChainReassemble(BufferUniqueId unique_id) {
122 if (swchain_lookup_table_.count(unique_id) != 0) {
123 if (swchain_lookup_table_[unique_id] ==
124 int(swchain_lookup_table_.size()) - 1) {
125 /* Skip same buffer */
126 return;
127 }
128 if (swchain_lookup_table_[unique_id] == 0) {
129 swchain_reassembled_ = true;
130 return;
131 }
132 /* Tracking error */
133 SwChainClearCache();
134 return;
135 }
136
137 swchain_lookup_table_[unique_id] = int(swchain_lookup_table_.size());
138 }
139
140 bool invalid_{}; /* Layer is invalid and should be skipped */
141 std::map<BufferUniqueId, int /*slot*/> swchain_lookup_table_;
142 std::map<int /*slot*/, bool /*buffer_provided*/> swchain_slots_;
143 bool swchain_reassembled_{};
144};
145
146static auto GetHwc2DeviceLayer(HwcLayer &layer)
147 -> std::shared_ptr<Hwc2DeviceLayer> {
148 auto frontend_private_data = layer.GetFrontendPrivateData();
149 if (!frontend_private_data) {
150 frontend_private_data = std::make_shared<Hwc2DeviceLayer>();
151 layer.SetFrontendPrivateData(frontend_private_data);
152 }
153 return std::static_pointer_cast<Hwc2DeviceLayer>(frontend_private_data);
154}
155
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200156struct Drmhwc2Device : hwc2_device {
157 DrmHwcTwo drmhwctwo;
158};
159
160static DrmHwcTwo *ToDrmHwcTwo(hwc2_device_t *dev) {
161 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast):
162 return &static_cast<Drmhwc2Device *>(dev)->drmhwctwo;
163}
164
165template <typename PFN, typename T>
166static hwc2_function_pointer_t ToHook(T function) {
Roman Stratiienko6275b4a2025-01-24 15:50:40 +0200167 // NOLINTNEXTLINE(modernize-type-traits): ToHook is going to be removed
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200168 static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
169 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast):
170 return reinterpret_cast<hwc2_function_pointer_t>(function);
171}
172
173template <typename T, typename HookType, HookType func, typename... Args>
174static T DeviceHook(hwc2_device_t *dev, Args... args) {
Roman Stratiienko13017522022-01-17 10:35:34 +0200175 ALOGV("Device hook: %s", GetFuncName(__PRETTY_FUNCTION__).c_str());
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200176 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
Roman Stratiienko9e2a2cd2022-12-28 20:47:29 +0200177 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200178 return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
179}
180
181template <typename HookType, HookType func, typename... Args>
182static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
183 Args... args) {
Roman Stratiienko13017522022-01-17 10:35:34 +0200184 ALOGV("Display #%" PRIu64 " hook: %s", display_handle,
185 GetFuncName(__PRETTY_FUNCTION__).c_str());
Roman Stratiienko74923582022-01-17 11:24:21 +0200186 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
Roman Stratiienko9e2a2cd2022-12-28 20:47:29 +0200187 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
Roman Stratiienko938a7422022-01-29 00:10:07 +0200188 auto *display = hwc->GetDisplay(display_handle);
189 if (display == nullptr)
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200190 return static_cast<int32_t>(HWC2::Error::BadDisplay);
191
192 return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...));
193}
194
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200195static int HookDevClose(hw_device_t *dev) {
196 // NOLINTNEXTLINE (cppcoreguidelines-pro-type-reinterpret-cast): Safe
197 auto *hwc2_dev = reinterpret_cast<hwc2_device_t *>(dev);
Roman Stratiienkoa7913de2022-10-20 13:18:57 +0300198 const std::unique_ptr<DrmHwcTwo> ctx(ToDrmHwcTwo(hwc2_dev));
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200199 return 0;
200}
201
202static void HookDevGetCapabilities(hwc2_device_t * /*dev*/, uint32_t *out_count,
203 int32_t * /*out_capabilities*/) {
204 *out_count = 0;
205}
206
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200207// NOLINTBEGIN(cppcoreguidelines-macro-usage)
208
209#define LOCK_COMPOSER(dev) \
210 auto *ihwc = ToDrmHwcTwo(dev); \
211 const std::unique_lock lock(ihwc->GetResMan().GetMainLock());
212
213#define GET_DISPLAY(display_id) \
214 auto *idisplay = ihwc->GetDisplay(display_id); \
215 if (!idisplay) \
216 return static_cast<int32_t>(HWC2::Error::BadDisplay);
217
218#define GET_LAYER(layer_id) \
219 auto *ilayer = idisplay->get_layer(layer_id); \
220 if (!ilayer) \
221 return static_cast<int32_t>(HWC2::Error::BadLayer);
222
223// NOLINTEND(cppcoreguidelines-macro-usage)
224
225static BufferColorSpace Hwc2ToColorSpace(int32_t dataspace) {
226 switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
227 case HAL_DATASPACE_STANDARD_BT709:
228 return BufferColorSpace::kItuRec709;
229 case HAL_DATASPACE_STANDARD_BT601_625:
230 case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
231 case HAL_DATASPACE_STANDARD_BT601_525:
232 case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
233 return BufferColorSpace::kItuRec601;
234 case HAL_DATASPACE_STANDARD_BT2020:
235 case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
236 return BufferColorSpace::kItuRec2020;
237 default:
238 return BufferColorSpace::kUndefined;
239 }
240}
241
242static BufferSampleRange Hwc2ToSampleRange(int32_t dataspace) {
243 switch (dataspace & HAL_DATASPACE_RANGE_MASK) {
244 case HAL_DATASPACE_RANGE_FULL:
245 return BufferSampleRange::kFullRange;
246 case HAL_DATASPACE_RANGE_LIMITED:
247 return BufferSampleRange::kLimitedRange;
248 default:
249 return BufferSampleRange::kUndefined;
250 }
251}
252
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200253/* Display functions */
254
255static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
256 buffer_handle_t target, int32_t acquire_fence,
257 int32_t dataspace, hwc_region_t /*damage*/) {
258 ALOGV("SetClientTarget");
259 LOCK_COMPOSER(device);
260 GET_DISPLAY(display);
261
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200262 auto &client_layer = idisplay->GetClientLayer();
263 auto h2l = GetHwc2DeviceLayer(client_layer);
264 if (!h2l) {
265 client_layer.SetFrontendPrivateData(std::make_shared<Hwc2DeviceLayer>());
266 }
267
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200268 if (target == nullptr) {
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200269 client_layer.ClearSlots();
270 h2l->SwChainClearCache();
271
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200272 return 0;
273 }
274
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200275 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(target, acquire_fence);
276 if (!lp) {
277 ALOGE("Failed to process client target");
278 return static_cast<int32_t>(HWC2::Error::BadLayer);
279 }
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200280
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200281 if (not_a_swapchain) {
282 client_layer.ClearSlots();
283 }
284
285 lp->color_space = Hwc2ToColorSpace(dataspace);
286 lp->sample_range = Hwc2ToSampleRange(dataspace);
287
288 idisplay->GetClientLayer().SetLayerProperties(lp.value());
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200289
290 return 0;
291}
292
293static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
294 buffer_handle_t buffer, int32_t release_fence) {
295 ALOGV("SetOutputBuffer");
296 LOCK_COMPOSER(device);
297 GET_DISPLAY(display);
298
299 auto &writeback_layer = idisplay->GetWritebackLayer();
300 if (!writeback_layer) {
301 ALOGE("Writeback layer is not available");
302 return static_cast<int32_t>(HWC2::Error::BadLayer);
303 }
304
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200305 auto h2l = GetHwc2DeviceLayer(*writeback_layer);
306 if (!h2l) {
307 writeback_layer->SetFrontendPrivateData(
308 std::make_shared<Hwc2DeviceLayer>());
309 }
310
311 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, release_fence);
312 if (!lp) {
313 ALOGE("Failed to process output buffer");
314 return static_cast<int32_t>(HWC2::Error::BadLayer);
315 }
316
317 if (not_a_swapchain) {
318 writeback_layer->ClearSlots();
319 }
320
321 writeback_layer->SetLayerProperties(lp.value());
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200322
323 return 0;
324}
325
326/* Layer functions */
327
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200328static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display,
329 hwc2_layer_t layer,
330 int32_t /*hwc2_blend_mode_t*/ mode) {
331 ALOGV("SetLayerBlendMode");
332 LOCK_COMPOSER(device);
333 GET_DISPLAY(display);
334 GET_LAYER(layer);
335
336 BufferBlendMode blend_mode{};
337 switch (static_cast<HWC2::BlendMode>(mode)) {
338 case HWC2::BlendMode::None:
339 blend_mode = BufferBlendMode::kNone;
340 break;
341 case HWC2::BlendMode::Premultiplied:
342 blend_mode = BufferBlendMode::kPreMult;
343 break;
344 case HWC2::BlendMode::Coverage:
345 blend_mode = BufferBlendMode::kCoverage;
346 break;
347 default:
348 ALOGE("Unknown blending mode b=%d", mode);
349 blend_mode = BufferBlendMode::kUndefined;
350 break;
351 }
352
353 HwcLayer::LayerProperties layer_properties;
354 layer_properties.blend_mode = blend_mode;
355
356 ilayer->SetLayerProperties(layer_properties);
357
358 return 0;
359}
360
361static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display,
362 hwc2_layer_t layer, buffer_handle_t buffer,
363 int32_t acquire_fence) {
364 ALOGV("SetLayerBuffer");
365 LOCK_COMPOSER(device);
366 GET_DISPLAY(display);
367 GET_LAYER(layer);
368
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200369 auto h2l = GetHwc2DeviceLayer(*ilayer);
370
371 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, acquire_fence);
372 if (!lp) {
373 ALOGV("Failed to process layer buffer");
374 return static_cast<int32_t>(HWC2::Error::BadLayer);
375 }
376
377 if (not_a_swapchain) {
378 ilayer->ClearSlots();
379 }
380
381 ilayer->SetLayerProperties(lp.value());
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200382
383 return 0;
384}
385
386static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display,
387 hwc2_layer_t layer,
388 int32_t /*android_dataspace_t*/ dataspace) {
389 ALOGV("SetLayerDataspace");
390 LOCK_COMPOSER(device);
391 GET_DISPLAY(display);
392 GET_LAYER(layer);
393
394 HwcLayer::LayerProperties layer_properties;
395 layer_properties.color_space = Hwc2ToColorSpace(dataspace);
396 layer_properties.sample_range = Hwc2ToSampleRange(dataspace);
397 ilayer->SetLayerProperties(layer_properties);
398 return 0;
399}
400
401static int32_t SetCursorPosition(hwc2_device_t * /*device*/,
402 hwc2_display_t /*display*/,
403 hwc2_layer_t /*layer*/, int32_t /*x*/,
404 int32_t /*y*/) {
405 ALOGV("SetCursorPosition");
406 return 0;
407}
408
409static int32_t SetLayerColor(hwc2_device_t * /*device*/,
410 hwc2_display_t /*display*/, hwc2_layer_t /*layer*/,
411 hwc_color_t /*color*/) {
412 ALOGV("SetLayerColor");
413 return 0;
414}
415
416static int32_t SetLayerCompositionType(hwc2_device_t *device,
417 hwc2_display_t display,
418 hwc2_layer_t layer,
419 int32_t /*hwc2_composition_t*/ type) {
420 ALOGV("SetLayerCompositionType");
421 LOCK_COMPOSER(device);
422 GET_DISPLAY(display);
423 GET_LAYER(layer);
424
425 HwcLayer::LayerProperties layer_properties;
426 layer_properties.composition_type = static_cast<HWC2::Composition>(type);
427 ilayer->SetLayerProperties(layer_properties);
428
429 return 0;
430}
431
432static int32_t SetLayerDisplayFrame(hwc2_device_t *device,
433 hwc2_display_t display, hwc2_layer_t layer,
434 hwc_rect_t frame) {
435 ALOGV("SetLayerDisplayFrame");
436 LOCK_COMPOSER(device);
437 GET_DISPLAY(display);
438 GET_LAYER(layer);
439
440 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200441 layer_properties.display_frame = {
442 .i_rect = DstRectInfo::IRect{.left = frame.left,
443 .top = frame.top,
444 .right = frame.right,
445 .bottom = frame.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200446 ilayer->SetLayerProperties(layer_properties);
447
448 return 0;
449}
450
451static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display,
452 hwc2_layer_t layer, float alpha) {
453 ALOGV("SetLayerPlaneAlpha");
454 LOCK_COMPOSER(device);
455 GET_DISPLAY(display);
456 GET_LAYER(layer);
457
458 HwcLayer::LayerProperties layer_properties;
459 layer_properties.alpha = alpha;
460 ilayer->SetLayerProperties(layer_properties);
461
462 return 0;
463}
464
465static int32_t SetLayerSidebandStream(hwc2_device_t * /*device*/,
466 hwc2_display_t /*display*/,
467 hwc2_layer_t /*layer*/,
468 const native_handle_t * /*stream*/) {
469 ALOGV("SetLayerSidebandStream");
470 return static_cast<int32_t>(HWC2::Error::Unsupported);
471}
472
473static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display,
474 hwc2_layer_t layer, hwc_frect_t crop) {
475 ALOGV("SetLayerSourceCrop");
476 LOCK_COMPOSER(device);
477 GET_DISPLAY(display);
478 GET_LAYER(layer);
479
480 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200481 layer_properties.source_crop = {
482 .f_rect = SrcRectInfo::FRect{.left = crop.left,
483 .top = crop.top,
484 .right = crop.right,
485 .bottom = crop.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200486 ilayer->SetLayerProperties(layer_properties);
487
488 return 0;
489}
490
491static int32_t SetLayerSurfaceDamage(hwc2_device_t * /*device*/,
492 hwc2_display_t /*display*/,
493 hwc2_layer_t /*layer*/,
494 hwc_region_t /*damage*/) {
495 ALOGV("SetLayerSurfaceDamage");
496 return 0;
497}
498
499static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display,
500 hwc2_layer_t layer, int32_t transform) {
501 ALOGV("SetLayerTransform");
502 LOCK_COMPOSER(device);
503 GET_DISPLAY(display);
504 GET_LAYER(layer);
505
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200506 HwcLayer::LayerProperties layer_properties;
Roman Stratiienkoda2fcf62025-01-23 17:47:03 +0200507 layer_properties.transform = {
508 .hflip = (transform & HAL_TRANSFORM_FLIP_H) != 0,
509 .vflip = (transform & HAL_TRANSFORM_FLIP_V) != 0,
510 .rotate90 = (transform & HAL_TRANSFORM_ROT_90) != 0,
511 };
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200512 ilayer->SetLayerProperties(layer_properties);
513
514 return 0;
515}
516
517static int32_t SetLayerVisibleRegion(hwc2_device_t * /*device*/,
518 hwc2_display_t /*display*/,
519 hwc2_layer_t /*layer*/,
520 hwc_region_t /*visible*/) {
521 ALOGV("SetLayerVisibleRegion");
522 return 0;
523}
524
525static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
526 hwc2_layer_t layer, uint32_t z) {
527 ALOGV("SetLayerZOrder");
528 LOCK_COMPOSER(device);
529 GET_DISPLAY(display);
530 GET_LAYER(layer);
531
532 HwcLayer::LayerProperties layer_properties;
533 layer_properties.z_order = z;
534 ilayer->SetLayerProperties(layer_properties);
535
536 return 0;
537}
538
539/* Entry point for the HWC2 API */
540// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
541
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200542static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
543 int32_t descriptor) {
544 auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
545 switch (func) {
546 // Device functions
547 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
548 return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
549 DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
550 &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
551 int32_t *, hwc2_display_t *>);
552 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
553 return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
554 DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
555 &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
556 case HWC2::FunctionDescriptor::Dump:
557 return ToHook<HWC2_PFN_DUMP>(
558 DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
559 uint32_t *, char *>);
560 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
561 return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
562 DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
563 &DrmHwcTwo::GetMaxVirtualDisplayCount>);
564 case HWC2::FunctionDescriptor::RegisterCallback:
565 return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
566 DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
567 &DrmHwcTwo::RegisterCallback, int32_t,
568 hwc2_callback_data_t, hwc2_function_pointer_t>);
569
570 // Display functions
571 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
572 return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200573 DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
574 &HwcDisplay::AcceptDisplayChanges>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200575 case HWC2::FunctionDescriptor::CreateLayer:
576 return ToHook<HWC2_PFN_CREATE_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200577 DisplayHook<decltype(&HwcDisplay::CreateLayer),
578 &HwcDisplay::CreateLayer, hwc2_layer_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200579 case HWC2::FunctionDescriptor::DestroyLayer:
580 return ToHook<HWC2_PFN_DESTROY_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200581 DisplayHook<decltype(&HwcDisplay::DestroyLayer),
582 &HwcDisplay::DestroyLayer, hwc2_layer_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200583 case HWC2::FunctionDescriptor::GetActiveConfig:
584 return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200585 DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
586 &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200587 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
588 return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200589 DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
590 &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
591 hwc2_layer_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200592 case HWC2::FunctionDescriptor::GetClientTargetSupport:
593 return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200594 DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport),
595 &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t,
596 int32_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200597 case HWC2::FunctionDescriptor::GetColorModes:
598 return ToHook<HWC2_PFN_GET_COLOR_MODES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200599 DisplayHook<decltype(&HwcDisplay::GetColorModes),
600 &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200601 case HWC2::FunctionDescriptor::GetDisplayAttribute:
602 return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200603 DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
604 &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
605 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200606 case HWC2::FunctionDescriptor::GetDisplayConfigs:
607 return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
Drew Davenportf7e88332024-09-06 12:54:38 -0600608 DisplayHook<decltype(&HwcDisplay::LegacyGetDisplayConfigs),
609 &HwcDisplay::LegacyGetDisplayConfigs, uint32_t *,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200610 hwc2_config_t *>);
611 case HWC2::FunctionDescriptor::GetDisplayName:
612 return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200613 DisplayHook<decltype(&HwcDisplay::GetDisplayName),
614 &HwcDisplay::GetDisplayName, uint32_t *, char *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200615 case HWC2::FunctionDescriptor::GetDisplayRequests:
616 return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200617 DisplayHook<decltype(&HwcDisplay::GetDisplayRequests),
618 &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *,
619 hwc2_layer_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200620 case HWC2::FunctionDescriptor::GetDisplayType:
621 return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200622 DisplayHook<decltype(&HwcDisplay::GetDisplayType),
623 &HwcDisplay::GetDisplayType, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200624 case HWC2::FunctionDescriptor::GetDozeSupport:
625 return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200626 DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
627 &HwcDisplay::GetDozeSupport, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200628 case HWC2::FunctionDescriptor::GetHdrCapabilities:
629 return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200630 DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
631 &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
632 float *, float *, float *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200633 case HWC2::FunctionDescriptor::GetReleaseFences:
634 return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200635 DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
636 &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
637 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200638 case HWC2::FunctionDescriptor::PresentDisplay:
639 return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200640 DisplayHook<decltype(&HwcDisplay::PresentDisplay),
641 &HwcDisplay::PresentDisplay, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200642 case HWC2::FunctionDescriptor::SetActiveConfig:
643 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200644 DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
645 &HwcDisplay::SetActiveConfig, hwc2_config_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200646 case HWC2::FunctionDescriptor::SetClientTarget:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200647 return (hwc2_function_pointer_t)SetClientTarget;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200648 case HWC2::FunctionDescriptor::SetColorMode:
649 return ToHook<HWC2_PFN_SET_COLOR_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200650 DisplayHook<decltype(&HwcDisplay::SetColorMode),
651 &HwcDisplay::SetColorMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200652 case HWC2::FunctionDescriptor::SetColorTransform:
653 return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200654 DisplayHook<decltype(&HwcDisplay::SetColorTransform),
655 &HwcDisplay::SetColorTransform, const float *, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200656 case HWC2::FunctionDescriptor::SetOutputBuffer:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200657 return (hwc2_function_pointer_t)SetOutputBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200658 case HWC2::FunctionDescriptor::SetPowerMode:
659 return ToHook<HWC2_PFN_SET_POWER_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200660 DisplayHook<decltype(&HwcDisplay::SetPowerMode),
661 &HwcDisplay::SetPowerMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200662 case HWC2::FunctionDescriptor::SetVsyncEnabled:
663 return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200664 DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
665 &HwcDisplay::SetVsyncEnabled, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200666 case HWC2::FunctionDescriptor::ValidateDisplay:
667 return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200668 DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
669 &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
Roman Stratiienko6b405052022-12-10 19:09:10 +0200670#if __ANDROID_API__ > 27
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200671 case HWC2::FunctionDescriptor::GetRenderIntents:
672 return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200673 DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
674 &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
675 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200676 case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
677 return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200678 DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
679 &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200680#endif
Roman Stratiienko6b405052022-12-10 19:09:10 +0200681#if __ANDROID_API__ > 28
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200682 case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
683 return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200684 DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
685 &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
686 uint32_t *, uint8_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200687 case HWC2::FunctionDescriptor::GetDisplayCapabilities:
688 return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200689 DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
690 &HwcDisplay::GetDisplayCapabilities, uint32_t *,
691 uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200692 case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
693 return ToHook<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200694 DisplayHook<decltype(&HwcDisplay::GetDisplayBrightnessSupport),
695 &HwcDisplay::GetDisplayBrightnessSupport, bool *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200696 case HWC2::FunctionDescriptor::SetDisplayBrightness:
697 return ToHook<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200698 DisplayHook<decltype(&HwcDisplay::SetDisplayBrightness),
699 &HwcDisplay::SetDisplayBrightness, float>);
Roman Stratiienko6b405052022-12-10 19:09:10 +0200700#endif /* __ANDROID_API__ > 28 */
701#if __ANDROID_API__ > 29
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200702 case HWC2::FunctionDescriptor::GetDisplayConnectionType:
703 return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200704 DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
705 &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200706 case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
707 return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200708 DisplayHook<decltype(&HwcDisplay::GetDisplayVsyncPeriod),
709 &HwcDisplay::GetDisplayVsyncPeriod,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200710 hwc2_vsync_period_t *>);
711 case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
712 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200713 DisplayHook<decltype(&HwcDisplay::SetActiveConfigWithConstraints),
714 &HwcDisplay::SetActiveConfigWithConstraints,
715 hwc2_config_t, hwc_vsync_period_change_constraints_t *,
716 hwc_vsync_period_change_timeline_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200717 case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
718 return ToHook<HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200719 DisplayHook<decltype(&HwcDisplay::SetAutoLowLatencyMode),
720 &HwcDisplay::SetAutoLowLatencyMode, bool>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200721 case HWC2::FunctionDescriptor::GetSupportedContentTypes:
722 return ToHook<HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200723 DisplayHook<decltype(&HwcDisplay::GetSupportedContentTypes),
724 &HwcDisplay::GetSupportedContentTypes, uint32_t *,
725 uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200726 case HWC2::FunctionDescriptor::SetContentType:
727 return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200728 DisplayHook<decltype(&HwcDisplay::SetContentType),
729 &HwcDisplay::SetContentType, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200730#endif
731 // Layer functions
732 case HWC2::FunctionDescriptor::SetCursorPosition:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200733 return (hwc2_function_pointer_t)SetCursorPosition;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200734 case HWC2::FunctionDescriptor::SetLayerBlendMode:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200735 return (hwc2_function_pointer_t)SetLayerBlendMode;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200736 case HWC2::FunctionDescriptor::SetLayerBuffer:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200737 return (hwc2_function_pointer_t)SetLayerBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200738 case HWC2::FunctionDescriptor::SetLayerColor:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200739 return (hwc2_function_pointer_t)SetLayerColor;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200740 case HWC2::FunctionDescriptor::SetLayerCompositionType:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200741 return (hwc2_function_pointer_t)SetLayerCompositionType;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200742 case HWC2::FunctionDescriptor::SetLayerDataspace:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200743 return (hwc2_function_pointer_t)SetLayerDataspace;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200744 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200745 return (hwc2_function_pointer_t)SetLayerDisplayFrame;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200746 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200747 return (hwc2_function_pointer_t)SetLayerPlaneAlpha;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200748 case HWC2::FunctionDescriptor::SetLayerSidebandStream:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200749 return (hwc2_function_pointer_t)SetLayerSidebandStream;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200750 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200751 return (hwc2_function_pointer_t)SetLayerSourceCrop;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200752 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200753 return (hwc2_function_pointer_t)SetLayerSurfaceDamage;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200754 case HWC2::FunctionDescriptor::SetLayerTransform:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200755 return (hwc2_function_pointer_t)SetLayerTransform;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200756 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200757 return (hwc2_function_pointer_t)SetLayerVisibleRegion;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200758 case HWC2::FunctionDescriptor::SetLayerZOrder:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200759 return (hwc2_function_pointer_t)SetLayerZOrder;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200760 case HWC2::FunctionDescriptor::Invalid:
761 default:
762 return nullptr;
763 }
764}
765
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200766// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
767
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200768static int HookDevOpen(const struct hw_module_t *module, const char *name,
769 struct hw_device_t **dev) {
770 if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
771 ALOGE("Invalid module name- %s", name);
772 return -EINVAL;
773 }
774
775 auto ctx = std::make_unique<Drmhwc2Device>();
776 if (!ctx) {
777 ALOGE("Failed to allocate DrmHwcTwo");
778 return -ENOMEM;
779 }
780
781 ctx->common.tag = HARDWARE_DEVICE_TAG;
782 ctx->common.version = HWC_DEVICE_API_VERSION_2_0;
783 ctx->common.close = HookDevClose;
784 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
785 ctx->common.module = (hw_module_t *)module;
786 ctx->getCapabilities = HookDevGetCapabilities;
787 ctx->getFunction = HookDevGetFunction;
788
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200789 *dev = &ctx.release()->common;
790
791 return 0;
792}
793
794} // namespace android
795
796// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
797static struct hw_module_methods_t hwc2_module_methods = {
798 .open = android::HookDevOpen,
799};
800
801// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
802hw_module_t HAL_MODULE_INFO_SYM = {
803 .tag = HARDWARE_MODULE_TAG,
804 .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
805 .id = HWC_HARDWARE_MODULE_ID,
806 .name = "DrmHwcTwo module",
807 .author = "The Android Open Source Project",
808 .methods = &hwc2_module_methods,
809 .dso = nullptr,
810 .reserved = {0},
811};