1 /*
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
17 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
18 // #define LOG_NDEBUG 0 // Uncomment to see HWC2 API calls in logcat
19
20 #define LOG_TAG "drmhwc"
21
22 #include <cassert>
23 #include <cinttypes>
24 #include <memory>
25 #include <optional>
26
27 #include <cutils/native_handle.h>
28
29 #include "DrmHwcTwo.h"
30 #include "backend/Backend.h"
31 #include "hwc2_device/HwcLayer.h"
32 #include "utils/log.h"
33
34 namespace android {
35
36 /* 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 */
GetFuncName(const char * pretty_function)43 static std::string GetFuncName(const char *pretty_function) {
44 const std::string str(pretty_function);
45 const char *start = "func = &";
46 auto p1 = str.find(start);
47 p1 += strlen(start);
48 auto p2 = str.find(',', p1);
49 return str.substr(p1, p2 - p1);
50 }
51
52 class Hwc2DeviceDisplay : public FrontendDisplayBase {
53 public:
54 std::vector<HwcDisplay::ReleaseFence> release_fences;
55 std::vector<HwcDisplay::ChangedLayer> changed_layers;
56
57 int64_t next_layer_id = 1;
58 };
59
GetHwc2DeviceDisplay(HwcDisplay & display)60 static auto GetHwc2DeviceDisplay(HwcDisplay &display)
61 -> std::shared_ptr<Hwc2DeviceDisplay> {
62 auto frontend_private_data = display.GetFrontendPrivateData();
63 if (!frontend_private_data) {
64 frontend_private_data = std::make_shared<Hwc2DeviceDisplay>();
65 display.SetFrontendPrivateData(frontend_private_data);
66 }
67 return std::static_pointer_cast<Hwc2DeviceDisplay>(frontend_private_data);
68 }
69
70 class Hwc2DeviceLayer : public FrontendLayerBase {
71 public:
HandleNextBuffer(buffer_handle_t buffer_handle,int32_t fence_fd)72 auto HandleNextBuffer(buffer_handle_t buffer_handle, int32_t fence_fd)
73 -> std::pair<std::optional<HwcLayer::LayerProperties>,
74 bool /* not a swapchain */> {
75 auto slot = GetSlotNumber(buffer_handle);
76
77 if (invalid_) {
78 return std::make_pair(std::nullopt, true);
79 }
80
81 bool buffer_provided = false;
82 bool not_a_swapchain = true;
83 int32_t slot_id = 0;
84
85 if (slot.has_value()) {
86 buffer_provided = swchain_slots_[slot.value()];
87 slot_id = slot.value();
88 not_a_swapchain = true;
89 }
90
91 HwcLayer::LayerProperties lp;
92 if (!buffer_provided) {
93 auto bo_info = BufferInfoGetter::GetInstance()->GetBoInfo(buffer_handle);
94 if (!bo_info) {
95 invalid_ = true;
96 return std::make_pair(std::nullopt, true);
97 }
98
99 lp.slot_buffer = {
100 .slot_id = slot_id,
101 .bi = bo_info,
102 };
103 }
104 lp.active_slot = {
105 .slot_id = slot_id,
106 .fence = MakeSharedFd(fence_fd),
107 };
108
109 return std::make_pair(lp, not_a_swapchain);
110 }
111
SwChainClearCache()112 void SwChainClearCache() {
113 swchain_lookup_table_.clear();
114 swchain_slots_.clear();
115 swchain_reassembled_ = false;
116 }
117
118 private:
GetSlotNumber(buffer_handle_t buffer_handle)119 auto GetSlotNumber(buffer_handle_t buffer_handle) -> std::optional<int32_t> {
120 auto unique_id = BufferInfoGetter::GetInstance()->GetUniqueId(
121 buffer_handle);
122 if (!unique_id) {
123 ALOGE("Failed to get unique id for buffer handle %p", buffer_handle);
124 return std::nullopt;
125 }
126
127 if (swchain_lookup_table_.count(*unique_id) == 0) {
128 SwChainReassemble(*unique_id);
129 return std::nullopt;
130 }
131
132 if (!swchain_reassembled_) {
133 return std::nullopt;
134 }
135
136 return swchain_lookup_table_[*unique_id];
137 }
138
SwChainReassemble(BufferUniqueId unique_id)139 void SwChainReassemble(BufferUniqueId unique_id) {
140 if (swchain_lookup_table_.count(unique_id) != 0) {
141 if (swchain_lookup_table_[unique_id] ==
142 int(swchain_lookup_table_.size()) - 1) {
143 /* Skip same buffer */
144 return;
145 }
146 if (swchain_lookup_table_[unique_id] == 0) {
147 swchain_reassembled_ = true;
148 return;
149 }
150 /* Tracking error */
151 SwChainClearCache();
152 return;
153 }
154
155 swchain_lookup_table_[unique_id] = int(swchain_lookup_table_.size());
156 }
157
158 bool invalid_{}; /* Layer is invalid and should be skipped */
159 std::map<BufferUniqueId, int /*slot*/> swchain_lookup_table_;
160 std::map<int /*slot*/, bool /*buffer_provided*/> swchain_slots_;
161 bool swchain_reassembled_{};
162 };
163
GetHwc2DeviceLayer(HwcLayer & layer)164 static auto GetHwc2DeviceLayer(HwcLayer &layer)
165 -> std::shared_ptr<Hwc2DeviceLayer> {
166 auto frontend_private_data = layer.GetFrontendPrivateData();
167 if (!frontend_private_data) {
168 frontend_private_data = std::make_shared<Hwc2DeviceLayer>();
169 layer.SetFrontendPrivateData(frontend_private_data);
170 }
171 return std::static_pointer_cast<Hwc2DeviceLayer>(frontend_private_data);
172 }
173
174 struct Drmhwc2Device : hwc2_device {
175 DrmHwcTwo drmhwctwo;
176 };
177
ToDrmHwcTwo(hwc2_device_t * dev)178 static DrmHwcTwo *ToDrmHwcTwo(hwc2_device_t *dev) {
179 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast):
180 return &static_cast<Drmhwc2Device *>(dev)->drmhwctwo;
181 }
182
183 template <typename PFN, typename T>
ToHook(T function)184 static hwc2_function_pointer_t ToHook(T function) {
185 // NOLINTNEXTLINE(modernize-type-traits): ToHook is going to be removed
186 static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
187 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast):
188 return reinterpret_cast<hwc2_function_pointer_t>(function);
189 }
190
191 template <typename T, typename HookType, HookType func, typename... Args>
DeviceHook(hwc2_device_t * dev,Args...args)192 static T DeviceHook(hwc2_device_t *dev, Args... args) {
193 ALOGV("Device hook: %s", GetFuncName(__PRETTY_FUNCTION__).c_str());
194 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
195 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
196 return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
197 }
198
199 template <typename HookType, HookType func, typename... Args>
DisplayHook(hwc2_device_t * dev,hwc2_display_t display_handle,Args...args)200 static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
201 Args... args) {
202 ALOGV("Display #%" PRIu64 " hook: %s", display_handle,
203 GetFuncName(__PRETTY_FUNCTION__).c_str());
204 DrmHwcTwo *hwc = ToDrmHwcTwo(dev);
205 const std::unique_lock lock(hwc->GetResMan().GetMainLock());
206 auto *display = hwc->GetDisplay(display_handle);
207 if (display == nullptr)
208 return static_cast<int32_t>(HWC2::Error::BadDisplay);
209
210 return static_cast<int32_t>((display->*func)(std::forward<Args>(args)...));
211 }
212
HookDevClose(hw_device_t * dev)213 static int HookDevClose(hw_device_t *dev) {
214 // NOLINTNEXTLINE (cppcoreguidelines-pro-type-reinterpret-cast): Safe
215 auto *hwc2_dev = reinterpret_cast<hwc2_device_t *>(dev);
216 const std::unique_ptr<DrmHwcTwo> ctx(ToDrmHwcTwo(hwc2_dev));
217 return 0;
218 }
219
HookDevGetCapabilities(hwc2_device_t *,uint32_t * out_count,int32_t *)220 static void HookDevGetCapabilities(hwc2_device_t * /*dev*/, uint32_t *out_count,
221 int32_t * /*out_capabilities*/) {
222 *out_count = 0;
223 }
224
225 // NOLINTBEGIN(cppcoreguidelines-macro-usage)
226
227 #define LOCK_COMPOSER(dev) \
228 auto *ihwc = ToDrmHwcTwo(dev); \
229 const std::unique_lock lock(ihwc->GetResMan().GetMainLock());
230
231 #define GET_DISPLAY(display_id) \
232 auto *idisplay = ihwc->GetDisplay(display_id); \
233 if (!idisplay) \
234 return static_cast<int32_t>(HWC2::Error::BadDisplay);
235
236 #define GET_LAYER(layer_id) \
237 auto *ilayer = idisplay->get_layer(layer_id); \
238 if (!ilayer) \
239 return static_cast<int32_t>(HWC2::Error::BadLayer);
240
241 // NOLINTEND(cppcoreguidelines-macro-usage)
242
Hwc2ToColorSpace(int32_t dataspace)243 static BufferColorSpace Hwc2ToColorSpace(int32_t dataspace) {
244 switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
245 case HAL_DATASPACE_STANDARD_BT709:
246 return BufferColorSpace::kItuRec709;
247 case HAL_DATASPACE_STANDARD_BT601_625:
248 case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
249 case HAL_DATASPACE_STANDARD_BT601_525:
250 case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
251 return BufferColorSpace::kItuRec601;
252 case HAL_DATASPACE_STANDARD_BT2020:
253 case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
254 return BufferColorSpace::kItuRec2020;
255 default:
256 return BufferColorSpace::kUndefined;
257 }
258 }
259
Hwc2ToSampleRange(int32_t dataspace)260 static BufferSampleRange Hwc2ToSampleRange(int32_t dataspace) {
261 switch (dataspace & HAL_DATASPACE_RANGE_MASK) {
262 case HAL_DATASPACE_RANGE_FULL:
263 return BufferSampleRange::kFullRange;
264 case HAL_DATASPACE_RANGE_LIMITED:
265 return BufferSampleRange::kLimitedRange;
266 default:
267 return BufferSampleRange::kUndefined;
268 }
269 }
270
271 /* Display functions */
CreateLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t * out_layer)272 static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
273 hwc2_layer_t *out_layer) {
274 ALOGV("CreateLayer");
275 LOCK_COMPOSER(device);
276 GET_DISPLAY(display);
277
278 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
279
280 if (!idisplay->CreateLayer(hwc2display->next_layer_id)) {
281 return static_cast<int32_t>(HWC2::Error::BadDisplay);
282 }
283
284 *out_layer = (hwc2_layer_t)hwc2display->next_layer_id;
285 hwc2display->next_layer_id++;
286
287 return 0;
288 }
289
DestroyLayer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer)290 static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
291 hwc2_layer_t layer) {
292 ALOGV("DestroyLayer");
293 LOCK_COMPOSER(device);
294 GET_DISPLAY(display);
295
296 if (!idisplay->DestroyLayer((ILayerId)layer)) {
297 return static_cast<int32_t>(HWC2::Error::BadLayer);
298 }
299
300 return 0;
301 }
302
GetDisplayRequests(hwc2_device_t *,hwc2_display_t,int32_t *,uint32_t * out_num_elements,hwc2_layer_t *,int32_t *)303 static int32_t GetDisplayRequests(hwc2_device_t * /*device*/,
304 hwc2_display_t /*display*/,
305 int32_t * /* out_display_requests */,
306 uint32_t *out_num_elements,
307 hwc2_layer_t * /*out_layers*/,
308 int32_t * /*out_layer_requests*/) {
309 ALOGV("GetDisplayRequests");
310
311 *out_num_elements = 0;
312 return 0;
313 }
314
GetDozeSupport(hwc2_device_t *,hwc2_display_t,int32_t * out_support)315 static int32_t GetDozeSupport(hwc2_device_t * /*device*/,
316 hwc2_display_t /*display*/,
317 int32_t *out_support) {
318 ALOGV("GetDozeSupport");
319 *out_support = 0; // Doze support is not available
320 return 0;
321 }
322
GetClientTargetSupport(hwc2_device_t *,hwc2_display_t,uint32_t,uint32_t,int32_t,int32_t dataspace)323 static int32_t GetClientTargetSupport(hwc2_device_t * /*device*/,
324 hwc2_display_t /*display*/,
325 uint32_t /*width*/, uint32_t /*height*/,
326 int32_t /*format*/, int32_t dataspace) {
327 ALOGV("GetClientTargetSupport");
328
329 if (dataspace != HAL_DATASPACE_UNKNOWN)
330 return static_cast<int32_t>(HWC2::Error::Unsupported);
331
332 return 0;
333 }
334
SetClientTarget(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t target,int32_t acquire_fence,int32_t dataspace,hwc_region_t)335 static int32_t SetClientTarget(hwc2_device_t *device, hwc2_display_t display,
336 buffer_handle_t target, int32_t acquire_fence,
337 int32_t dataspace, hwc_region_t /*damage*/) {
338 ALOGV("SetClientTarget");
339 LOCK_COMPOSER(device);
340 GET_DISPLAY(display);
341
342 auto &client_layer = idisplay->GetClientLayer();
343 auto h2l = GetHwc2DeviceLayer(client_layer);
344 if (!h2l) {
345 client_layer.SetFrontendPrivateData(std::make_shared<Hwc2DeviceLayer>());
346 }
347
348 if (target == nullptr) {
349 client_layer.ClearSlots();
350 h2l->SwChainClearCache();
351
352 return 0;
353 }
354
355 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(target, acquire_fence);
356 if (!lp) {
357 ALOGE("Failed to process client target");
358 return static_cast<int32_t>(HWC2::Error::BadLayer);
359 }
360
361 if (not_a_swapchain) {
362 client_layer.ClearSlots();
363 }
364
365 lp->color_space = Hwc2ToColorSpace(dataspace);
366 lp->sample_range = Hwc2ToSampleRange(dataspace);
367
368 idisplay->GetClientLayer().SetLayerProperties(lp.value());
369
370 return 0;
371 }
372
SetOutputBuffer(hwc2_device_t * device,hwc2_display_t display,buffer_handle_t buffer,int32_t release_fence)373 static int32_t SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
374 buffer_handle_t buffer, int32_t release_fence) {
375 ALOGV("SetOutputBuffer");
376 LOCK_COMPOSER(device);
377 GET_DISPLAY(display);
378
379 auto &writeback_layer = idisplay->GetWritebackLayer();
380 if (!writeback_layer) {
381 ALOGE("Writeback layer is not available");
382 return static_cast<int32_t>(HWC2::Error::BadLayer);
383 }
384
385 auto h2l = GetHwc2DeviceLayer(*writeback_layer);
386 if (!h2l) {
387 writeback_layer->SetFrontendPrivateData(
388 std::make_shared<Hwc2DeviceLayer>());
389 }
390
391 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, release_fence);
392 if (!lp) {
393 ALOGE("Failed to process output buffer");
394 return static_cast<int32_t>(HWC2::Error::BadLayer);
395 }
396
397 if (not_a_swapchain) {
398 writeback_layer->ClearSlots();
399 }
400
401 writeback_layer->SetLayerProperties(lp.value());
402
403 return 0;
404 }
405
AcceptDisplayChanges(hwc2_device_t * device,hwc2_display_t display)406 static int32_t AcceptDisplayChanges(hwc2_device_t *device,
407 hwc2_display_t display) {
408 ALOGV("AcceptDisplayChanges");
409 LOCK_COMPOSER(device);
410 GET_DISPLAY(display);
411
412 idisplay->AcceptValidatedComposition();
413
414 return 0;
415 }
416
GetReleaseFences(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_fences)417 static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
418 uint32_t *out_num_elements,
419 hwc2_layer_t *out_layers, int32_t *out_fences) {
420 ALOGV("GetReleaseFences");
421 LOCK_COMPOSER(device);
422 GET_DISPLAY(display);
423
424 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
425
426 if (*out_num_elements < hwc2display->release_fences.size()) {
427 ALOGW("Overflow num_elements %d/%zu", *out_num_elements,
428 hwc2display->release_fences.size());
429 return static_cast<int32_t>(HWC2::Error::NoResources);
430 }
431
432 for (size_t i = 0; i < hwc2display->release_fences.size(); ++i) {
433 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
434 out_layers[i] = hwc2display->release_fences[i].first;
435 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
436 out_fences[i] = DupFd(hwc2display->release_fences[i].second);
437 }
438
439 *out_num_elements = hwc2display->release_fences.size();
440 hwc2display->release_fences.clear();
441
442 return static_cast<int32_t>(HWC2::Error::None);
443 }
444
ValidateDisplay(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_types,uint32_t * out_num_requests)445 static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
446 uint32_t *out_num_types,
447 uint32_t *out_num_requests) {
448 ALOGV("ValidateDisplay");
449 LOCK_COMPOSER(device);
450 GET_DISPLAY(display);
451
452 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
453
454 hwc2display->changed_layers = idisplay->ValidateStagedComposition();
455
456 *out_num_types = hwc2display->changed_layers.size();
457 *out_num_requests = 0;
458
459 return 0;
460 }
461
GetChangedCompositionTypes(hwc2_device_t * device,hwc2_display_t display,uint32_t * out_num_elements,hwc2_layer_t * out_layers,int32_t * out_types)462 static int32_t GetChangedCompositionTypes(hwc2_device_t *device,
463 hwc2_display_t display,
464 uint32_t *out_num_elements,
465 hwc2_layer_t *out_layers,
466 int32_t *out_types) {
467 ALOGV("GetChangedCompositionTypes");
468 LOCK_COMPOSER(device);
469 GET_DISPLAY(display);
470
471 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
472
473 if (*out_num_elements < hwc2display->changed_layers.size()) {
474 ALOGW("Overflow num_elements %d/%zu", *out_num_elements,
475 hwc2display->changed_layers.size());
476 return static_cast<int32_t>(HWC2::Error::NoResources);
477 }
478
479 for (size_t i = 0; i < hwc2display->changed_layers.size(); ++i) {
480 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
481 out_layers[i] = hwc2display->changed_layers[i].first;
482 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic):
483 out_types[i] = static_cast<int32_t>(hwc2display->changed_layers[i].second);
484 }
485
486 *out_num_elements = hwc2display->changed_layers.size();
487 hwc2display->changed_layers.clear();
488
489 return static_cast<int32_t>(HWC2::Error::None);
490 }
491
PresentDisplay(hwc2_device_t * device,hwc2_display_t display,int32_t * out_release_fence)492 static int32_t PresentDisplay(hwc2_device_t *device, hwc2_display_t display,
493 int32_t *out_release_fence) {
494 ALOGV("PresentDisplay");
495 LOCK_COMPOSER(device);
496 GET_DISPLAY(display);
497
498 auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
499
500 SharedFd out_fence;
501
502 hwc2display->release_fences.clear();
503
504 if (!idisplay->PresentStagedComposition(std::nullopt, out_fence,
505 hwc2display->release_fences)) {
506 ALOGE("Failed to present display");
507 return static_cast<int32_t>(HWC2::Error::BadDisplay);
508 }
509
510 *out_release_fence = DupFd(out_fence);
511
512 return 0;
513 }
514
515 #if __ANDROID_API__ >= 28
516
GetDisplayBrightnessSupport(hwc2_device_t *,hwc2_display_t,bool * out_support)517 static int32_t GetDisplayBrightnessSupport(hwc2_device_t * /*device*/,
518 hwc2_display_t /*display*/,
519 bool *out_support) {
520 ALOGV("GetDisplayBrightnessSupport");
521 *out_support = false; // Brightness support is not available
522 return static_cast<int32_t>(HWC2::Error::None);
523 }
524
SetDisplayBrightness(hwc2_device_t *,hwc2_display_t,float)525 static int32_t SetDisplayBrightness(hwc2_device_t * /*device*/,
526 hwc2_display_t /*display*/,
527 float /*brightness*/) {
528 ALOGV("SetDisplayBrightness");
529 return static_cast<int32_t>(HWC2::Error::Unsupported);
530 }
531
532 #endif
533
534 #if __ANDROID_API__ >= 29
SetAutoLowLatencyMode(hwc2_device_t *,hwc2_display_t,bool)535 static int32_t SetAutoLowLatencyMode(hwc2_device_t * /*device*/,
536 hwc2_display_t /*display*/, bool /*on*/) {
537 ALOGV("SetAutoLowLatencyMode");
538 return static_cast<int32_t>(HWC2::Error::Unsupported);
539 }
540
GetSupportedContentTypes(hwc2_device_t *,hwc2_display_t,uint32_t * out_num_supported_content_types,uint32_t *)541 static int32_t GetSupportedContentTypes(
542 hwc2_device_t * /*device*/, hwc2_display_t /*display*/,
543 uint32_t *out_num_supported_content_types,
544 uint32_t * /*out_supported_content_types*/) {
545 ALOGV("GetSupportedContentTypes");
546 *out_num_supported_content_types = 0;
547 return static_cast<int32_t>(HWC2::Error::None);
548 }
549 #endif
550
551 /* Layer functions */
552
SetLayerBlendMode(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t mode)553 static int32_t SetLayerBlendMode(hwc2_device_t *device, hwc2_display_t display,
554 hwc2_layer_t layer,
555 int32_t /*hwc2_blend_mode_t*/ mode) {
556 ALOGV("SetLayerBlendMode");
557 LOCK_COMPOSER(device);
558 GET_DISPLAY(display);
559 GET_LAYER(layer);
560
561 BufferBlendMode blend_mode{};
562 switch (static_cast<HWC2::BlendMode>(mode)) {
563 case HWC2::BlendMode::None:
564 blend_mode = BufferBlendMode::kNone;
565 break;
566 case HWC2::BlendMode::Premultiplied:
567 blend_mode = BufferBlendMode::kPreMult;
568 break;
569 case HWC2::BlendMode::Coverage:
570 blend_mode = BufferBlendMode::kCoverage;
571 break;
572 default:
573 ALOGE("Unknown blending mode b=%d", mode);
574 blend_mode = BufferBlendMode::kUndefined;
575 break;
576 }
577
578 HwcLayer::LayerProperties layer_properties;
579 layer_properties.blend_mode = blend_mode;
580
581 ilayer->SetLayerProperties(layer_properties);
582
583 return 0;
584 }
585
SetLayerBuffer(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,buffer_handle_t buffer,int32_t acquire_fence)586 static int32_t SetLayerBuffer(hwc2_device_t *device, hwc2_display_t display,
587 hwc2_layer_t layer, buffer_handle_t buffer,
588 int32_t acquire_fence) {
589 ALOGV("SetLayerBuffer");
590 LOCK_COMPOSER(device);
591 GET_DISPLAY(display);
592 GET_LAYER(layer);
593
594 auto h2l = GetHwc2DeviceLayer(*ilayer);
595
596 auto [lp, not_a_swapchain] = h2l->HandleNextBuffer(buffer, acquire_fence);
597 if (!lp) {
598 ALOGV("Failed to process layer buffer");
599 return static_cast<int32_t>(HWC2::Error::BadLayer);
600 }
601
602 if (not_a_swapchain) {
603 ilayer->ClearSlots();
604 }
605
606 ilayer->SetLayerProperties(lp.value());
607
608 return 0;
609 }
610
SetLayerDataspace(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t dataspace)611 static int32_t SetLayerDataspace(hwc2_device_t *device, hwc2_display_t display,
612 hwc2_layer_t layer,
613 int32_t /*android_dataspace_t*/ dataspace) {
614 ALOGV("SetLayerDataspace");
615 LOCK_COMPOSER(device);
616 GET_DISPLAY(display);
617 GET_LAYER(layer);
618
619 HwcLayer::LayerProperties layer_properties;
620 layer_properties.color_space = Hwc2ToColorSpace(dataspace);
621 layer_properties.sample_range = Hwc2ToSampleRange(dataspace);
622 ilayer->SetLayerProperties(layer_properties);
623 return 0;
624 }
625
SetCursorPosition(hwc2_device_t *,hwc2_display_t,hwc2_layer_t,int32_t,int32_t)626 static int32_t SetCursorPosition(hwc2_device_t * /*device*/,
627 hwc2_display_t /*display*/,
628 hwc2_layer_t /*layer*/, int32_t /*x*/,
629 int32_t /*y*/) {
630 ALOGV("SetCursorPosition");
631 return 0;
632 }
633
SetLayerColor(hwc2_device_t *,hwc2_display_t,hwc2_layer_t,hwc_color_t)634 static int32_t SetLayerColor(hwc2_device_t * /*device*/,
635 hwc2_display_t /*display*/, hwc2_layer_t /*layer*/,
636 hwc_color_t /*color*/) {
637 ALOGV("SetLayerColor");
638 return 0;
639 }
640
SetLayerCompositionType(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t type)641 static int32_t SetLayerCompositionType(hwc2_device_t *device,
642 hwc2_display_t display,
643 hwc2_layer_t layer,
644 int32_t /*hwc2_composition_t*/ type) {
645 ALOGV("SetLayerCompositionType");
646 LOCK_COMPOSER(device);
647 GET_DISPLAY(display);
648 GET_LAYER(layer);
649
650 HwcLayer::LayerProperties layer_properties;
651 layer_properties.composition_type = static_cast<HWC2::Composition>(type);
652 ilayer->SetLayerProperties(layer_properties);
653
654 return 0;
655 }
656
SetLayerDisplayFrame(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_rect_t frame)657 static int32_t SetLayerDisplayFrame(hwc2_device_t *device,
658 hwc2_display_t display, hwc2_layer_t layer,
659 hwc_rect_t frame) {
660 ALOGV("SetLayerDisplayFrame");
661 LOCK_COMPOSER(device);
662 GET_DISPLAY(display);
663 GET_LAYER(layer);
664
665 HwcLayer::LayerProperties layer_properties;
666 layer_properties.display_frame = {
667 .i_rect = DstRectInfo::IRect{.left = frame.left,
668 .top = frame.top,
669 .right = frame.right,
670 .bottom = frame.bottom}};
671 ilayer->SetLayerProperties(layer_properties);
672
673 return 0;
674 }
675
SetLayerPlaneAlpha(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,float alpha)676 static int32_t SetLayerPlaneAlpha(hwc2_device_t *device, hwc2_display_t display,
677 hwc2_layer_t layer, float alpha) {
678 ALOGV("SetLayerPlaneAlpha");
679 LOCK_COMPOSER(device);
680 GET_DISPLAY(display);
681 GET_LAYER(layer);
682
683 HwcLayer::LayerProperties layer_properties;
684 layer_properties.alpha = alpha;
685 ilayer->SetLayerProperties(layer_properties);
686
687 return 0;
688 }
689
SetLayerSidebandStream(hwc2_device_t *,hwc2_display_t,hwc2_layer_t,const native_handle_t *)690 static int32_t SetLayerSidebandStream(hwc2_device_t * /*device*/,
691 hwc2_display_t /*display*/,
692 hwc2_layer_t /*layer*/,
693 const native_handle_t * /*stream*/) {
694 ALOGV("SetLayerSidebandStream");
695 return static_cast<int32_t>(HWC2::Error::Unsupported);
696 }
697
SetLayerSourceCrop(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,hwc_frect_t crop)698 static int32_t SetLayerSourceCrop(hwc2_device_t *device, hwc2_display_t display,
699 hwc2_layer_t layer, hwc_frect_t crop) {
700 ALOGV("SetLayerSourceCrop");
701 LOCK_COMPOSER(device);
702 GET_DISPLAY(display);
703 GET_LAYER(layer);
704
705 HwcLayer::LayerProperties layer_properties;
706 layer_properties.source_crop = {
707 .f_rect = SrcRectInfo::FRect{.left = crop.left,
708 .top = crop.top,
709 .right = crop.right,
710 .bottom = crop.bottom}};
711 ilayer->SetLayerProperties(layer_properties);
712
713 return 0;
714 }
715
SetLayerSurfaceDamage(hwc2_device_t *,hwc2_display_t,hwc2_layer_t,hwc_region_t)716 static int32_t SetLayerSurfaceDamage(hwc2_device_t * /*device*/,
717 hwc2_display_t /*display*/,
718 hwc2_layer_t /*layer*/,
719 hwc_region_t /*damage*/) {
720 ALOGV("SetLayerSurfaceDamage");
721 return 0;
722 }
723
SetLayerTransform(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,int32_t transform)724 static int32_t SetLayerTransform(hwc2_device_t *device, hwc2_display_t display,
725 hwc2_layer_t layer, int32_t transform) {
726 ALOGV("SetLayerTransform");
727 LOCK_COMPOSER(device);
728 GET_DISPLAY(display);
729 GET_LAYER(layer);
730
731 HwcLayer::LayerProperties layer_properties;
732 layer_properties.transform = {
733 .hflip = (transform & HAL_TRANSFORM_FLIP_H) != 0,
734 .vflip = (transform & HAL_TRANSFORM_FLIP_V) != 0,
735 .rotate90 = (transform & HAL_TRANSFORM_ROT_90) != 0,
736 };
737 ilayer->SetLayerProperties(layer_properties);
738
739 return 0;
740 }
741
SetLayerVisibleRegion(hwc2_device_t *,hwc2_display_t,hwc2_layer_t,hwc_region_t)742 static int32_t SetLayerVisibleRegion(hwc2_device_t * /*device*/,
743 hwc2_display_t /*display*/,
744 hwc2_layer_t /*layer*/,
745 hwc_region_t /*visible*/) {
746 ALOGV("SetLayerVisibleRegion");
747 return 0;
748 }
749
SetLayerZOrder(hwc2_device_t * device,hwc2_display_t display,hwc2_layer_t layer,uint32_t z)750 static int32_t SetLayerZOrder(hwc2_device_t *device, hwc2_display_t display,
751 hwc2_layer_t layer, uint32_t z) {
752 ALOGV("SetLayerZOrder");
753 LOCK_COMPOSER(device);
754 GET_DISPLAY(display);
755 GET_LAYER(layer);
756
757 HwcLayer::LayerProperties layer_properties;
758 layer_properties.z_order = z;
759 ilayer->SetLayerProperties(layer_properties);
760
761 return 0;
762 }
763
764 /* Entry point for the HWC2 API */
765 // NOLINTBEGIN(cppcoreguidelines-pro-type-cstyle-cast)
766
HookDevGetFunction(struct hwc2_device *,int32_t descriptor)767 static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
768 int32_t descriptor) {
769 auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
770 switch (func) {
771 // Device functions
772 case HWC2::FunctionDescriptor::CreateVirtualDisplay:
773 return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
774 DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
775 &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
776 int32_t *, hwc2_display_t *>);
777 case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
778 return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
779 DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
780 &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
781 case HWC2::FunctionDescriptor::Dump:
782 return ToHook<HWC2_PFN_DUMP>(
783 DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
784 uint32_t *, char *>);
785 case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
786 return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
787 DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
788 &DrmHwcTwo::GetMaxVirtualDisplayCount>);
789 case HWC2::FunctionDescriptor::RegisterCallback:
790 return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
791 DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
792 &DrmHwcTwo::RegisterCallback, int32_t,
793 hwc2_callback_data_t, hwc2_function_pointer_t>);
794
795 // Display functions
796 case HWC2::FunctionDescriptor::AcceptDisplayChanges:
797 return (hwc2_function_pointer_t)AcceptDisplayChanges;
798 case HWC2::FunctionDescriptor::CreateLayer:
799 return (hwc2_function_pointer_t)CreateLayer;
800 case HWC2::FunctionDescriptor::DestroyLayer:
801 return (hwc2_function_pointer_t)DestroyLayer;
802 case HWC2::FunctionDescriptor::GetActiveConfig:
803 return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
804 DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
805 &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
806 case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
807 return (hwc2_function_pointer_t)GetChangedCompositionTypes;
808 case HWC2::FunctionDescriptor::GetClientTargetSupport:
809 return (hwc2_function_pointer_t)GetClientTargetSupport;
810 case HWC2::FunctionDescriptor::GetColorModes:
811 return ToHook<HWC2_PFN_GET_COLOR_MODES>(
812 DisplayHook<decltype(&HwcDisplay::GetColorModes),
813 &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
814 case HWC2::FunctionDescriptor::GetDisplayAttribute:
815 return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
816 DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
817 &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
818 int32_t *>);
819 case HWC2::FunctionDescriptor::GetDisplayConfigs:
820 return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
821 DisplayHook<decltype(&HwcDisplay::LegacyGetDisplayConfigs),
822 &HwcDisplay::LegacyGetDisplayConfigs, uint32_t *,
823 hwc2_config_t *>);
824 case HWC2::FunctionDescriptor::GetDisplayName:
825 return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
826 DisplayHook<decltype(&HwcDisplay::GetDisplayName),
827 &HwcDisplay::GetDisplayName, uint32_t *, char *>);
828 case HWC2::FunctionDescriptor::GetDisplayRequests:
829 return (hwc2_function_pointer_t)GetDisplayRequests;
830 case HWC2::FunctionDescriptor::GetDisplayType:
831 return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
832 DisplayHook<decltype(&HwcDisplay::GetDisplayType),
833 &HwcDisplay::GetDisplayType, int32_t *>);
834 case HWC2::FunctionDescriptor::GetDozeSupport:
835 return (hwc2_function_pointer_t)GetDozeSupport;
836 case HWC2::FunctionDescriptor::GetHdrCapabilities:
837 return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
838 DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
839 &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
840 float *, float *, float *>);
841 case HWC2::FunctionDescriptor::GetReleaseFences:
842 return (hwc2_function_pointer_t)GetReleaseFences;
843 case HWC2::FunctionDescriptor::PresentDisplay:
844 return (hwc2_function_pointer_t)PresentDisplay;
845 case HWC2::FunctionDescriptor::SetActiveConfig:
846 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
847 DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
848 &HwcDisplay::SetActiveConfig, hwc2_config_t>);
849 case HWC2::FunctionDescriptor::SetClientTarget:
850 return (hwc2_function_pointer_t)SetClientTarget;
851 case HWC2::FunctionDescriptor::SetColorMode:
852 return ToHook<HWC2_PFN_SET_COLOR_MODE>(
853 DisplayHook<decltype(&HwcDisplay::SetColorMode),
854 &HwcDisplay::SetColorMode, int32_t>);
855 case HWC2::FunctionDescriptor::SetColorTransform:
856 return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
857 DisplayHook<decltype(&HwcDisplay::SetColorTransform),
858 &HwcDisplay::SetColorTransform, const float *, int32_t>);
859 case HWC2::FunctionDescriptor::SetOutputBuffer:
860 return (hwc2_function_pointer_t)SetOutputBuffer;
861 case HWC2::FunctionDescriptor::SetPowerMode:
862 return ToHook<HWC2_PFN_SET_POWER_MODE>(
863 DisplayHook<decltype(&HwcDisplay::SetPowerMode),
864 &HwcDisplay::SetPowerMode, int32_t>);
865 case HWC2::FunctionDescriptor::SetVsyncEnabled:
866 return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
867 DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
868 &HwcDisplay::SetVsyncEnabled, int32_t>);
869 case HWC2::FunctionDescriptor::ValidateDisplay:
870 return (hwc2_function_pointer_t)ValidateDisplay;
871 #if __ANDROID_API__ > 27
872 case HWC2::FunctionDescriptor::GetRenderIntents:
873 return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
874 DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
875 &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
876 int32_t *>);
877 case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
878 return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
879 DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
880 &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
881 #endif
882 #if __ANDROID_API__ > 28
883 case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
884 return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
885 DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
886 &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
887 uint32_t *, uint8_t *>);
888 case HWC2::FunctionDescriptor::GetDisplayCapabilities:
889 return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
890 DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
891 &HwcDisplay::GetDisplayCapabilities, uint32_t *,
892 uint32_t *>);
893 case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
894 return (hwc2_function_pointer_t)GetDisplayBrightnessSupport;
895 case HWC2::FunctionDescriptor::SetDisplayBrightness:
896 return (hwc2_function_pointer_t)SetDisplayBrightness;
897 #endif /* __ANDROID_API__ > 28 */
898 #if __ANDROID_API__ > 29
899 case HWC2::FunctionDescriptor::GetDisplayConnectionType:
900 return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
901 DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
902 &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
903 case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
904 return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
905 DisplayHook<decltype(&HwcDisplay::GetDisplayVsyncPeriod),
906 &HwcDisplay::GetDisplayVsyncPeriod,
907 hwc2_vsync_period_t *>);
908 case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
909 return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(
910 DisplayHook<decltype(&HwcDisplay::SetActiveConfigWithConstraints),
911 &HwcDisplay::SetActiveConfigWithConstraints,
912 hwc2_config_t, hwc_vsync_period_change_constraints_t *,
913 hwc_vsync_period_change_timeline_t *>);
914 case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
915 return (hwc2_function_pointer_t)SetAutoLowLatencyMode;
916 case HWC2::FunctionDescriptor::GetSupportedContentTypes:
917 return (hwc2_function_pointer_t)GetSupportedContentTypes;
918 case HWC2::FunctionDescriptor::SetContentType:
919 return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
920 DisplayHook<decltype(&HwcDisplay::SetContentType),
921 &HwcDisplay::SetContentType, int32_t>);
922 #endif
923 // Layer functions
924 case HWC2::FunctionDescriptor::SetCursorPosition:
925 return (hwc2_function_pointer_t)SetCursorPosition;
926 case HWC2::FunctionDescriptor::SetLayerBlendMode:
927 return (hwc2_function_pointer_t)SetLayerBlendMode;
928 case HWC2::FunctionDescriptor::SetLayerBuffer:
929 return (hwc2_function_pointer_t)SetLayerBuffer;
930 case HWC2::FunctionDescriptor::SetLayerColor:
931 return (hwc2_function_pointer_t)SetLayerColor;
932 case HWC2::FunctionDescriptor::SetLayerCompositionType:
933 return (hwc2_function_pointer_t)SetLayerCompositionType;
934 case HWC2::FunctionDescriptor::SetLayerDataspace:
935 return (hwc2_function_pointer_t)SetLayerDataspace;
936 case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
937 return (hwc2_function_pointer_t)SetLayerDisplayFrame;
938 case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
939 return (hwc2_function_pointer_t)SetLayerPlaneAlpha;
940 case HWC2::FunctionDescriptor::SetLayerSidebandStream:
941 return (hwc2_function_pointer_t)SetLayerSidebandStream;
942 case HWC2::FunctionDescriptor::SetLayerSourceCrop:
943 return (hwc2_function_pointer_t)SetLayerSourceCrop;
944 case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
945 return (hwc2_function_pointer_t)SetLayerSurfaceDamage;
946 case HWC2::FunctionDescriptor::SetLayerTransform:
947 return (hwc2_function_pointer_t)SetLayerTransform;
948 case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
949 return (hwc2_function_pointer_t)SetLayerVisibleRegion;
950 case HWC2::FunctionDescriptor::SetLayerZOrder:
951 return (hwc2_function_pointer_t)SetLayerZOrder;
952 case HWC2::FunctionDescriptor::Invalid:
953 default:
954 return nullptr;
955 }
956 }
957
958 // NOLINTEND(cppcoreguidelines-pro-type-cstyle-cast)
959
HookDevOpen(const struct hw_module_t * module,const char * name,struct hw_device_t ** dev)960 static int HookDevOpen(const struct hw_module_t *module, const char *name,
961 struct hw_device_t **dev) {
962 if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
963 ALOGE("Invalid module name- %s", name);
964 return -EINVAL;
965 }
966
967 auto ctx = std::make_unique<Drmhwc2Device>();
968 if (!ctx) {
969 ALOGE("Failed to allocate DrmHwcTwo");
970 return -ENOMEM;
971 }
972
973 ctx->common.tag = HARDWARE_DEVICE_TAG;
974 ctx->common.version = HWC_DEVICE_API_VERSION_2_0;
975 ctx->common.close = HookDevClose;
976 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
977 ctx->common.module = (hw_module_t *)module;
978 ctx->getCapabilities = HookDevGetCapabilities;
979 ctx->getFunction = HookDevGetFunction;
980
981 *dev = &ctx.release()->common;
982
983 return 0;
984 }
985
986 } // namespace android
987
988 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
989 static struct hw_module_methods_t hwc2_module_methods = {
990 .open = android::HookDevOpen,
991 };
992
993 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
994 hw_module_t HAL_MODULE_INFO_SYM = {
995 .tag = HARDWARE_MODULE_TAG,
996 .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
997 .id = HWC_HARDWARE_MODULE_ID,
998 .name = "DrmHwcTwo module",
999 .author = "The Android Open Source Project",
1000 .methods = &hwc2_module_methods,
1001 .dso = nullptr,
1002 .reserved = {0},
1003 };
1004