blob: 27ff611454968c621efbec924377ee60d7e7357d [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 Stratiienko72ff8c32025-02-09 00:48:44 +020052class Hwc2DeviceDisplay : public FrontendDisplayBase {
53 public:
54 std::vector<HwcDisplay::ReleaseFence> release_fences;
55};
56
57static auto GetHwc2DeviceDisplay(HwcDisplay &display)
58 -> std::shared_ptr<Hwc2DeviceDisplay> {
59 auto frontend_private_data = display.GetFrontendPrivateData();
60 if (!frontend_private_data) {
61 frontend_private_data = std::make_shared<Hwc2DeviceDisplay>();
62 display.SetFrontendPrivateData(frontend_private_data);
63 }
64 return std::static_pointer_cast<Hwc2DeviceDisplay>(frontend_private_data);
65}
66
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +020067class Hwc2DeviceLayer : public FrontendLayerBase {
68 public:
69 auto HandleNextBuffer(buffer_handle_t buffer_handle, int32_t fence_fd)
70 -> std::pair<std::optional<HwcLayer::LayerProperties>,
71 bool /* not a swapchain */> {
72 auto slot = GetSlotNumber(buffer_handle);
73
74 if (invalid_) {
75 return std::make_pair(std::nullopt, true);
76 }
77
78 bool buffer_provided = false;
79 bool not_a_swapchain = true;
80 int32_t slot_id = 0;
81
82 if (slot.has_value()) {
83 buffer_provided = swchain_slots_[slot.value()];
84 slot_id = slot.value();
85 not_a_swapchain = true;
86 }
87
88 HwcLayer::LayerProperties lp;
89 if (!buffer_provided) {
90 auto bo_info = BufferInfoGetter::GetInstance()->GetBoInfo(buffer_handle);
91 if (!bo_info) {
92 invalid_ = true;
93 return std::make_pair(std::nullopt, true);
94 }
95
96 lp.slot_buffer = {
97 .slot_id = slot_id,
98 .bi = bo_info,
99 };
100 }
101 lp.active_slot = {
102 .slot_id = slot_id,
103 .fence = MakeSharedFd(fence_fd),
104 };
105
106 return std::make_pair(lp, not_a_swapchain);
107 }
108
109 void SwChainClearCache() {
110 swchain_lookup_table_.clear();
111 swchain_slots_.clear();
112 swchain_reassembled_ = false;
113 }
114
115 private:
116 auto GetSlotNumber(buffer_handle_t buffer_handle) -> std::optional<int32_t> {
117 auto unique_id = BufferInfoGetter::GetInstance()->GetUniqueId(
118 buffer_handle);
119 if (!unique_id) {
120 ALOGE("Failed to get unique id for buffer handle %p", buffer_handle);
121 return std::nullopt;
122 }
123
124 if (swchain_lookup_table_.count(*unique_id) == 0) {
125 SwChainReassemble(*unique_id);
126 return std::nullopt;
127 }
128
129 if (!swchain_reassembled_) {
130 return std::nullopt;
131 }
132
133 return swchain_lookup_table_[*unique_id];
134 }
135
136 void SwChainReassemble(BufferUniqueId unique_id) {
137 if (swchain_lookup_table_.count(unique_id) != 0) {
138 if (swchain_lookup_table_[unique_id] ==
139 int(swchain_lookup_table_.size()) - 1) {
140 /* Skip same buffer */
141 return;
142 }
143 if (swchain_lookup_table_[unique_id] == 0) {
144 swchain_reassembled_ = true;
145 return;
146 }
147 /* Tracking error */
148 SwChainClearCache();
149 return;
150 }
151
152 swchain_lookup_table_[unique_id] = int(swchain_lookup_table_.size());
153 }
154
155 bool invalid_{}; /* Layer is invalid and should be skipped */
156 std::map<BufferUniqueId, int /*slot*/> swchain_lookup_table_;
157 std::map<int /*slot*/, bool /*buffer_provided*/> swchain_slots_;
158 bool swchain_reassembled_{};
159};
160
161static auto GetHwc2DeviceLayer(HwcLayer &layer)
162 -> std::shared_ptr<Hwc2DeviceLayer> {
163 auto frontend_private_data = layer.GetFrontendPrivateData();
164 if (!frontend_private_data) {
165 frontend_private_data = std::make_shared<Hwc2DeviceLayer>();
166 layer.SetFrontendPrivateData(frontend_private_data);
167 }
168 return std::static_pointer_cast<Hwc2DeviceLayer>(frontend_private_data);
169}
170
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200171struct Drmhwc2Device : hwc2_device {
172 DrmHwcTwo drmhwctwo;
173};
174
175static DrmHwcTwo *ToDrmHwcTwo(hwc2_device_t *dev) {
176 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast):
177 return &static_cast<Drmhwc2Device *>(dev)->drmhwctwo;
178}
179
180template <typename PFN, typename T>
181static hwc2_function_pointer_t ToHook(T function) {
Roman Stratiienko6275b4a2025-01-24 15:50:40 +0200182 // NOLINTNEXTLINE(modernize-type-traits): ToHook is going to be removed
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200183 static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
184 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast):
185 return reinterpret_cast<hwc2_function_pointer_t>(function);
186}
187
188template <typename T, typename HookType, HookType func, typename... Args>
189static T DeviceHook(hwc2_device_t *dev, Args... args) {
Roman Stratiienko13017522022-01-17 10:35:34 +0200190 ALOGV("Device hook: %s", GetFuncName(__PRETTY_FUNCTION__).c_str());
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200191 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
Roman Stratiienko9e2a2cd2022-12-28 20:47:29 +0200192 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200193 return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
194}
195
196template <typename HookType, HookType func, typename... Args>
197static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
198 Args... args) {
Roman Stratiienko13017522022-01-17 10:35:34 +0200199 ALOGV("Display #%" PRIu64 " hook: %s", display_handle,
200 GetFuncName(__PRETTY_FUNCTION__).c_str());
Roman Stratiienko74923582022-01-17 11:24:21 +0200201 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
Roman Stratiienko9e2a2cd2022-12-28 20:47:29 +0200202 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
Roman Stratiienko938a7422022-01-29 00:10:07 +0200203 auto *display = hwc->GetDisplay(display_handle);
204 if (display == nullptr)
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200205 return static_cast<int32_t>(HWC2::Error::BadDisplay);
206
207 return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...));
208}
209
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200210static int HookDevClose(hw_device_t *dev) {
211 // NOLINTNEXTLINE (cppcoreguidelines-pro-type-reinterpret-cast): Safe
212 auto *hwc2_dev = reinterpret_cast<hwc2_device_t *>(dev);
Roman Stratiienkoa7913de2022-10-20 13:18:57 +0300213 const std::unique_ptr<DrmHwcTwo> ctx(ToDrmHwcTwo(hwc2_dev));
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200214 return 0;
215}
216
217static void HookDevGetCapabilities(hwc2_device_t * /*dev*/, uint32_t *out_count,
218 int32_t * /*out_capabilities*/) {
219 *out_count = 0;
220}
221
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200222// NOLINTBEGIN(cppcoreguidelines-macro-usage)
223
224#define LOCK_COMPOSER(dev) \
225 auto *ihwc = ToDrmHwcTwo(dev); \
226 const std::unique_lock lock(ihwc->GetResMan().GetMainLock());
227
228#define GET_DISPLAY(display_id) \
229 auto *idisplay = ihwc->GetDisplay(display_id); \
230 if (!idisplay) \
231 return static_cast<int32_t>(HWC2::Error::BadDisplay);
232
233#define GET_LAYER(layer_id) \
234 auto *ilayer = idisplay->get_layer(layer_id); \
235 if (!ilayer) \
236 return static_cast<int32_t>(HWC2::Error::BadLayer);
237
238// NOLINTEND(cppcoreguidelines-macro-usage)
239
240static BufferColorSpace Hwc2ToColorSpace(int32_t dataspace) {
241 switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
242 case HAL_DATASPACE_STANDARD_BT709:
243 return BufferColorSpace::kItuRec709;
244 case HAL_DATASPACE_STANDARD_BT601_625:
245 case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
246 case HAL_DATASPACE_STANDARD_BT601_525:
247 case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
248 return BufferColorSpace::kItuRec601;
249 case HAL_DATASPACE_STANDARD_BT2020:
250 case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
251 return BufferColorSpace::kItuRec2020;
252 default:
253 return BufferColorSpace::kUndefined;
254 }
255}
256
257static BufferSampleRange Hwc2ToSampleRange(int32_t dataspace) {
258 switch (dataspace & HAL_DATASPACE_RANGE_MASK) {
259 case HAL_DATASPACE_RANGE_FULL:
260 return BufferSampleRange::kFullRange;
261 case HAL_DATASPACE_RANGE_LIMITED:
262 return BufferSampleRange::kLimitedRange;
263 default:
264 return BufferSampleRange::kUndefined;
265 }
266}
267
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200268/* Display functions */
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200269static int32_t GetDisplayRequests(hwc2_device_t * /*device*/,
270 hwc2_display_t /*display*/,
271 int32_t * /* out_display_requests */,
272 uint32_t *out_num_elements,
273 hwc2_layer_t * /*out_layers*/,
274 int32_t * /*out_layer_requests*/) {
275 ALOGV("GetDisplayRequests");
276
277 *out_num_elements = 0;
278 return 0;
279}
280
281static int32_t GetDozeSupport(hwc2_device_t * /*device*/,
282 hwc2_display_t /*display*/,
283 int32_t *out_support) {
284 ALOGV("GetDozeSupport");
285 *out_support = 0; // Doze support is not available
286 return 0;
287}
288
289static int32_t GetClientTargetSupport(hwc2_device_t * /*device*/,
290 hwc2_display_t /*display*/,
291 uint32_t /*width*/, uint32_t /*height*/,
292 int32_t /*format*/, int32_t dataspace) {
293 ALOGV("GetClientTargetSupport");
294
295 if (dataspace != HAL_DATASPACE_UNKNOWN)
296 return static_cast<int32_t>(HWC2::Error::Unsupported);
297
298 return 0;
299}
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200300
301static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
302 buffer_handle_t target, int32_t acquire_fence,
303 int32_t dataspace, hwc_region_t /*damage*/) {
304 ALOGV("SetClientTarget");
305 LOCK_COMPOSER(device);
306 GET_DISPLAY(display);
307
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200308 auto &client_layer = idisplay->GetClientLayer();
309 auto h2l = GetHwc2DeviceLayer(client_layer);
310 if (!h2l) {
311 client_layer.SetFrontendPrivateData(std::make_shared<Hwc2DeviceLayer>());
312 }
313
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200314 if (target == nullptr) {
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200315 client_layer.ClearSlots();
316 h2l->SwChainClearCache();
317
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200318 return 0;
319 }
320
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200321 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(target, acquire_fence);
322 if (!lp) {
323 ALOGE("Failed to process client target");
324 return static_cast<int32_t>(HWC2::Error::BadLayer);
325 }
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200326
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200327 if (not_a_swapchain) {
328 client_layer.ClearSlots();
329 }
330
331 lp->color_space = Hwc2ToColorSpace(dataspace);
332 lp->sample_range = Hwc2ToSampleRange(dataspace);
333
334 idisplay->GetClientLayer().SetLayerProperties(lp.value());
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200335
336 return 0;
337}
338
339static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
340 buffer_handle_t buffer, int32_t release_fence) {
341 ALOGV("SetOutputBuffer");
342 LOCK_COMPOSER(device);
343 GET_DISPLAY(display);
344
345 auto &writeback_layer = idisplay->GetWritebackLayer();
346 if (!writeback_layer) {
347 ALOGE("Writeback layer is not available");
348 return static_cast<int32_t>(HWC2::Error::BadLayer);
349 }
350
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200351 auto h2l = GetHwc2DeviceLayer(*writeback_layer);
352 if (!h2l) {
353 writeback_layer->SetFrontendPrivateData(
354 std::make_shared<Hwc2DeviceLayer>());
355 }
356
357 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, release_fence);
358 if (!lp) {
359 ALOGE("Failed to process output buffer");
360 return static_cast<int32_t>(HWC2::Error::BadLayer);
361 }
362
363 if (not_a_swapchain) {
364 writeback_layer->ClearSlots();
365 }
366
367 writeback_layer->SetLayerProperties(lp.value());
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200368
369 return 0;
370}
371
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200372static int32_t AcceptDisplayChanges(hwc2_device_t *device,
373 hwc2_display_t display) {
374 ALOGV("AcceptDisplayChanges");
375 LOCK_COMPOSER(device);
376 GET_DISPLAY(display);
377
378 idisplay->AcceptValidatedComposition();
379
380 return 0;
381}
382
Roman Stratiienko72ff8c32025-02-09 00:48:44 +0200383static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
384 uint32_t *out_num_elements,
385 hwc2_layer_t *out_layers, int32_t *out_fences) {
386 ALOGV("GetReleaseFences");
387 LOCK_COMPOSER(device);
388 GET_DISPLAY(display);
389
390 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
391
392 if (*out_num_elements < hwc2display->release_fences.size()) {
393 ALOGW("Overflow num_elements %d/%zu", *out_num_elements,
394 hwc2display->release_fences.size());
395 return static_cast<int32_t>(HWC2::Error::NoResources);
396 }
397
398 for (size_t i = 0; i < hwc2display->release_fences.size(); ++i) {
399 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
400 out_layers[i] = hwc2display->release_fences[i].first;
401 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
402 out_fences[i] = DupFd(hwc2display->release_fences[i].second);
403 }
404
405 *out_num_elements = hwc2display->release_fences.size();
406 hwc2display->release_fences.clear();
407
408 return static_cast<int32_t>(HWC2::Error::None);
409}
410
411static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
412 int32_t *out_release_fence) {
413 ALOGV("PresentDisplay");
414 LOCK_COMPOSER(device);
415 GET_DISPLAY(display);
416
417 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
418
419 SharedFd out_fence;
420
421 hwc2display->release_fences.clear();
422
423 if (!idisplay->PresentStagedComposition(out_fence,
424 hwc2display->release_fences)) {
425 ALOGE("Failed to present display");
426 return static_cast<int32_t>(HWC2::Error::BadDisplay);
427 }
428
429 *out_release_fence = DupFd(out_fence);
430
431 return 0;
432}
433
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200434#if __ANDROID_API__ >= 28
435
436static int32_t GetDisplayBrightnessSupport(hwc2_device_t * /*device*/,
437 hwc2_display_t /*display*/,
438 bool *out_support) {
439 ALOGV("GetDisplayBrightnessSupport");
440 *out_support = false; // Brightness support is not available
441 return static_cast<int32_t>(HWC2::Error::None);
442}
443
444static int32_t SetDisplayBrightness(hwc2_device_t * /*device*/,
445 hwc2_display_t /*display*/,
446 float /*brightness*/) {
447 ALOGV("SetDisplayBrightness");
448 return static_cast<int32_t>(HWC2::Error::Unsupported);
449}
450
451#endif
452
453#if __ANDROID_API__ >= 29
454static int32_t SetAutoLowLatencyMode(hwc2_device_t * /*device*/,
455 hwc2_display_t /*display*/, bool /*on*/) {
456 ALOGV("SetAutoLowLatencyMode");
457 return static_cast<int32_t>(HWC2::Error::Unsupported);
458}
459
460static int32_t GetSupportedContentTypes(
461 hwc2_device_t * /*device*/, hwc2_display_t /*display*/,
462 uint32_t *out_num_supported_content_types,
463 uint32_t * /*out_supported_content_types*/) {
464 ALOGV("GetSupportedContentTypes");
465 *out_num_supported_content_types = 0;
466 return static_cast<int32_t>(HWC2::Error::None);
467}
468#endif
469
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200470/* Layer functions */
471
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200472static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display,
473 hwc2_layer_t layer,
474 int32_t /*hwc2_blend_mode_t*/ mode) {
475 ALOGV("SetLayerBlendMode");
476 LOCK_COMPOSER(device);
477 GET_DISPLAY(display);
478 GET_LAYER(layer);
479
480 BufferBlendMode blend_mode{};
481 switch (static_cast<HWC2::BlendMode>(mode)) {
482 case HWC2::BlendMode::None:
483 blend_mode = BufferBlendMode::kNone;
484 break;
485 case HWC2::BlendMode::Premultiplied:
486 blend_mode = BufferBlendMode::kPreMult;
487 break;
488 case HWC2::BlendMode::Coverage:
489 blend_mode = BufferBlendMode::kCoverage;
490 break;
491 default:
492 ALOGE("Unknown blending mode b=%d", mode);
493 blend_mode = BufferBlendMode::kUndefined;
494 break;
495 }
496
497 HwcLayer::LayerProperties layer_properties;
498 layer_properties.blend_mode = blend_mode;
499
500 ilayer->SetLayerProperties(layer_properties);
501
502 return 0;
503}
504
505static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display,
506 hwc2_layer_t layer, buffer_handle_t buffer,
507 int32_t acquire_fence) {
508 ALOGV("SetLayerBuffer");
509 LOCK_COMPOSER(device);
510 GET_DISPLAY(display);
511 GET_LAYER(layer);
512
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200513 auto h2l = GetHwc2DeviceLayer(*ilayer);
514
515 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, acquire_fence);
516 if (!lp) {
517 ALOGV("Failed to process layer buffer");
518 return static_cast<int32_t>(HWC2::Error::BadLayer);
519 }
520
521 if (not_a_swapchain) {
522 ilayer->ClearSlots();
523 }
524
525 ilayer->SetLayerProperties(lp.value());
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200526
527 return 0;
528}
529
530static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display,
531 hwc2_layer_t layer,
532 int32_t /*android_dataspace_t*/ dataspace) {
533 ALOGV("SetLayerDataspace");
534 LOCK_COMPOSER(device);
535 GET_DISPLAY(display);
536 GET_LAYER(layer);
537
538 HwcLayer::LayerProperties layer_properties;
539 layer_properties.color_space = Hwc2ToColorSpace(dataspace);
540 layer_properties.sample_range = Hwc2ToSampleRange(dataspace);
541 ilayer->SetLayerProperties(layer_properties);
542 return 0;
543}
544
545static int32_t SetCursorPosition(hwc2_device_t * /*device*/,
546 hwc2_display_t /*display*/,
547 hwc2_layer_t /*layer*/, int32_t /*x*/,
548 int32_t /*y*/) {
549 ALOGV("SetCursorPosition");
550 return 0;
551}
552
553static int32_t SetLayerColor(hwc2_device_t * /*device*/,
554 hwc2_display_t /*display*/, hwc2_layer_t /*layer*/,
555 hwc_color_t /*color*/) {
556 ALOGV("SetLayerColor");
557 return 0;
558}
559
560static int32_t SetLayerCompositionType(hwc2_device_t *device,
561 hwc2_display_t display,
562 hwc2_layer_t layer,
563 int32_t /*hwc2_composition_t*/ type) {
564 ALOGV("SetLayerCompositionType");
565 LOCK_COMPOSER(device);
566 GET_DISPLAY(display);
567 GET_LAYER(layer);
568
569 HwcLayer::LayerProperties layer_properties;
570 layer_properties.composition_type = static_cast<HWC2::Composition>(type);
571 ilayer->SetLayerProperties(layer_properties);
572
573 return 0;
574}
575
576static int32_t SetLayerDisplayFrame(hwc2_device_t *device,
577 hwc2_display_t display, hwc2_layer_t layer,
578 hwc_rect_t frame) {
579 ALOGV("SetLayerDisplayFrame");
580 LOCK_COMPOSER(device);
581 GET_DISPLAY(display);
582 GET_LAYER(layer);
583
584 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200585 layer_properties.display_frame = {
586 .i_rect = DstRectInfo::IRect{.left = frame.left,
587 .top = frame.top,
588 .right = frame.right,
589 .bottom = frame.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200590 ilayer->SetLayerProperties(layer_properties);
591
592 return 0;
593}
594
595static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display,
596 hwc2_layer_t layer, float alpha) {
597 ALOGV("SetLayerPlaneAlpha");
598 LOCK_COMPOSER(device);
599 GET_DISPLAY(display);
600 GET_LAYER(layer);
601
602 HwcLayer::LayerProperties layer_properties;
603 layer_properties.alpha = alpha;
604 ilayer->SetLayerProperties(layer_properties);
605
606 return 0;
607}
608
609static int32_t SetLayerSidebandStream(hwc2_device_t * /*device*/,
610 hwc2_display_t /*display*/,
611 hwc2_layer_t /*layer*/,
612 const native_handle_t * /*stream*/) {
613 ALOGV("SetLayerSidebandStream");
614 return static_cast<int32_t>(HWC2::Error::Unsupported);
615}
616
617static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display,
618 hwc2_layer_t layer, hwc_frect_t crop) {
619 ALOGV("SetLayerSourceCrop");
620 LOCK_COMPOSER(device);
621 GET_DISPLAY(display);
622 GET_LAYER(layer);
623
624 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200625 layer_properties.source_crop = {
626 .f_rect = SrcRectInfo::FRect{.left = crop.left,
627 .top = crop.top,
628 .right = crop.right,
629 .bottom = crop.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200630 ilayer->SetLayerProperties(layer_properties);
631
632 return 0;
633}
634
635static int32_t SetLayerSurfaceDamage(hwc2_device_t * /*device*/,
636 hwc2_display_t /*display*/,
637 hwc2_layer_t /*layer*/,
638 hwc_region_t /*damage*/) {
639 ALOGV("SetLayerSurfaceDamage");
640 return 0;
641}
642
643static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display,
644 hwc2_layer_t layer, int32_t transform) {
645 ALOGV("SetLayerTransform");
646 LOCK_COMPOSER(device);
647 GET_DISPLAY(display);
648 GET_LAYER(layer);
649
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200650 HwcLayer::LayerProperties layer_properties;
Roman Stratiienkoda2fcf62025-01-23 17:47:03 +0200651 layer_properties.transform = {
652 .hflip = (transform & HAL_TRANSFORM_FLIP_H) != 0,
653 .vflip = (transform & HAL_TRANSFORM_FLIP_V) != 0,
654 .rotate90 = (transform & HAL_TRANSFORM_ROT_90) != 0,
655 };
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200656 ilayer->SetLayerProperties(layer_properties);
657
658 return 0;
659}
660
661static int32_t SetLayerVisibleRegion(hwc2_device_t * /*device*/,
662 hwc2_display_t /*display*/,
663 hwc2_layer_t /*layer*/,
664 hwc_region_t /*visible*/) {
665 ALOGV("SetLayerVisibleRegion");
666 return 0;
667}
668
669static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
670 hwc2_layer_t layer, uint32_t z) {
671 ALOGV("SetLayerZOrder");
672 LOCK_COMPOSER(device);
673 GET_DISPLAY(display);
674 GET_LAYER(layer);
675
676 HwcLayer::LayerProperties layer_properties;
677 layer_properties.z_order = z;
678 ilayer->SetLayerProperties(layer_properties);
679
680 return 0;
681}
682
683/* Entry point for the HWC2 API */
684// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
685
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200686static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
687 int32_t descriptor) {
688 auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
689 switch (func) {
690 // Device functions
691 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
692 return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
693 DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
694 &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
695 int32_t *, hwc2_display_t *>);
696 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
697 return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
698 DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
699 &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
700 case HWC2::FunctionDescriptor::Dump:
701 return ToHook<HWC2_PFN_DUMP>(
702 DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
703 uint32_t *, char *>);
704 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
705 return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
706 DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
707 &DrmHwcTwo::GetMaxVirtualDisplayCount>);
708 case HWC2::FunctionDescriptor::RegisterCallback:
709 return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
710 DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
711 &DrmHwcTwo::RegisterCallback, int32_t,
712 hwc2_callback_data_t, hwc2_function_pointer_t>);
713
714 // Display functions
715 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200716 return (hwc2_function_pointer_t)AcceptDisplayChanges;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200717 case HWC2::FunctionDescriptor::CreateLayer:
718 return ToHook<HWC2_PFN_CREATE_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200719 DisplayHook<decltype(&HwcDisplay::CreateLayer),
720 &HwcDisplay::CreateLayer, hwc2_layer_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200721 case HWC2::FunctionDescriptor::DestroyLayer:
722 return ToHook<HWC2_PFN_DESTROY_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200723 DisplayHook<decltype(&HwcDisplay::DestroyLayer),
724 &HwcDisplay::DestroyLayer, hwc2_layer_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200725 case HWC2::FunctionDescriptor::GetActiveConfig:
726 return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200727 DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
728 &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200729 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
730 return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200731 DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
732 &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
733 hwc2_layer_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200734 case HWC2::FunctionDescriptor::GetClientTargetSupport:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200735 return (hwc2_function_pointer_t)GetClientTargetSupport;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200736 case HWC2::FunctionDescriptor::GetColorModes:
737 return ToHook<HWC2_PFN_GET_COLOR_MODES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200738 DisplayHook<decltype(&HwcDisplay::GetColorModes),
739 &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200740 case HWC2::FunctionDescriptor::GetDisplayAttribute:
741 return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200742 DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
743 &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
744 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200745 case HWC2::FunctionDescriptor::GetDisplayConfigs:
746 return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
Drew Davenportf7e88332024-09-06 12:54:38 -0600747 DisplayHook<decltype(&HwcDisplay::LegacyGetDisplayConfigs),
748 &HwcDisplay::LegacyGetDisplayConfigs, uint32_t *,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200749 hwc2_config_t *>);
750 case HWC2::FunctionDescriptor::GetDisplayName:
751 return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200752 DisplayHook<decltype(&HwcDisplay::GetDisplayName),
753 &HwcDisplay::GetDisplayName, uint32_t *, char *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200754 case HWC2::FunctionDescriptor::GetDisplayRequests:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200755 return (hwc2_function_pointer_t)GetDisplayRequests;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200756 case HWC2::FunctionDescriptor::GetDisplayType:
757 return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200758 DisplayHook<decltype(&HwcDisplay::GetDisplayType),
759 &HwcDisplay::GetDisplayType, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200760 case HWC2::FunctionDescriptor::GetDozeSupport:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200761 return (hwc2_function_pointer_t)GetDozeSupport;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200762 case HWC2::FunctionDescriptor::GetHdrCapabilities:
763 return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200764 DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
765 &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
766 float *, float *, float *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200767 case HWC2::FunctionDescriptor::GetReleaseFences:
Roman Stratiienko72ff8c32025-02-09 00:48:44 +0200768 return (hwc2_function_pointer_t)GetReleaseFences;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200769 case HWC2::FunctionDescriptor::PresentDisplay:
Roman Stratiienko72ff8c32025-02-09 00:48:44 +0200770 return (hwc2_function_pointer_t)PresentDisplay;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200771 case HWC2::FunctionDescriptor::SetActiveConfig:
772 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200773 DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
774 &HwcDisplay::SetActiveConfig, hwc2_config_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200775 case HWC2::FunctionDescriptor::SetClientTarget:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200776 return (hwc2_function_pointer_t)SetClientTarget;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200777 case HWC2::FunctionDescriptor::SetColorMode:
778 return ToHook<HWC2_PFN_SET_COLOR_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200779 DisplayHook<decltype(&HwcDisplay::SetColorMode),
780 &HwcDisplay::SetColorMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200781 case HWC2::FunctionDescriptor::SetColorTransform:
782 return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200783 DisplayHook<decltype(&HwcDisplay::SetColorTransform),
784 &HwcDisplay::SetColorTransform, const float *, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200785 case HWC2::FunctionDescriptor::SetOutputBuffer:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200786 return (hwc2_function_pointer_t)SetOutputBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200787 case HWC2::FunctionDescriptor::SetPowerMode:
788 return ToHook<HWC2_PFN_SET_POWER_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200789 DisplayHook<decltype(&HwcDisplay::SetPowerMode),
790 &HwcDisplay::SetPowerMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200791 case HWC2::FunctionDescriptor::SetVsyncEnabled:
792 return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200793 DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
794 &HwcDisplay::SetVsyncEnabled, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200795 case HWC2::FunctionDescriptor::ValidateDisplay:
796 return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200797 DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
798 &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
Roman Stratiienko6b405052022-12-10 19:09:10 +0200799#if __ANDROID_API__ > 27
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200800 case HWC2::FunctionDescriptor::GetRenderIntents:
801 return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200802 DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
803 &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
804 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200805 case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
806 return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200807 DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
808 &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200809#endif
Roman Stratiienko6b405052022-12-10 19:09:10 +0200810#if __ANDROID_API__ > 28
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200811 case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
812 return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200813 DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
814 &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
815 uint32_t *, uint8_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200816 case HWC2::FunctionDescriptor::GetDisplayCapabilities:
817 return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200818 DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
819 &HwcDisplay::GetDisplayCapabilities, uint32_t *,
820 uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200821 case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200822 return (hwc2_function_pointer_t)GetDisplayBrightnessSupport;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200823 case HWC2::FunctionDescriptor::SetDisplayBrightness:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200824 return (hwc2_function_pointer_t)SetDisplayBrightness;
Roman Stratiienko6b405052022-12-10 19:09:10 +0200825#endif /* __ANDROID_API__ > 28 */
826#if __ANDROID_API__ > 29
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200827 case HWC2::FunctionDescriptor::GetDisplayConnectionType:
828 return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200829 DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
830 &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200831 case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
832 return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200833 DisplayHook<decltype(&HwcDisplay::GetDisplayVsyncPeriod),
834 &HwcDisplay::GetDisplayVsyncPeriod,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200835 hwc2_vsync_period_t *>);
836 case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
837 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200838 DisplayHook<decltype(&HwcDisplay::SetActiveConfigWithConstraints),
839 &HwcDisplay::SetActiveConfigWithConstraints,
840 hwc2_config_t, hwc_vsync_period_change_constraints_t *,
841 hwc_vsync_period_change_timeline_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200842 case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200843 return (hwc2_function_pointer_t)SetAutoLowLatencyMode;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200844 case HWC2::FunctionDescriptor::GetSupportedContentTypes:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200845 return (hwc2_function_pointer_t)GetSupportedContentTypes;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200846 case HWC2::FunctionDescriptor::SetContentType:
847 return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200848 DisplayHook<decltype(&HwcDisplay::SetContentType),
849 &HwcDisplay::SetContentType, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200850#endif
851 // Layer functions
852 case HWC2::FunctionDescriptor::SetCursorPosition:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200853 return (hwc2_function_pointer_t)SetCursorPosition;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200854 case HWC2::FunctionDescriptor::SetLayerBlendMode:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200855 return (hwc2_function_pointer_t)SetLayerBlendMode;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200856 case HWC2::FunctionDescriptor::SetLayerBuffer:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200857 return (hwc2_function_pointer_t)SetLayerBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200858 case HWC2::FunctionDescriptor::SetLayerColor:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200859 return (hwc2_function_pointer_t)SetLayerColor;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200860 case HWC2::FunctionDescriptor::SetLayerCompositionType:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200861 return (hwc2_function_pointer_t)SetLayerCompositionType;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200862 case HWC2::FunctionDescriptor::SetLayerDataspace:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200863 return (hwc2_function_pointer_t)SetLayerDataspace;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200864 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200865 return (hwc2_function_pointer_t)SetLayerDisplayFrame;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200866 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200867 return (hwc2_function_pointer_t)SetLayerPlaneAlpha;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200868 case HWC2::FunctionDescriptor::SetLayerSidebandStream:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200869 return (hwc2_function_pointer_t)SetLayerSidebandStream;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200870 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200871 return (hwc2_function_pointer_t)SetLayerSourceCrop;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200872 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200873 return (hwc2_function_pointer_t)SetLayerSurfaceDamage;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200874 case HWC2::FunctionDescriptor::SetLayerTransform:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200875 return (hwc2_function_pointer_t)SetLayerTransform;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200876 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200877 return (hwc2_function_pointer_t)SetLayerVisibleRegion;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200878 case HWC2::FunctionDescriptor::SetLayerZOrder:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200879 return (hwc2_function_pointer_t)SetLayerZOrder;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200880 case HWC2::FunctionDescriptor::Invalid:
881 default:
882 return nullptr;
883 }
884}
885
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200886// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
887
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200888static int HookDevOpen(const struct hw_module_t *module, const char *name,
889 struct hw_device_t **dev) {
890 if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
891 ALOGE("Invalid module name- %s", name);
892 return -EINVAL;
893 }
894
895 auto ctx = std::make_unique<Drmhwc2Device>();
896 if (!ctx) {
897 ALOGE("Failed to allocate DrmHwcTwo");
898 return -ENOMEM;
899 }
900
901 ctx->common.tag = HARDWARE_DEVICE_TAG;
902 ctx->common.version = HWC_DEVICE_API_VERSION_2_0;
903 ctx->common.close = HookDevClose;
904 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
905 ctx->common.module = (hw_module_t *)module;
906 ctx->getCapabilities = HookDevGetCapabilities;
907 ctx->getFunction = HookDevGetFunction;
908
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200909 *dev = &ctx.release()->common;
910
911 return 0;
912}
913
914} // namespace android
915
916// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
917static struct hw_module_methods_t hwc2_module_methods = {
918 .open = android::HookDevOpen,
919};
920
921// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
922hw_module_t HAL_MODULE_INFO_SYM = {
923 .tag = HARDWARE_MODULE_TAG,
924 .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
925 .id = HWC_HARDWARE_MODULE_ID,
926 .name = "DrmHwcTwo module",
927 .author = "The Android Open Source Project",
928 .methods = &hwc2_module_methods,
929 .dso = nullptr,
930 .reserved = {0},
931};