blob: 72d0aa958d83c958da9a99a359cef773a0c11956 [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;
Roman Stratiienko34c50ce2025-02-09 02:33:58 +020055 std::vector<HwcDisplay::ChangedLayer> changed_layers;
Roman Stratiienko72ff8c32025-02-09 00:48:44 +020056};
57
58static auto GetHwc2DeviceDisplay(HwcDisplay &display)
59 -> std::shared_ptr<Hwc2DeviceDisplay> {
60 auto frontend_private_data = display.GetFrontendPrivateData();
61 if (!frontend_private_data) {
62 frontend_private_data = std::make_shared<Hwc2DeviceDisplay>();
63 display.SetFrontendPrivateData(frontend_private_data);
64 }
65 return std::static_pointer_cast<Hwc2DeviceDisplay>(frontend_private_data);
66}
67
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +020068class Hwc2DeviceLayer : public FrontendLayerBase {
69 public:
70 auto HandleNextBuffer(buffer_handle_t buffer_handle, int32_t fence_fd)
71 -> std::pair<std::optional<HwcLayer::LayerProperties>,
72 bool /* not a swapchain */> {
73 auto slot = GetSlotNumber(buffer_handle);
74
75 if (invalid_) {
76 return std::make_pair(std::nullopt, true);
77 }
78
79 bool buffer_provided = false;
80 bool not_a_swapchain = true;
81 int32_t slot_id = 0;
82
83 if (slot.has_value()) {
84 buffer_provided = swchain_slots_[slot.value()];
85 slot_id = slot.value();
86 not_a_swapchain = true;
87 }
88
89 HwcLayer::LayerProperties lp;
90 if (!buffer_provided) {
91 auto bo_info = BufferInfoGetter::GetInstance()->GetBoInfo(buffer_handle);
92 if (!bo_info) {
93 invalid_ = true;
94 return std::make_pair(std::nullopt, true);
95 }
96
97 lp.slot_buffer = {
98 .slot_id = slot_id,
99 .bi = bo_info,
100 };
101 }
102 lp.active_slot = {
103 .slot_id = slot_id,
104 .fence = MakeSharedFd(fence_fd),
105 };
106
107 return std::make_pair(lp, not_a_swapchain);
108 }
109
110 void SwChainClearCache() {
111 swchain_lookup_table_.clear();
112 swchain_slots_.clear();
113 swchain_reassembled_ = false;
114 }
115
116 private:
117 auto GetSlotNumber(buffer_handle_t buffer_handle) -> std::optional<int32_t> {
118 auto unique_id = BufferInfoGetter::GetInstance()->GetUniqueId(
119 buffer_handle);
120 if (!unique_id) {
121 ALOGE("Failed to get unique id for buffer handle %p", buffer_handle);
122 return std::nullopt;
123 }
124
125 if (swchain_lookup_table_.count(*unique_id) == 0) {
126 SwChainReassemble(*unique_id);
127 return std::nullopt;
128 }
129
130 if (!swchain_reassembled_) {
131 return std::nullopt;
132 }
133
134 return swchain_lookup_table_[*unique_id];
135 }
136
137 void SwChainReassemble(BufferUniqueId unique_id) {
138 if (swchain_lookup_table_.count(unique_id) != 0) {
139 if (swchain_lookup_table_[unique_id] ==
140 int(swchain_lookup_table_.size()) - 1) {
141 /* Skip same buffer */
142 return;
143 }
144 if (swchain_lookup_table_[unique_id] == 0) {
145 swchain_reassembled_ = true;
146 return;
147 }
148 /* Tracking error */
149 SwChainClearCache();
150 return;
151 }
152
153 swchain_lookup_table_[unique_id] = int(swchain_lookup_table_.size());
154 }
155
156 bool invalid_{}; /* Layer is invalid and should be skipped */
157 std::map<BufferUniqueId, int /*slot*/> swchain_lookup_table_;
158 std::map<int /*slot*/, bool /*buffer_provided*/> swchain_slots_;
159 bool swchain_reassembled_{};
160};
161
162static auto GetHwc2DeviceLayer(HwcLayer &layer)
163 -> std::shared_ptr<Hwc2DeviceLayer> {
164 auto frontend_private_data = layer.GetFrontendPrivateData();
165 if (!frontend_private_data) {
166 frontend_private_data = std::make_shared<Hwc2DeviceLayer>();
167 layer.SetFrontendPrivateData(frontend_private_data);
168 }
169 return std::static_pointer_cast<Hwc2DeviceLayer>(frontend_private_data);
170}
171
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200172struct Drmhwc2Device : hwc2_device {
173 DrmHwcTwo drmhwctwo;
174};
175
176static DrmHwcTwo *ToDrmHwcTwo(hwc2_device_t *dev) {
177 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast):
178 return &static_cast<Drmhwc2Device *>(dev)->drmhwctwo;
179}
180
181template <typename PFN, typename T>
182static hwc2_function_pointer_t ToHook(T function) {
Roman Stratiienko6275b4a2025-01-24 15:50:40 +0200183 // NOLINTNEXTLINE(modernize-type-traits): ToHook is going to be removed
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200184 static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
185 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast):
186 return reinterpret_cast<hwc2_function_pointer_t>(function);
187}
188
189template <typename T, typename HookType, HookType func, typename... Args>
190static T DeviceHook(hwc2_device_t *dev, Args... args) {
Roman Stratiienko13017522022-01-17 10:35:34 +0200191 ALOGV("Device hook: %s", GetFuncName(__PRETTY_FUNCTION__).c_str());
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200192 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
Roman Stratiienko9e2a2cd2022-12-28 20:47:29 +0200193 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200194 return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
195}
196
197template <typename HookType, HookType func, typename... Args>
198static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
199 Args... args) {
Roman Stratiienko13017522022-01-17 10:35:34 +0200200 ALOGV("Display #%" PRIu64 " hook: %s", display_handle,
201 GetFuncName(__PRETTY_FUNCTION__).c_str());
Roman Stratiienko74923582022-01-17 11:24:21 +0200202 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
Roman Stratiienko9e2a2cd2022-12-28 20:47:29 +0200203 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
Roman Stratiienko938a7422022-01-29 00:10:07 +0200204 auto *display = hwc->GetDisplay(display_handle);
205 if (display == nullptr)
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200206 return static_cast<int32_t>(HWC2::Error::BadDisplay);
207
208 return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...));
209}
210
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200211static int HookDevClose(hw_device_t *dev) {
212 // NOLINTNEXTLINE (cppcoreguidelines-pro-type-reinterpret-cast): Safe
213 auto *hwc2_dev = reinterpret_cast<hwc2_device_t *>(dev);
Roman Stratiienkoa7913de2022-10-20 13:18:57 +0300214 const std::unique_ptr<DrmHwcTwo> ctx(ToDrmHwcTwo(hwc2_dev));
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200215 return 0;
216}
217
218static void HookDevGetCapabilities(hwc2_device_t * /*dev*/, uint32_t *out_count,
219 int32_t * /*out_capabilities*/) {
220 *out_count = 0;
221}
222
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200223// NOLINTBEGIN(cppcoreguidelines-macro-usage)
224
225#define LOCK_COMPOSER(dev) \
226 auto *ihwc = ToDrmHwcTwo(dev); \
227 const std::unique_lock lock(ihwc->GetResMan().GetMainLock());
228
229#define GET_DISPLAY(display_id) \
230 auto *idisplay = ihwc->GetDisplay(display_id); \
231 if (!idisplay) \
232 return static_cast<int32_t>(HWC2::Error::BadDisplay);
233
234#define GET_LAYER(layer_id) \
235 auto *ilayer = idisplay->get_layer(layer_id); \
236 if (!ilayer) \
237 return static_cast<int32_t>(HWC2::Error::BadLayer);
238
239// NOLINTEND(cppcoreguidelines-macro-usage)
240
241static BufferColorSpace Hwc2ToColorSpace(int32_t dataspace) {
242 switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
243 case HAL_DATASPACE_STANDARD_BT709:
244 return BufferColorSpace::kItuRec709;
245 case HAL_DATASPACE_STANDARD_BT601_625:
246 case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
247 case HAL_DATASPACE_STANDARD_BT601_525:
248 case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
249 return BufferColorSpace::kItuRec601;
250 case HAL_DATASPACE_STANDARD_BT2020:
251 case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
252 return BufferColorSpace::kItuRec2020;
253 default:
254 return BufferColorSpace::kUndefined;
255 }
256}
257
258static BufferSampleRange Hwc2ToSampleRange(int32_t dataspace) {
259 switch (dataspace & HAL_DATASPACE_RANGE_MASK) {
260 case HAL_DATASPACE_RANGE_FULL:
261 return BufferSampleRange::kFullRange;
262 case HAL_DATASPACE_RANGE_LIMITED:
263 return BufferSampleRange::kLimitedRange;
264 default:
265 return BufferSampleRange::kUndefined;
266 }
267}
268
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200269/* Display functions */
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200270static int32_t GetDisplayRequests(hwc2_device_t * /*device*/,
271 hwc2_display_t /*display*/,
272 int32_t * /* out_display_requests */,
273 uint32_t *out_num_elements,
274 hwc2_layer_t * /*out_layers*/,
275 int32_t * /*out_layer_requests*/) {
276 ALOGV("GetDisplayRequests");
277
278 *out_num_elements = 0;
279 return 0;
280}
281
282static int32_t GetDozeSupport(hwc2_device_t * /*device*/,
283 hwc2_display_t /*display*/,
284 int32_t *out_support) {
285 ALOGV("GetDozeSupport");
286 *out_support = 0; // Doze support is not available
287 return 0;
288}
289
290static int32_t GetClientTargetSupport(hwc2_device_t * /*device*/,
291 hwc2_display_t /*display*/,
292 uint32_t /*width*/, uint32_t /*height*/,
293 int32_t /*format*/, int32_t dataspace) {
294 ALOGV("GetClientTargetSupport");
295
296 if (dataspace != HAL_DATASPACE_UNKNOWN)
297 return static_cast<int32_t>(HWC2::Error::Unsupported);
298
299 return 0;
300}
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200301
302static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
303 buffer_handle_t target, int32_t acquire_fence,
304 int32_t dataspace, hwc_region_t /*damage*/) {
305 ALOGV("SetClientTarget");
306 LOCK_COMPOSER(device);
307 GET_DISPLAY(display);
308
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200309 auto &client_layer = idisplay->GetClientLayer();
310 auto h2l = GetHwc2DeviceLayer(client_layer);
311 if (!h2l) {
312 client_layer.SetFrontendPrivateData(std::make_shared<Hwc2DeviceLayer>());
313 }
314
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200315 if (target == nullptr) {
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200316 client_layer.ClearSlots();
317 h2l->SwChainClearCache();
318
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200319 return 0;
320 }
321
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200322 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(target, acquire_fence);
323 if (!lp) {
324 ALOGE("Failed to process client target");
325 return static_cast<int32_t>(HWC2::Error::BadLayer);
326 }
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200327
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200328 if (not_a_swapchain) {
329 client_layer.ClearSlots();
330 }
331
332 lp->color_space = Hwc2ToColorSpace(dataspace);
333 lp->sample_range = Hwc2ToSampleRange(dataspace);
334
335 idisplay->GetClientLayer().SetLayerProperties(lp.value());
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200336
337 return 0;
338}
339
340static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
341 buffer_handle_t buffer, int32_t release_fence) {
342 ALOGV("SetOutputBuffer");
343 LOCK_COMPOSER(device);
344 GET_DISPLAY(display);
345
346 auto &writeback_layer = idisplay->GetWritebackLayer();
347 if (!writeback_layer) {
348 ALOGE("Writeback layer is not available");
349 return static_cast<int32_t>(HWC2::Error::BadLayer);
350 }
351
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200352 auto h2l = GetHwc2DeviceLayer(*writeback_layer);
353 if (!h2l) {
354 writeback_layer->SetFrontendPrivateData(
355 std::make_shared<Hwc2DeviceLayer>());
356 }
357
358 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, release_fence);
359 if (!lp) {
360 ALOGE("Failed to process output buffer");
361 return static_cast<int32_t>(HWC2::Error::BadLayer);
362 }
363
364 if (not_a_swapchain) {
365 writeback_layer->ClearSlots();
366 }
367
368 writeback_layer->SetLayerProperties(lp.value());
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200369
370 return 0;
371}
372
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200373static int32_t AcceptDisplayChanges(hwc2_device_t *device,
374 hwc2_display_t display) {
375 ALOGV("AcceptDisplayChanges");
376 LOCK_COMPOSER(device);
377 GET_DISPLAY(display);
378
379 idisplay->AcceptValidatedComposition();
380
381 return 0;
382}
383
Roman Stratiienko72ff8c32025-02-09 00:48:44 +0200384static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
385 uint32_t *out_num_elements,
386 hwc2_layer_t *out_layers, int32_t *out_fences) {
387 ALOGV("GetReleaseFences");
388 LOCK_COMPOSER(device);
389 GET_DISPLAY(display);
390
391 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
392
393 if (*out_num_elements < hwc2display->release_fences.size()) {
394 ALOGW("Overflow num_elements %d/%zu", *out_num_elements,
395 hwc2display->release_fences.size());
396 return static_cast<int32_t>(HWC2::Error::NoResources);
397 }
398
399 for (size_t i = 0; i < hwc2display->release_fences.size(); ++i) {
400 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
401 out_layers[i] = hwc2display->release_fences[i].first;
402 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
403 out_fences[i] = DupFd(hwc2display->release_fences[i].second);
404 }
405
406 *out_num_elements = hwc2display->release_fences.size();
407 hwc2display->release_fences.clear();
408
409 return static_cast<int32_t>(HWC2::Error::None);
410}
411
Roman Stratiienko34c50ce2025-02-09 02:33:58 +0200412static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
413 uint32_t *out_num_types,
414 uint32_t *out_num_requests) {
415 ALOGV("ValidateDisplay");
416 LOCK_COMPOSER(device);
417 GET_DISPLAY(display);
418
419 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
420
421 hwc2display->changed_layers = idisplay->ValidateStagedComposition();
422
423 *out_num_types = hwc2display->changed_layers.size();
424 *out_num_requests = 0;
425
426 return 0;
427}
428
429static int32_t GetChangedCompositionTypes(hwc2_device_t *device,
430 hwc2_display_t display,
431 uint32_t *out_num_elements,
432 hwc2_layer_t *out_layers,
433 int32_t *out_types) {
434 ALOGV("GetChangedCompositionTypes");
435 LOCK_COMPOSER(device);
436 GET_DISPLAY(display);
437
438 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
439
440 if (*out_num_elements < hwc2display->changed_layers.size()) {
441 ALOGW("Overflow num_elements %d/%zu", *out_num_elements,
442 hwc2display->changed_layers.size());
443 return static_cast<int32_t>(HWC2::Error::NoResources);
444 }
445
446 for (size_t i = 0; i < hwc2display->changed_layers.size(); ++i) {
447 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
448 out_layers[i] = hwc2display->changed_layers[i].first;
449 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
450 out_types[i] = static_cast<int32_t>(hwc2display->changed_layers[i].second);
451 }
452
453 *out_num_elements = hwc2display->changed_layers.size();
454 hwc2display->changed_layers.clear();
455
456 return static_cast<int32_t>(HWC2::Error::None);
457}
458
Roman Stratiienko72ff8c32025-02-09 00:48:44 +0200459static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
460 int32_t *out_release_fence) {
461 ALOGV("PresentDisplay");
462 LOCK_COMPOSER(device);
463 GET_DISPLAY(display);
464
465 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
466
467 SharedFd out_fence;
468
469 hwc2display->release_fences.clear();
470
471 if (!idisplay->PresentStagedComposition(out_fence,
472 hwc2display->release_fences)) {
473 ALOGE("Failed to present display");
474 return static_cast<int32_t>(HWC2::Error::BadDisplay);
475 }
476
477 *out_release_fence = DupFd(out_fence);
478
479 return 0;
480}
481
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200482#if __ANDROID_API__ >= 28
483
484static int32_t GetDisplayBrightnessSupport(hwc2_device_t * /*device*/,
485 hwc2_display_t /*display*/,
486 bool *out_support) {
487 ALOGV("GetDisplayBrightnessSupport");
488 *out_support = false; // Brightness support is not available
489 return static_cast<int32_t>(HWC2::Error::None);
490}
491
492static int32_t SetDisplayBrightness(hwc2_device_t * /*device*/,
493 hwc2_display_t /*display*/,
494 float /*brightness*/) {
495 ALOGV("SetDisplayBrightness");
496 return static_cast<int32_t>(HWC2::Error::Unsupported);
497}
498
499#endif
500
501#if __ANDROID_API__ >= 29
502static int32_t SetAutoLowLatencyMode(hwc2_device_t * /*device*/,
503 hwc2_display_t /*display*/, bool /*on*/) {
504 ALOGV("SetAutoLowLatencyMode");
505 return static_cast<int32_t>(HWC2::Error::Unsupported);
506}
507
508static int32_t GetSupportedContentTypes(
509 hwc2_device_t * /*device*/, hwc2_display_t /*display*/,
510 uint32_t *out_num_supported_content_types,
511 uint32_t * /*out_supported_content_types*/) {
512 ALOGV("GetSupportedContentTypes");
513 *out_num_supported_content_types = 0;
514 return static_cast<int32_t>(HWC2::Error::None);
515}
516#endif
517
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200518/* Layer functions */
519
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200520static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display,
521 hwc2_layer_t layer,
522 int32_t /*hwc2_blend_mode_t*/ mode) {
523 ALOGV("SetLayerBlendMode");
524 LOCK_COMPOSER(device);
525 GET_DISPLAY(display);
526 GET_LAYER(layer);
527
528 BufferBlendMode blend_mode{};
529 switch (static_cast<HWC2::BlendMode>(mode)) {
530 case HWC2::BlendMode::None:
531 blend_mode = BufferBlendMode::kNone;
532 break;
533 case HWC2::BlendMode::Premultiplied:
534 blend_mode = BufferBlendMode::kPreMult;
535 break;
536 case HWC2::BlendMode::Coverage:
537 blend_mode = BufferBlendMode::kCoverage;
538 break;
539 default:
540 ALOGE("Unknown blending mode b=%d", mode);
541 blend_mode = BufferBlendMode::kUndefined;
542 break;
543 }
544
545 HwcLayer::LayerProperties layer_properties;
546 layer_properties.blend_mode = blend_mode;
547
548 ilayer->SetLayerProperties(layer_properties);
549
550 return 0;
551}
552
553static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display,
554 hwc2_layer_t layer, buffer_handle_t buffer,
555 int32_t acquire_fence) {
556 ALOGV("SetLayerBuffer");
557 LOCK_COMPOSER(device);
558 GET_DISPLAY(display);
559 GET_LAYER(layer);
560
Roman Stratiienko7c8cc4e2025-01-25 22:41:53 +0200561 auto h2l = GetHwc2DeviceLayer(*ilayer);
562
563 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, acquire_fence);
564 if (!lp) {
565 ALOGV("Failed to process layer buffer");
566 return static_cast<int32_t>(HWC2::Error::BadLayer);
567 }
568
569 if (not_a_swapchain) {
570 ilayer->ClearSlots();
571 }
572
573 ilayer->SetLayerProperties(lp.value());
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200574
575 return 0;
576}
577
578static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display,
579 hwc2_layer_t layer,
580 int32_t /*android_dataspace_t*/ dataspace) {
581 ALOGV("SetLayerDataspace");
582 LOCK_COMPOSER(device);
583 GET_DISPLAY(display);
584 GET_LAYER(layer);
585
586 HwcLayer::LayerProperties layer_properties;
587 layer_properties.color_space = Hwc2ToColorSpace(dataspace);
588 layer_properties.sample_range = Hwc2ToSampleRange(dataspace);
589 ilayer->SetLayerProperties(layer_properties);
590 return 0;
591}
592
593static int32_t SetCursorPosition(hwc2_device_t * /*device*/,
594 hwc2_display_t /*display*/,
595 hwc2_layer_t /*layer*/, int32_t /*x*/,
596 int32_t /*y*/) {
597 ALOGV("SetCursorPosition");
598 return 0;
599}
600
601static int32_t SetLayerColor(hwc2_device_t * /*device*/,
602 hwc2_display_t /*display*/, hwc2_layer_t /*layer*/,
603 hwc_color_t /*color*/) {
604 ALOGV("SetLayerColor");
605 return 0;
606}
607
608static int32_t SetLayerCompositionType(hwc2_device_t *device,
609 hwc2_display_t display,
610 hwc2_layer_t layer,
611 int32_t /*hwc2_composition_t*/ type) {
612 ALOGV("SetLayerCompositionType");
613 LOCK_COMPOSER(device);
614 GET_DISPLAY(display);
615 GET_LAYER(layer);
616
617 HwcLayer::LayerProperties layer_properties;
618 layer_properties.composition_type = static_cast<HWC2::Composition>(type);
619 ilayer->SetLayerProperties(layer_properties);
620
621 return 0;
622}
623
624static int32_t SetLayerDisplayFrame(hwc2_device_t *device,
625 hwc2_display_t display, hwc2_layer_t layer,
626 hwc_rect_t frame) {
627 ALOGV("SetLayerDisplayFrame");
628 LOCK_COMPOSER(device);
629 GET_DISPLAY(display);
630 GET_LAYER(layer);
631
632 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200633 layer_properties.display_frame = {
634 .i_rect = DstRectInfo::IRect{.left = frame.left,
635 .top = frame.top,
636 .right = frame.right,
637 .bottom = frame.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200638 ilayer->SetLayerProperties(layer_properties);
639
640 return 0;
641}
642
643static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display,
644 hwc2_layer_t layer, float alpha) {
645 ALOGV("SetLayerPlaneAlpha");
646 LOCK_COMPOSER(device);
647 GET_DISPLAY(display);
648 GET_LAYER(layer);
649
650 HwcLayer::LayerProperties layer_properties;
651 layer_properties.alpha = alpha;
652 ilayer->SetLayerProperties(layer_properties);
653
654 return 0;
655}
656
657static int32_t SetLayerSidebandStream(hwc2_device_t * /*device*/,
658 hwc2_display_t /*display*/,
659 hwc2_layer_t /*layer*/,
660 const native_handle_t * /*stream*/) {
661 ALOGV("SetLayerSidebandStream");
662 return static_cast<int32_t>(HWC2::Error::Unsupported);
663}
664
665static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display,
666 hwc2_layer_t layer, hwc_frect_t crop) {
667 ALOGV("SetLayerSourceCrop");
668 LOCK_COMPOSER(device);
669 GET_DISPLAY(display);
670 GET_LAYER(layer);
671
672 HwcLayer::LayerProperties layer_properties;
Roman Stratiienko4e15bfc2025-01-23 01:55:21 +0200673 layer_properties.source_crop = {
674 .f_rect = SrcRectInfo::FRect{.left = crop.left,
675 .top = crop.top,
676 .right = crop.right,
677 .bottom = crop.bottom}};
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200678 ilayer->SetLayerProperties(layer_properties);
679
680 return 0;
681}
682
683static int32_t SetLayerSurfaceDamage(hwc2_device_t * /*device*/,
684 hwc2_display_t /*display*/,
685 hwc2_layer_t /*layer*/,
686 hwc_region_t /*damage*/) {
687 ALOGV("SetLayerSurfaceDamage");
688 return 0;
689}
690
691static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display,
692 hwc2_layer_t layer, int32_t transform) {
693 ALOGV("SetLayerTransform");
694 LOCK_COMPOSER(device);
695 GET_DISPLAY(display);
696 GET_LAYER(layer);
697
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200698 HwcLayer::LayerProperties layer_properties;
Roman Stratiienkoda2fcf62025-01-23 17:47:03 +0200699 layer_properties.transform = {
700 .hflip = (transform & HAL_TRANSFORM_FLIP_H) != 0,
701 .vflip = (transform & HAL_TRANSFORM_FLIP_V) != 0,
702 .rotate90 = (transform & HAL_TRANSFORM_ROT_90) != 0,
703 };
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200704 ilayer->SetLayerProperties(layer_properties);
705
706 return 0;
707}
708
709static int32_t SetLayerVisibleRegion(hwc2_device_t * /*device*/,
710 hwc2_display_t /*display*/,
711 hwc2_layer_t /*layer*/,
712 hwc_region_t /*visible*/) {
713 ALOGV("SetLayerVisibleRegion");
714 return 0;
715}
716
717static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
718 hwc2_layer_t layer, uint32_t z) {
719 ALOGV("SetLayerZOrder");
720 LOCK_COMPOSER(device);
721 GET_DISPLAY(display);
722 GET_LAYER(layer);
723
724 HwcLayer::LayerProperties layer_properties;
725 layer_properties.z_order = z;
726 ilayer->SetLayerProperties(layer_properties);
727
728 return 0;
729}
730
731/* Entry point for the HWC2 API */
732// NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
733
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200734static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
735 int32_t descriptor) {
736 auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
737 switch (func) {
738 // Device functions
739 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
740 return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
741 DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
742 &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
743 int32_t *, hwc2_display_t *>);
744 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
745 return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
746 DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
747 &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
748 case HWC2::FunctionDescriptor::Dump:
749 return ToHook<HWC2_PFN_DUMP>(
750 DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
751 uint32_t *, char *>);
752 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
753 return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
754 DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
755 &DrmHwcTwo::GetMaxVirtualDisplayCount>);
756 case HWC2::FunctionDescriptor::RegisterCallback:
757 return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
758 DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
759 &DrmHwcTwo::RegisterCallback, int32_t,
760 hwc2_callback_data_t, hwc2_function_pointer_t>);
761
762 // Display functions
763 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200764 return (hwc2_function_pointer_t)AcceptDisplayChanges;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200765 case HWC2::FunctionDescriptor::CreateLayer:
766 return ToHook<HWC2_PFN_CREATE_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200767 DisplayHook<decltype(&HwcDisplay::CreateLayer),
768 &HwcDisplay::CreateLayer, hwc2_layer_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200769 case HWC2::FunctionDescriptor::DestroyLayer:
770 return ToHook<HWC2_PFN_DESTROY_LAYER>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200771 DisplayHook<decltype(&HwcDisplay::DestroyLayer),
772 &HwcDisplay::DestroyLayer, hwc2_layer_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200773 case HWC2::FunctionDescriptor::GetActiveConfig:
774 return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200775 DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
776 &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200777 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
Roman Stratiienko34c50ce2025-02-09 02:33:58 +0200778 return (hwc2_function_pointer_t)GetChangedCompositionTypes;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200779 case HWC2::FunctionDescriptor::GetClientTargetSupport:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200780 return (hwc2_function_pointer_t)GetClientTargetSupport;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200781 case HWC2::FunctionDescriptor::GetColorModes:
782 return ToHook<HWC2_PFN_GET_COLOR_MODES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200783 DisplayHook<decltype(&HwcDisplay::GetColorModes),
784 &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200785 case HWC2::FunctionDescriptor::GetDisplayAttribute:
786 return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200787 DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
788 &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
789 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200790 case HWC2::FunctionDescriptor::GetDisplayConfigs:
791 return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
Drew Davenportf7e88332024-09-06 12:54:38 -0600792 DisplayHook<decltype(&HwcDisplay::LegacyGetDisplayConfigs),
793 &HwcDisplay::LegacyGetDisplayConfigs, uint32_t *,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200794 hwc2_config_t *>);
795 case HWC2::FunctionDescriptor::GetDisplayName:
796 return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200797 DisplayHook<decltype(&HwcDisplay::GetDisplayName),
798 &HwcDisplay::GetDisplayName, uint32_t *, char *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200799 case HWC2::FunctionDescriptor::GetDisplayRequests:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200800 return (hwc2_function_pointer_t)GetDisplayRequests;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200801 case HWC2::FunctionDescriptor::GetDisplayType:
802 return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200803 DisplayHook<decltype(&HwcDisplay::GetDisplayType),
804 &HwcDisplay::GetDisplayType, int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200805 case HWC2::FunctionDescriptor::GetDozeSupport:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200806 return (hwc2_function_pointer_t)GetDozeSupport;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200807 case HWC2::FunctionDescriptor::GetHdrCapabilities:
808 return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200809 DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
810 &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
811 float *, float *, float *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200812 case HWC2::FunctionDescriptor::GetReleaseFences:
Roman Stratiienko72ff8c32025-02-09 00:48:44 +0200813 return (hwc2_function_pointer_t)GetReleaseFences;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200814 case HWC2::FunctionDescriptor::PresentDisplay:
Roman Stratiienko72ff8c32025-02-09 00:48:44 +0200815 return (hwc2_function_pointer_t)PresentDisplay;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200816 case HWC2::FunctionDescriptor::SetActiveConfig:
817 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200818 DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
819 &HwcDisplay::SetActiveConfig, hwc2_config_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200820 case HWC2::FunctionDescriptor::SetClientTarget:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200821 return (hwc2_function_pointer_t)SetClientTarget;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200822 case HWC2::FunctionDescriptor::SetColorMode:
823 return ToHook<HWC2_PFN_SET_COLOR_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200824 DisplayHook<decltype(&HwcDisplay::SetColorMode),
825 &HwcDisplay::SetColorMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200826 case HWC2::FunctionDescriptor::SetColorTransform:
827 return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200828 DisplayHook<decltype(&HwcDisplay::SetColorTransform),
829 &HwcDisplay::SetColorTransform, const float *, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200830 case HWC2::FunctionDescriptor::SetOutputBuffer:
Roman Stratiienko70ab9392025-01-23 12:11:48 +0200831 return (hwc2_function_pointer_t)SetOutputBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200832 case HWC2::FunctionDescriptor::SetPowerMode:
833 return ToHook<HWC2_PFN_SET_POWER_MODE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200834 DisplayHook<decltype(&HwcDisplay::SetPowerMode),
835 &HwcDisplay::SetPowerMode, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200836 case HWC2::FunctionDescriptor::SetVsyncEnabled:
837 return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200838 DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
839 &HwcDisplay::SetVsyncEnabled, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200840 case HWC2::FunctionDescriptor::ValidateDisplay:
Roman Stratiienko34c50ce2025-02-09 02:33:58 +0200841 return (hwc2_function_pointer_t)ValidateDisplay;
Roman Stratiienko6b405052022-12-10 19:09:10 +0200842#if __ANDROID_API__ > 27
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200843 case HWC2::FunctionDescriptor::GetRenderIntents:
844 return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200845 DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
846 &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
847 int32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200848 case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
849 return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200850 DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
851 &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200852#endif
Roman Stratiienko6b405052022-12-10 19:09:10 +0200853#if __ANDROID_API__ > 28
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200854 case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
855 return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200856 DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
857 &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
858 uint32_t *, uint8_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200859 case HWC2::FunctionDescriptor::GetDisplayCapabilities:
860 return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200861 DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
862 &HwcDisplay::GetDisplayCapabilities, uint32_t *,
863 uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200864 case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200865 return (hwc2_function_pointer_t)GetDisplayBrightnessSupport;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200866 case HWC2::FunctionDescriptor::SetDisplayBrightness:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200867 return (hwc2_function_pointer_t)SetDisplayBrightness;
Roman Stratiienko6b405052022-12-10 19:09:10 +0200868#endif /* __ANDROID_API__ > 28 */
869#if __ANDROID_API__ > 29
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200870 case HWC2::FunctionDescriptor::GetDisplayConnectionType:
871 return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200872 DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
873 &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200874 case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
875 return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200876 DisplayHook<decltype(&HwcDisplay::GetDisplayVsyncPeriod),
877 &HwcDisplay::GetDisplayVsyncPeriod,
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200878 hwc2_vsync_period_t *>);
879 case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
880 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200881 DisplayHook<decltype(&HwcDisplay::SetActiveConfigWithConstraints),
882 &HwcDisplay::SetActiveConfigWithConstraints,
883 hwc2_config_t, hwc_vsync_period_change_constraints_t *,
884 hwc_vsync_period_change_timeline_t *>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200885 case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200886 return (hwc2_function_pointer_t)SetAutoLowLatencyMode;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200887 case HWC2::FunctionDescriptor::GetSupportedContentTypes:
Roman Stratiienkof74b7312025-02-08 23:16:00 +0200888 return (hwc2_function_pointer_t)GetSupportedContentTypes;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200889 case HWC2::FunctionDescriptor::SetContentType:
890 return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
Roman Stratiienko3627beb2022-01-04 16:02:55 +0200891 DisplayHook<decltype(&HwcDisplay::SetContentType),
892 &HwcDisplay::SetContentType, int32_t>);
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200893#endif
894 // Layer functions
895 case HWC2::FunctionDescriptor::SetCursorPosition:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200896 return (hwc2_function_pointer_t)SetCursorPosition;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200897 case HWC2::FunctionDescriptor::SetLayerBlendMode:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200898 return (hwc2_function_pointer_t)SetLayerBlendMode;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200899 case HWC2::FunctionDescriptor::SetLayerBuffer:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200900 return (hwc2_function_pointer_t)SetLayerBuffer;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200901 case HWC2::FunctionDescriptor::SetLayerColor:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200902 return (hwc2_function_pointer_t)SetLayerColor;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200903 case HWC2::FunctionDescriptor::SetLayerCompositionType:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200904 return (hwc2_function_pointer_t)SetLayerCompositionType;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200905 case HWC2::FunctionDescriptor::SetLayerDataspace:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200906 return (hwc2_function_pointer_t)SetLayerDataspace;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200907 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200908 return (hwc2_function_pointer_t)SetLayerDisplayFrame;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200909 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200910 return (hwc2_function_pointer_t)SetLayerPlaneAlpha;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200911 case HWC2::FunctionDescriptor::SetLayerSidebandStream:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200912 return (hwc2_function_pointer_t)SetLayerSidebandStream;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200913 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200914 return (hwc2_function_pointer_t)SetLayerSourceCrop;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200915 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200916 return (hwc2_function_pointer_t)SetLayerSurfaceDamage;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200917 case HWC2::FunctionDescriptor::SetLayerTransform:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200918 return (hwc2_function_pointer_t)SetLayerTransform;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200919 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200920 return (hwc2_function_pointer_t)SetLayerVisibleRegion;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200921 case HWC2::FunctionDescriptor::SetLayerZOrder:
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200922 return (hwc2_function_pointer_t)SetLayerZOrder;
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200923 case HWC2::FunctionDescriptor::Invalid:
924 default:
925 return nullptr;
926 }
927}
928
Roman Stratiienko41cd9502025-01-22 16:48:58 +0200929// NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
930
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200931static int HookDevOpen(const struct hw_module_t *module, const char *name,
932 struct hw_device_t **dev) {
933 if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
934 ALOGE("Invalid module name- %s", name);
935 return -EINVAL;
936 }
937
938 auto ctx = std::make_unique<Drmhwc2Device>();
939 if (!ctx) {
940 ALOGE("Failed to allocate DrmHwcTwo");
941 return -ENOMEM;
942 }
943
944 ctx->common.tag = HARDWARE_DEVICE_TAG;
945 ctx->common.version = HWC_DEVICE_API_VERSION_2_0;
946 ctx->common.close = HookDevClose;
947 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
948 ctx->common.module = (hw_module_t *)module;
949 ctx->getCapabilities = HookDevGetCapabilities;
950 ctx->getFunction = HookDevGetFunction;
951
Roman Stratiienko26fd2b22022-01-04 12:59:29 +0200952 *dev = &ctx.release()->common;
953
954 return 0;
955}
956
957} // namespace android
958
959// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
960static struct hw_module_methods_t hwc2_module_methods = {
961 .open = android::HookDevOpen,
962};
963
964// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
965hw_module_t HAL_MODULE_INFO_SYM = {
966 .tag = HARDWARE_MODULE_TAG,
967 .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
968 .id = HWC_HARDWARE_MODULE_ID,
969 .name = "DrmHwcTwo module",
970 .author = "The Android Open Source Project",
971 .methods = &hwc2_module_methods,
972 .dso = nullptr,
973 .reserved = {0},
974};