blob: 29831ff87de4487658d309d00820b6238ddb0fc2 [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 */
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200254static int32_t GetDisplayRequests(hwc2_device_t * /*device*/,
255 hwc2_display_t /*display*/,
256 int32_t * /* out_display_requests */,
257 uint32_t *out_num_elements,
258 hwc2_layer_t * /*out_layers*/,
259 int32_t * /*out_layer_requests*/) {
260 ALOGV("GetDisplayRequests");
261
262 *out_num_elements = 0;
263 return 0;
264}
265
266static int32_t GetDozeSupport(hwc2_device_t * /*device*/,
267 hwc2_display_t /*display*/,
268 int32_t *out_support) {
269 ALOGV("GetDozeSupport");
270 *out_support = 0; // Doze support is not available
271 return 0;
272}
273
274static int32_t GetClientTargetSupport(hwc2_device_t * /*device*/,
275 hwc2_display_t /*display*/,
276 uint32_t /*width*/, uint32_t /*height*/,
277 int32_t /*format*/, int32_t dataspace) {
278 ALOGV("GetClientTargetSupport");
279
280 if (dataspace != HAL_DATASPACE_UNKNOWN)
281 return static_cast<int32_t>(HWC2::Error::Unsupported);
282
283 return 0;
284}
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200285
286static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
287 buffer_handle_t target, int32_t acquire_fence,
288 int32_t dataspace, hwc_region_t /*damage*/) {
289 ALOGV("SetClientTarget");
290 LOCK_COMPOSER(device);
291 GET_DISPLAY(display);
292
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200293 auto &client_layer = idisplay->GetClientLayer();
294 auto h2l = GetHwc2DeviceLayer(client_layer);
295 if (!h2l) {
296 client_layer.SetFrontendPrivateData(std::make_shared<Hwc2DeviceLayer>());
297 }
298
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200299 if (target == nullptr) {
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200300 client_layer.ClearSlots();
301 h2l->SwChainClearCache();
302
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200303 return 0;
304 }
305
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200306 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(target, acquire_fence);
307 if (!lp) {
308 ALOGE("Failed to process client target");
309 return static_cast<int32_t>(HWC2::Error::BadLayer);
310 }
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200311
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200312 if (not_a_swapchain) {
313 client_layer.ClearSlots();
314 }
315
316 lp->color_space = Hwc2ToColorSpace(dataspace);
317 lp->sample_range = Hwc2ToSampleRange(dataspace);
318
319 idisplay->GetClientLayer().SetLayerProperties(lp.value());
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200320
321 return 0;
322}
323
324static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
325 buffer_handle_t buffer, int32_t release_fence) {
326 ALOGV("SetOutputBuffer");
327 LOCK_COMPOSER(device);
328 GET_DISPLAY(display);
329
330 auto &writeback_layer = idisplay->GetWritebackLayer();
331 if (!writeback_layer) {
332 ALOGE("Writeback layer is not available");
333 return static_cast<int32_t>(HWC2::Error::BadLayer);
334 }
335
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200336 auto h2l = GetHwc2DeviceLayer(*writeback_layer);
337 if (!h2l) {
338 writeback_layer->SetFrontendPrivateData(
339 std::make_shared<Hwc2DeviceLayer>());
340 }
341
342 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, release_fence);
343 if (!lp) {
344 ALOGE("Failed to process output buffer");
345 return static_cast<int32_t>(HWC2::Error::BadLayer);
346 }
347
348 if (not_a_swapchain) {
349 writeback_layer->ClearSlots();
350 }
351
352 writeback_layer->SetLayerProperties(lp.value());
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200353
354 return 0;
355}
356
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200357static int32_t AcceptDisplayChanges(hwc2_device_t *device,
358 hwc2_display_t display) {
359 ALOGV("AcceptDisplayChanges");
360 LOCK_COMPOSER(device);
361 GET_DISPLAY(display);
362
363 idisplay->AcceptValidatedComposition();
364
365 return 0;
366}
367
368#if __ANDROID_API__ >= 28
369
370static int32_t GetDisplayBrightnessSupport(hwc2_device_t * /*device*/,
371 hwc2_display_t /*display*/,
372 bool *out_support) {
373 ALOGV("GetDisplayBrightnessSupport");
374 *out_support = false; // Brightness support is not available
375 return static_cast<int32_t>(HWC2::Error::None);
376}
377
378static int32_t SetDisplayBrightness(hwc2_device_t * /*device*/,
379 hwc2_display_t /*display*/,
380 float /*brightness*/) {
381 ALOGV("SetDisplayBrightness");
382 return static_cast<int32_t>(HWC2::Error::Unsupported);
383}
384
385#endif
386
387#if __ANDROID_API__ >= 29
388static int32_t SetAutoLowLatencyMode(hwc2_device_t * /*device*/,
389 hwc2_display_t /*display*/, bool /*on*/) {
390 ALOGV("SetAutoLowLatencyMode");
391 return static_cast<int32_t>(HWC2::Error::Unsupported);
392}
393
394static int32_t GetSupportedContentTypes(
395 hwc2_device_t * /*device*/, hwc2_display_t /*display*/,
396 uint32_t *out_num_supported_content_types,
397 uint32_t * /*out_supported_content_types*/) {
398 ALOGV("GetSupportedContentTypes");
399 *out_num_supported_content_types = 0;
400 return static_cast<int32_t>(HWC2::Error::None);
401}
402#endif
403
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200404/* Layer functions */
405
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200406static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display,
407 hwc2_layer_t layer,
408 int32_t /*hwc2_blend_mode_t*/ mode) {
409 ALOGV("SetLayerBlendMode");
410 LOCK_COMPOSER(device);
411 GET_DISPLAY(display);
412 GET_LAYER(layer);
413
414 BufferBlendMode blend_mode{};
415 switch (static_cast<HWC2::BlendMode>(mode)) {
416 case HWC2::BlendMode::None:
417 blend_mode = BufferBlendMode::kNone;
418 break;
419 case HWC2::BlendMode::Premultiplied:
420 blend_mode = BufferBlendMode::kPreMult;
421 break;
422 case HWC2::BlendMode::Coverage:
423 blend_mode = BufferBlendMode::kCoverage;
424 break;
425 default:
426 ALOGE("Unknown blending mode b=%d", mode);
427 blend_mode = BufferBlendMode::kUndefined;
428 break;
429 }
430
431 HwcLayer::LayerProperties layer_properties;
432 layer_properties.blend_mode = blend_mode;
433
434 ilayer->SetLayerProperties(layer_properties);
435
436 return 0;
437}
438
439static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display,
440 hwc2_layer_t layer, buffer_handle_t buffer,
441 int32_t acquire_fence) {
442 ALOGV("SetLayerBuffer");
443 LOCK_COMPOSER(device);
444 GET_DISPLAY(display);
445 GET_LAYER(layer);
446
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200447 auto h2l = GetHwc2DeviceLayer(*ilayer);
448
449 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, acquire_fence);
450 if (!lp) {
451 ALOGV("Failed to process layer buffer");
452 return static_cast<int32_t>(HWC2::Error::BadLayer);
453 }
454
455 if (not_a_swapchain) {
456 ilayer->ClearSlots();
457 }
458
459 ilayer->SetLayerProperties(lp.value());
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200460
461 return 0;
462}
463
464static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display,
465 hwc2_layer_t layer,
466 int32_t /*android_dataspace_t*/ dataspace) {
467 ALOGV("SetLayerDataspace");
468 LOCK_COMPOSER(device);
469 GET_DISPLAY(display);
470 GET_LAYER(layer);
471
472 HwcLayer::LayerProperties layer_properties;
473 layer_properties.color_space = Hwc2ToColorSpace(dataspace);
474 layer_properties.sample_range = Hwc2ToSampleRange(dataspace);
475 ilayer->SetLayerProperties(layer_properties);
476 return 0;
477}
478
479static int32_t SetCursorPosition(hwc2_device_t * /*device*/,
480 hwc2_display_t /*display*/,
481 hwc2_layer_t /*layer*/, int32_t /*x*/,
482 int32_t /*y*/) {
483 ALOGV("SetCursorPosition");
484 return 0;
485}
486
487static int32_t SetLayerColor(hwc2_device_t * /*device*/,
488 hwc2_display_t /*display*/, hwc2_layer_t /*layer*/,
489 hwc_color_t /*color*/) {
490 ALOGV("SetLayerColor");
491 return 0;
492}
493
494static int32_t SetLayerCompositionType(hwc2_device_t *device,
495 hwc2_display_t display,
496 hwc2_layer_t layer,
497 int32_t /*hwc2_composition_t*/ type) {
498 ALOGV("SetLayerCompositionType");
499 LOCK_COMPOSER(device);
500 GET_DISPLAY(display);
501 GET_LAYER(layer);
502
503 HwcLayer::LayerProperties layer_properties;
504 layer_properties.composition_type = static_cast<HWC2::Composition>(type);
505 ilayer->SetLayerProperties(layer_properties);
506
507 return 0;
508}
509
510static int32_t SetLayerDisplayFrame(hwc2_device_t *device,
511 hwc2_display_t display, hwc2_layer_t layer,
512 hwc_rect_t frame) {
513 ALOGV("SetLayerDisplayFrame");
514 LOCK_COMPOSER(device);
515 GET_DISPLAY(display);
516 GET_LAYER(layer);
517
518 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200519 layer_properties.display_frame = {
520 .i_rect = DstRectInfo::IRect{.left = frame.left,
521 .top = frame.top,
522 .right = frame.right,
523 .bottom = frame.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200524 ilayer->SetLayerProperties(layer_properties);
525
526 return 0;
527}
528
529static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display,
530 hwc2_layer_t layer, float alpha) {
531 ALOGV("SetLayerPlaneAlpha");
532 LOCK_COMPOSER(device);
533 GET_DISPLAY(display);
534 GET_LAYER(layer);
535
536 HwcLayer::LayerProperties layer_properties;
537 layer_properties.alpha = alpha;
538 ilayer->SetLayerProperties(layer_properties);
539
540 return 0;
541}
542
543static int32_t SetLayerSidebandStream(hwc2_device_t * /*device*/,
544 hwc2_display_t /*display*/,
545 hwc2_layer_t /*layer*/,
546 const native_handle_t * /*stream*/) {
547 ALOGV("SetLayerSidebandStream");
548 return static_cast<int32_t>(HWC2::Error::Unsupported);
549}
550
551static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display,
552 hwc2_layer_t layer, hwc_frect_t crop) {
553 ALOGV("SetLayerSourceCrop");
554 LOCK_COMPOSER(device);
555 GET_DISPLAY(display);
556 GET_LAYER(layer);
557
558 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200559 layer_properties.source_crop = {
560 .f_rect = SrcRectInfo::FRect{.left = crop.left,
561 .top = crop.top,
562 .right = crop.right,
563 .bottom = crop.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200564 ilayer->SetLayerProperties(layer_properties);
565
566 return 0;
567}
568
569static int32_t SetLayerSurfaceDamage(hwc2_device_t * /*device*/,
570 hwc2_display_t /*display*/,
571 hwc2_layer_t /*layer*/,
572 hwc_region_t /*damage*/) {
573 ALOGV("SetLayerSurfaceDamage");
574 return 0;
575}
576
577static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display,
578 hwc2_layer_t layer, int32_t transform) {
579 ALOGV("SetLayerTransform");
580 LOCK_COMPOSER(device);
581 GET_DISPLAY(display);
582 GET_LAYER(layer);
583
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200584 HwcLayer::LayerProperties layer_properties;
Roman Stratiienkoda2fcf62025-01-23 17:47:03 +0200585 layer_properties.transform = {
586 .hflip = (transform & HAL_TRANSFORM_FLIP_H) != 0,
587 .vflip = (transform & HAL_TRANSFORM_FLIP_V) != 0,
588 .rotate90 = (transform & HAL_TRANSFORM_ROT_90) != 0,
589 };
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200590 ilayer->SetLayerProperties(layer_properties);
591
592 return 0;
593}
594
595static int32_t SetLayerVisibleRegion(hwc2_device_t * /*device*/,
596 hwc2_display_t /*display*/,
597 hwc2_layer_t /*layer*/,
598 hwc_region_t /*visible*/) {
599 ALOGV("SetLayerVisibleRegion");
600 return 0;
601}
602
603static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
604 hwc2_layer_t layer, uint32_t z) {
605 ALOGV("SetLayerZOrder");
606 LOCK_COMPOSER(device);
607 GET_DISPLAY(display);
608 GET_LAYER(layer);
609
610 HwcLayer::LayerProperties layer_properties;
611 layer_properties.z_order = z;
612 ilayer->SetLayerProperties(layer_properties);
613
614 return 0;
615}
616
617/* Entry point for the HWC2 API */
618// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
619
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200620static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
621 int32_t descriptor) {
622 auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
623 switch (func) {
624 // Device functions
625 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
626 return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
627 DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
628 &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
629 int32_t *, hwc2_display_t *>);
630 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
631 return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
632 DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
633 &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
634 case HWC2::FunctionDescriptor::Dump:
635 return ToHook<HWC2_PFN_DUMP>(
636 DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
637 uint32_t *, char *>);
638 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
639 return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
640 DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
641 &DrmHwcTwo::GetMaxVirtualDisplayCount>);
642 case HWC2::FunctionDescriptor::RegisterCallback:
643 return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
644 DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
645 &DrmHwcTwo::RegisterCallback, int32_t,
646 hwc2_callback_data_t, hwc2_function_pointer_t>);
647
648 // Display functions
649 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200650 return (hwc2_function_pointer_t)AcceptDisplayChanges;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200651 case HWC2::FunctionDescriptor::CreateLayer:
652 return ToHook<HWC2_PFN_CREATE_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200653 DisplayHook<decltype(&HwcDisplay::CreateLayer),
654 &HwcDisplay::CreateLayer, hwc2_layer_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200655 case HWC2::FunctionDescriptor::DestroyLayer:
656 return ToHook<HWC2_PFN_DESTROY_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200657 DisplayHook<decltype(&HwcDisplay::DestroyLayer),
658 &HwcDisplay::DestroyLayer, hwc2_layer_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200659 case HWC2::FunctionDescriptor::GetActiveConfig:
660 return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200661 DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
662 &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200663 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
664 return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200665 DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
666 &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
667 hwc2_layer_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200668 case HWC2::FunctionDescriptor::GetClientTargetSupport:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200669 return (hwc2_function_pointer_t)GetClientTargetSupport;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200670 case HWC2::FunctionDescriptor::GetColorModes:
671 return ToHook<HWC2_PFN_GET_COLOR_MODES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200672 DisplayHook<decltype(&HwcDisplay::GetColorModes),
673 &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200674 case HWC2::FunctionDescriptor::GetDisplayAttribute:
675 return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200676 DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
677 &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
678 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200679 case HWC2::FunctionDescriptor::GetDisplayConfigs:
680 return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
Drew Davenportf7e88332024-09-06 12:54:38 -0600681 DisplayHook<decltype(&HwcDisplay::LegacyGetDisplayConfigs),
682 &HwcDisplay::LegacyGetDisplayConfigs, uint32_t *,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200683 hwc2_config_t *>);
684 case HWC2::FunctionDescriptor::GetDisplayName:
685 return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200686 DisplayHook<decltype(&HwcDisplay::GetDisplayName),
687 &HwcDisplay::GetDisplayName, uint32_t *, char *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200688 case HWC2::FunctionDescriptor::GetDisplayRequests:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200689 return (hwc2_function_pointer_t)GetDisplayRequests;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200690 case HWC2::FunctionDescriptor::GetDisplayType:
691 return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200692 DisplayHook<decltype(&HwcDisplay::GetDisplayType),
693 &HwcDisplay::GetDisplayType, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200694 case HWC2::FunctionDescriptor::GetDozeSupport:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200695 return (hwc2_function_pointer_t)GetDozeSupport;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200696 case HWC2::FunctionDescriptor::GetHdrCapabilities:
697 return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200698 DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
699 &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
700 float *, float *, float *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200701 case HWC2::FunctionDescriptor::GetReleaseFences:
702 return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200703 DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
704 &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
705 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200706 case HWC2::FunctionDescriptor::PresentDisplay:
707 return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200708 DisplayHook<decltype(&HwcDisplay::PresentDisplay),
709 &HwcDisplay::PresentDisplay, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200710 case HWC2::FunctionDescriptor::SetActiveConfig:
711 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200712 DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
713 &HwcDisplay::SetActiveConfig, hwc2_config_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200714 case HWC2::FunctionDescriptor::SetClientTarget:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200715 return (hwc2_function_pointer_t)SetClientTarget;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200716 case HWC2::FunctionDescriptor::SetColorMode:
717 return ToHook<HWC2_PFN_SET_COLOR_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200718 DisplayHook<decltype(&HwcDisplay::SetColorMode),
719 &HwcDisplay::SetColorMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200720 case HWC2::FunctionDescriptor::SetColorTransform:
721 return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200722 DisplayHook<decltype(&HwcDisplay::SetColorTransform),
723 &HwcDisplay::SetColorTransform, const float *, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200724 case HWC2::FunctionDescriptor::SetOutputBuffer:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200725 return (hwc2_function_pointer_t)SetOutputBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200726 case HWC2::FunctionDescriptor::SetPowerMode:
727 return ToHook<HWC2_PFN_SET_POWER_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200728 DisplayHook<decltype(&HwcDisplay::SetPowerMode),
729 &HwcDisplay::SetPowerMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200730 case HWC2::FunctionDescriptor::SetVsyncEnabled:
731 return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200732 DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
733 &HwcDisplay::SetVsyncEnabled, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200734 case HWC2::FunctionDescriptor::ValidateDisplay:
735 return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200736 DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
737 &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
Roman Stratiienko6b405052022-12-10 19:09:10 +0200738#if __ANDROID_API__ > 27
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200739 case HWC2::FunctionDescriptor::GetRenderIntents:
740 return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200741 DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
742 &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
743 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200744 case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
745 return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200746 DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
747 &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200748#endif
Roman Stratiienko6b405052022-12-10 19:09:10 +0200749#if __ANDROID_API__ > 28
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200750 case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
751 return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200752 DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
753 &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
754 uint32_t *, uint8_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200755 case HWC2::FunctionDescriptor::GetDisplayCapabilities:
756 return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200757 DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
758 &HwcDisplay::GetDisplayCapabilities, uint32_t *,
759 uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200760 case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200761 return (hwc2_function_pointer_t)GetDisplayBrightnessSupport;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200762 case HWC2::FunctionDescriptor::SetDisplayBrightness:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200763 return (hwc2_function_pointer_t)SetDisplayBrightness;
Roman Stratiienko6b405052022-12-10 19:09:10 +0200764#endif /* __ANDROID_API__ > 28 */
765#if __ANDROID_API__ > 29
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200766 case HWC2::FunctionDescriptor::GetDisplayConnectionType:
767 return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200768 DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
769 &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200770 case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
771 return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200772 DisplayHook<decltype(&HwcDisplay::GetDisplayVsyncPeriod),
773 &HwcDisplay::GetDisplayVsyncPeriod,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200774 hwc2_vsync_period_t *>);
775 case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
776 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200777 DisplayHook<decltype(&HwcDisplay::SetActiveConfigWithConstraints),
778 &HwcDisplay::SetActiveConfigWithConstraints,
779 hwc2_config_t, hwc_vsync_period_change_constraints_t *,
780 hwc_vsync_period_change_timeline_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200781 case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200782 return (hwc2_function_pointer_t)SetAutoLowLatencyMode;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200783 case HWC2::FunctionDescriptor::GetSupportedContentTypes:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200784 return (hwc2_function_pointer_t)GetSupportedContentTypes;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200785 case HWC2::FunctionDescriptor::SetContentType:
786 return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200787 DisplayHook<decltype(&HwcDisplay::SetContentType),
788 &HwcDisplay::SetContentType, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200789#endif
790 // Layer functions
791 case HWC2::FunctionDescriptor::SetCursorPosition:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200792 return (hwc2_function_pointer_t)SetCursorPosition;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200793 case HWC2::FunctionDescriptor::SetLayerBlendMode:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200794 return (hwc2_function_pointer_t)SetLayerBlendMode;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200795 case HWC2::FunctionDescriptor::SetLayerBuffer:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200796 return (hwc2_function_pointer_t)SetLayerBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200797 case HWC2::FunctionDescriptor::SetLayerColor:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200798 return (hwc2_function_pointer_t)SetLayerColor;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200799 case HWC2::FunctionDescriptor::SetLayerCompositionType:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200800 return (hwc2_function_pointer_t)SetLayerCompositionType;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200801 case HWC2::FunctionDescriptor::SetLayerDataspace:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200802 return (hwc2_function_pointer_t)SetLayerDataspace;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200803 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200804 return (hwc2_function_pointer_t)SetLayerDisplayFrame;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200805 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200806 return (hwc2_function_pointer_t)SetLayerPlaneAlpha;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200807 case HWC2::FunctionDescriptor::SetLayerSidebandStream:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200808 return (hwc2_function_pointer_t)SetLayerSidebandStream;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200809 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200810 return (hwc2_function_pointer_t)SetLayerSourceCrop;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200811 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200812 return (hwc2_function_pointer_t)SetLayerSurfaceDamage;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200813 case HWC2::FunctionDescriptor::SetLayerTransform:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200814 return (hwc2_function_pointer_t)SetLayerTransform;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200815 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200816 return (hwc2_function_pointer_t)SetLayerVisibleRegion;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200817 case HWC2::FunctionDescriptor::SetLayerZOrder:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200818 return (hwc2_function_pointer_t)SetLayerZOrder;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200819 case HWC2::FunctionDescriptor::Invalid:
820 default:
821 return nullptr;
822 }
823}
824
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200825// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
826
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200827static int HookDevOpen(const struct hw_module_t *module, const char *name,
828 struct hw_device_t **dev) {
829 if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
830 ALOGE("Invalid module name- %s", name);
831 return -EINVAL;
832 }
833
834 auto ctx = std::make_unique<Drmhwc2Device>();
835 if (!ctx) {
836 ALOGE("Failed to allocate DrmHwcTwo");
837 return -ENOMEM;
838 }
839
840 ctx->common.tag = HARDWARE_DEVICE_TAG;
841 ctx->common.version = HWC_DEVICE_API_VERSION_2_0;
842 ctx->common.close = HookDevClose;
843 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
844 ctx->common.module = (hw_module_t *)module;
845 ctx->getCapabilities = HookDevGetCapabilities;
846 ctx->getFunction = HookDevGetFunction;
847
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200848 *dev = &ctx.release()->common;
849
850 return 0;
851}
852
853} // namespace android
854
855// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
856static struct hw_module_methods_t hwc2_module_methods = {
857 .open = android::HookDevOpen,
858};
859
860// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
861hw_module_t HAL_MODULE_INFO_SYM = {
862 .tag = HARDWARE_MODULE_TAG,
863 .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
864 .id = HWC_HARDWARE_MODULE_ID,
865 .name = "DrmHwcTwo module",
866 .author = "The Android Open Source Project",
867 .methods = &hwc2_module_methods,
868 .dso = nullptr,
869 .reserved = {0},
870};