OSDN Git Service

drm_hwcomposer: Rework display modes handling
[android-x86/external-drm_hwcomposer.git] / DrmHwcTwo.cpp
1 /*
2  * Copyright (C) 2016 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 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18 #define LOG_TAG "hwc-drm-two"
19
20 #include "DrmHwcTwo.h"
21
22 #include <fcntl.h>
23 #include <hardware/hardware.h>
24 #include <hardware/hwcomposer2.h>
25 #include <sync/sync.h>
26 #include <unistd.h>
27
28 #include <cinttypes>
29 #include <iostream>
30 #include <sstream>
31 #include <string>
32
33 #include "backend/BackendManager.h"
34 #include "bufferinfo/BufferInfoGetter.h"
35 #include "compositor/DrmDisplayComposition.h"
36 #include "utils/log.h"
37 #include "utils/properties.h"
38
39 namespace android {
40
41 DrmHwcTwo::DrmHwcTwo() : hwc2_device() {
42   common.tag = HARDWARE_DEVICE_TAG;
43   common.version = HWC_DEVICE_API_VERSION_2_0;
44   common.close = HookDevClose;
45   getCapabilities = HookDevGetCapabilities;
46   getFunction = HookDevGetFunction;
47 }
48
49 HWC2::Error DrmHwcTwo::CreateDisplay(hwc2_display_t displ,
50                                      HWC2::DisplayType type) {
51   DrmDevice *drm = resource_manager_.GetDrmDevice(static_cast<int>(displ));
52   if (!drm) {
53     ALOGE("Failed to get a valid drmresource");
54     return HWC2::Error::NoResources;
55   }
56   displays_.emplace(std::piecewise_construct, std::forward_as_tuple(displ),
57                     std::forward_as_tuple(&resource_manager_, drm, displ, type,
58                                           this));
59
60   DrmCrtc *crtc = drm->GetCrtcForDisplay(static_cast<int>(displ));
61   if (!crtc) {
62     ALOGE("Failed to get crtc for display %d", static_cast<int>(displ));
63     return HWC2::Error::BadDisplay;
64   }
65   auto display_planes = std::vector<DrmPlane *>();
66   for (const auto &plane : drm->planes()) {
67     if (plane->GetCrtcSupported(*crtc))
68       display_planes.push_back(plane.get());
69   }
70   displays_.at(displ).Init(&display_planes);
71   return HWC2::Error::None;
72 }
73
74 HWC2::Error DrmHwcTwo::Init() {
75   int rv = resource_manager_.Init();
76   if (rv) {
77     ALOGE("Can't initialize the resource manager %d", rv);
78     return HWC2::Error::NoResources;
79   }
80
81   HWC2::Error ret = HWC2::Error::None;
82   for (int i = 0; i < resource_manager_.getDisplayCount(); i++) {
83     ret = CreateDisplay(i, HWC2::DisplayType::Physical);
84     if (ret != HWC2::Error::None) {
85       ALOGE("Failed to create display %d with error %d", i, ret);
86       return ret;
87     }
88   }
89
90   resource_manager_.GetUEventListener()->RegisterHotplugHandler(
91       [this] { HandleHotplugUEvent(); });
92
93   return ret;
94 }
95
96 template <typename... Args>
97 static inline HWC2::Error unsupported(char const *func, Args... /*args*/) {
98   ALOGV("Unsupported function: %s", func);
99   return HWC2::Error::Unsupported;
100 }
101
102 static inline void supported(char const *func) {
103   ALOGV("Supported function: %s", func);
104 }
105
106 HWC2::Error DrmHwcTwo::CreateVirtualDisplay(uint32_t width, uint32_t height,
107                                             int32_t *format,
108                                             hwc2_display_t *display) {
109   // TODO(nobody): Implement virtual display
110   return unsupported(__func__, width, height, format, display);
111 }
112
113 HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t display) {
114   // TODO(nobody): Implement virtual display
115   return unsupported(__func__, display);
116 }
117
118 std::string DrmHwcTwo::HwcDisplay::DumpDelta(
119     DrmHwcTwo::HwcDisplay::Stats delta) {
120   if (delta.total_pixops_ == 0)
121     return "No stats yet";
122   double ratio = 1.0 - double(delta.gpu_pixops_) / double(delta.total_pixops_);
123
124   std::stringstream ss;
125   ss << " Total frames count: " << delta.total_frames_ << "\n"
126      << " Failed to test commit frames: " << delta.failed_kms_validate_ << "\n"
127      << " Failed to commit frames: " << delta.failed_kms_present_ << "\n"
128      << ((delta.failed_kms_present_ > 0)
129              ? " !!! Internal failure, FIX it please\n"
130              : "")
131      << " Flattened frames: " << delta.frames_flattened_ << "\n"
132      << " Pixel operations (free units)"
133      << " : [TOTAL: " << delta.total_pixops_ << " / GPU: " << delta.gpu_pixops_
134      << "]\n"
135      << " Composition efficiency: " << ratio;
136
137   return ss.str();
138 }
139
140 std::string DrmHwcTwo::HwcDisplay::Dump() {
141   std::string flattening_state_str;
142   switch (flattenning_state_) {
143     case ClientFlattenningState::Disabled:
144       flattening_state_str = "Disabled";
145       break;
146     case ClientFlattenningState::NotRequired:
147       flattening_state_str = "Not needed";
148       break;
149     case ClientFlattenningState::Flattened:
150       flattening_state_str = "Active";
151       break;
152     case ClientFlattenningState::ClientRefreshRequested:
153       flattening_state_str = "Refresh requested";
154       break;
155     default:
156       flattening_state_str = std::to_string(flattenning_state_) +
157                              " VSync remains";
158   }
159
160   std::stringstream ss;
161   ss << "- Display on: " << connector_->name() << "\n"
162      << "  Flattening state: " << flattening_state_str << "\n"
163      << "Statistics since system boot:\n"
164      << DumpDelta(total_stats_) << "\n\n"
165      << "Statistics since last dumpsys request:\n"
166      << DumpDelta(total_stats_.minus(prev_stats_)) << "\n\n";
167
168   memcpy(&prev_stats_, &total_stats_, sizeof(Stats));
169   return ss.str();
170 }
171
172 void DrmHwcTwo::Dump(uint32_t *outSize, char *outBuffer) {
173   supported(__func__);
174
175   if (outBuffer != nullptr) {
176     auto copied_bytes = mDumpString.copy(outBuffer, *outSize);
177     *outSize = static_cast<uint32_t>(copied_bytes);
178     return;
179   }
180
181   std::stringstream output;
182
183   output << "-- drm_hwcomposer --\n\n";
184
185   for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &dp : displays_)
186     output << dp.second.Dump();
187
188   mDumpString = output.str();
189   *outSize = static_cast<uint32_t>(mDumpString.size());
190 }
191
192 uint32_t DrmHwcTwo::GetMaxVirtualDisplayCount() {
193   // TODO(nobody): Implement virtual display
194   unsupported(__func__);
195   return 0;
196 }
197
198 HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
199                                         hwc2_callback_data_t data,
200                                         hwc2_function_pointer_t function) {
201   supported(__func__);
202
203   std::unique_lock<std::mutex> lock(callback_lock_);
204
205   switch (static_cast<HWC2::Callback>(descriptor)) {
206     case HWC2::Callback::Hotplug: {
207       hotplug_callback_ = std::make_pair(HWC2_PFN_HOTPLUG(function), data);
208       lock.unlock();
209       const auto &drm_devices = resource_manager_.getDrmDevices();
210       for (const auto &device : drm_devices)
211         HandleInitialHotplugState(device.get());
212       break;
213     }
214     case HWC2::Callback::Refresh: {
215       refresh_callback_ = std::make_pair(HWC2_PFN_REFRESH(function), data);
216       break;
217     }
218     case HWC2::Callback::Vsync: {
219       vsync_callback_ = std::make_pair(HWC2_PFN_VSYNC(function), data);
220       break;
221     }
222 #if PLATFORM_SDK_VERSION > 29
223     case HWC2::Callback::Vsync_2_4: {
224       vsync_2_4_callback_ = std::make_pair(HWC2_PFN_VSYNC_2_4(function), data);
225       break;
226     }
227 #endif
228     default:
229       break;
230   }
231   return HWC2::Error::None;
232 }
233
234 DrmHwcTwo::HwcDisplay::HwcDisplay(ResourceManager *resource_manager,
235                                   DrmDevice *drm, hwc2_display_t handle,
236                                   HWC2::DisplayType type, DrmHwcTwo *hwc2)
237     : hwc2_(hwc2),
238       resource_manager_(resource_manager),
239       drm_(drm),
240       handle_(handle),
241       type_(type),
242       color_transform_hint_(HAL_COLOR_TRANSFORM_IDENTITY) {
243   supported(__func__);
244
245   // clang-format off
246   color_transform_matrix_ = {1.0, 0.0, 0.0, 0.0,
247                              0.0, 1.0, 0.0, 0.0,
248                              0.0, 0.0, 1.0, 0.0,
249                              0.0, 0.0, 0.0, 1.0};
250   // clang-format on
251 }
252
253 void DrmHwcTwo::HwcDisplay::ClearDisplay() {
254   AtomicCommitArgs a_args = {.clear_active_composition = true};
255   compositor_.ExecuteAtomicCommit(a_args);
256 }
257
258 HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) {
259   supported(__func__);
260   planner_ = Planner::CreateInstance(drm_);
261   if (!planner_) {
262     ALOGE("Failed to create planner instance for composition");
263     return HWC2::Error::NoResources;
264   }
265
266   int display = static_cast<int>(handle_);
267   int ret = compositor_.Init(resource_manager_, display);
268   if (ret) {
269     ALOGE("Failed display compositor init for display %d (%d)", display, ret);
270     return HWC2::Error::NoResources;
271   }
272
273   // Split up the given display planes into primary and overlay to properly
274   // interface with the composition
275   char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
276   property_get("vendor.hwc.drm.use_overlay_planes", use_overlay_planes_prop,
277                "1");
278   bool use_overlay_planes = strtol(use_overlay_planes_prop, nullptr, 10);
279   for (auto &plane : *planes) {
280     if (plane->type() == DRM_PLANE_TYPE_PRIMARY)
281       primary_planes_.push_back(plane);
282     else if (use_overlay_planes && (plane)->type() == DRM_PLANE_TYPE_OVERLAY)
283       overlay_planes_.push_back(plane);
284   }
285
286   crtc_ = drm_->GetCrtcForDisplay(display);
287   if (!crtc_) {
288     ALOGE("Failed to get crtc for display %d", display);
289     return HWC2::Error::BadDisplay;
290   }
291
292   connector_ = drm_->GetConnectorForDisplay(display);
293   if (!connector_) {
294     ALOGE("Failed to get connector for display %d", display);
295     return HWC2::Error::BadDisplay;
296   }
297
298   ret = vsync_worker_.Init(drm_, display, [this](int64_t timestamp) {
299     const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
300     /* vsync callback */
301 #if PLATFORM_SDK_VERSION > 29
302     if (hwc2_->vsync_2_4_callback_.first != nullptr &&
303         hwc2_->vsync_2_4_callback_.second != nullptr) {
304       hwc2_vsync_period_t period_ns{};
305       GetDisplayVsyncPeriod(&period_ns);
306       hwc2_->vsync_2_4_callback_.first(hwc2_->vsync_2_4_callback_.second,
307                                        handle_, timestamp, period_ns);
308     } else
309 #endif
310         if (hwc2_->vsync_callback_.first != nullptr &&
311             hwc2_->vsync_callback_.second != nullptr) {
312       hwc2_->vsync_callback_.first(hwc2_->vsync_callback_.second, handle_,
313                                    timestamp);
314     }
315   });
316   if (ret) {
317     ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
318     return HWC2::Error::BadDisplay;
319   }
320
321   ret = flattening_vsync_worker_.Init(drm_, display, [this](int64_t /*timestamp*/) {
322     const std::lock_guard<std::mutex> lock(hwc2_->callback_lock_);
323     /* Frontend flattening */
324     if (flattenning_state_ > ClientFlattenningState::ClientRefreshRequested &&
325         --flattenning_state_ ==
326             ClientFlattenningState::ClientRefreshRequested &&
327         hwc2_->refresh_callback_.first != nullptr &&
328         hwc2_->refresh_callback_.second != nullptr) {
329       hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second, handle_);
330       flattening_vsync_worker_.VSyncControl(false);
331     }
332   });
333   if (ret) {
334     ALOGE("Failed to create event worker for d=%d %d\n", display, ret);
335     return HWC2::Error::BadDisplay;
336   }
337
338   ret = BackendManager::GetInstance().SetBackendForDisplay(this);
339   if (ret) {
340     ALOGE("Failed to set backend for d=%d %d\n", display, ret);
341     return HWC2::Error::BadDisplay;
342   }
343
344   return ChosePreferredConfig();
345 }
346
347 HWC2::Error DrmHwcTwo::HwcDisplay::ChosePreferredConfig() {
348   // Fetch the number of modes from the display
349   uint32_t num_configs = 0;
350   HWC2::Error err = GetDisplayConfigs(&num_configs, nullptr);
351   if (err != HWC2::Error::None || !num_configs)
352     return HWC2::Error::BadDisplay;
353
354   return SetActiveConfig(preferred_config_id_);
355 }
356
357 HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() {
358   supported(__func__);
359   for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
360     l.second.accept_type_change();
361   return HWC2::Error::None;
362 }
363
364 HWC2::Error DrmHwcTwo::HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
365   supported(__func__);
366   layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer());
367   *layer = static_cast<hwc2_layer_t>(layer_idx_);
368   ++layer_idx_;
369   return HWC2::Error::None;
370 }
371
372 HWC2::Error DrmHwcTwo::HwcDisplay::DestroyLayer(hwc2_layer_t layer) {
373   supported(__func__);
374   if (!get_layer(layer))
375     return HWC2::Error::BadLayer;
376
377   layers_.erase(layer);
378   return HWC2::Error::None;
379 }
380
381 HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(
382     hwc2_config_t *config) const {
383   supported(__func__);
384   if (hwc_configs_.count(active_config_id_) == 0)
385     return HWC2::Error::BadConfig;
386
387   *config = active_config_id_;
388   return HWC2::Error::None;
389 }
390
391 HWC2::Error DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes(
392     uint32_t *num_elements, hwc2_layer_t *layers, int32_t *types) {
393   supported(__func__);
394   uint32_t num_changes = 0;
395   for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
396     if (l.second.type_changed()) {
397       if (layers && num_changes < *num_elements)
398         layers[num_changes] = l.first;
399       if (types && num_changes < *num_elements)
400         types[num_changes] = static_cast<int32_t>(l.second.validated_type());
401       ++num_changes;
402     }
403   }
404   if (!layers && !types)
405     *num_elements = num_changes;
406   return HWC2::Error::None;
407 }
408
409 HWC2::Error DrmHwcTwo::HwcDisplay::GetClientTargetSupport(uint32_t width,
410                                                           uint32_t height,
411                                                           int32_t /*format*/,
412                                                           int32_t dataspace) {
413   supported(__func__);
414   std::pair<uint32_t, uint32_t> min = drm_->min_resolution();
415   std::pair<uint32_t, uint32_t> max = drm_->max_resolution();
416
417   if (width < min.first || height < min.second)
418     return HWC2::Error::Unsupported;
419
420   if (width > max.first || height > max.second)
421     return HWC2::Error::Unsupported;
422
423   if (dataspace != HAL_DATASPACE_UNKNOWN)
424     return HWC2::Error::Unsupported;
425
426   // TODO(nobody): Validate format can be handled by either GL or planes
427   return HWC2::Error::None;
428 }
429
430 HWC2::Error DrmHwcTwo::HwcDisplay::GetColorModes(uint32_t *num_modes,
431                                                  int32_t *modes) {
432   supported(__func__);
433   if (!modes)
434     *num_modes = 1;
435
436   if (modes)
437     *modes = HAL_COLOR_MODE_NATIVE;
438
439   return HWC2::Error::None;
440 }
441
442 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayAttribute(hwc2_config_t config,
443                                                        int32_t attribute_in,
444                                                        int32_t *value) {
445   supported(__func__);
446   int conf = static_cast<int>(config);
447
448   if (hwc_configs_.count(conf) == 0) {
449     ALOGE("Could not find active mode for %d", conf);
450     return HWC2::Error::BadConfig;
451   }
452
453   auto &hwc_config = hwc_configs_[conf];
454
455   static const int32_t kUmPerInch = 25400;
456   uint32_t mm_width = connector_->mm_width();
457   uint32_t mm_height = connector_->mm_height();
458   auto attribute = static_cast<HWC2::Attribute>(attribute_in);
459   switch (attribute) {
460     case HWC2::Attribute::Width:
461       *value = static_cast<int>(hwc_config.mode.h_display());
462       break;
463     case HWC2::Attribute::Height:
464       *value = static_cast<int>(hwc_config.mode.v_display());
465       break;
466     case HWC2::Attribute::VsyncPeriod:
467       // in nanoseconds
468       *value = static_cast<int>(1E9 / hwc_config.mode.v_refresh());
469       break;
470     case HWC2::Attribute::DpiX:
471       // Dots per 1000 inches
472       *value = mm_width ? static_cast<int>(hwc_config.mode.h_display() *
473                                            kUmPerInch / mm_width)
474                         : -1;
475       break;
476     case HWC2::Attribute::DpiY:
477       // Dots per 1000 inches
478       *value = mm_height ? static_cast<int>(hwc_config.mode.v_display() *
479                                             kUmPerInch / mm_height)
480                          : -1;
481       break;
482 #if PLATFORM_SDK_VERSION > 29
483     case HWC2::Attribute::ConfigGroup:
484       /* Dispite ConfigGroup is a part of HWC2.4 API, framework
485        * able to request it even if service @2.1 is used */
486       *value = hwc_config.group_id;
487       break;
488 #endif
489     default:
490       *value = -1;
491       return HWC2::Error::BadConfig;
492   }
493   return HWC2::Error::None;
494 }
495
496 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs,
497                                                      hwc2_config_t *configs) {
498   supported(__func__);
499   // Since this callback is normally invoked twice (once to get the count, and
500   // once to populate configs), we don't really want to read the edid
501   // redundantly. Instead, only update the modes on the first invocation. While
502   // it's possible this will result in stale modes, it'll all come out in the
503   // wash when we try to set the active config later.
504   if (!configs) {
505     int ret = connector_->UpdateModes();
506     if (ret) {
507       ALOGE("Failed to update display modes %d", ret);
508       return HWC2::Error::BadDisplay;
509     }
510
511     hwc_configs_.clear();
512     preferred_config_id_ = 0;
513     int preferred_config_group_id_ = 0;
514
515     if (connector_->modes().empty()) {
516       ALOGE("No modes reported by KMS");
517       return HWC2::Error::BadDisplay;
518     }
519
520     int last_config_id = 1;
521     int last_group_id = 1;
522
523     /* Group modes */
524     for (const auto &mode : connector_->modes()) {
525       /* Find group for the new mode or create new group */
526       int group_found = 0;
527       for (auto &hwc_config : hwc_configs_) {
528         if (mode.h_display() == hwc_config.second.mode.h_display() &&
529             mode.v_display() == hwc_config.second.mode.v_display()) {
530           group_found = hwc_config.second.group_id;
531         }
532       }
533       if (group_found == 0) {
534         group_found = last_group_id++;
535       }
536
537       bool disabled = false;
538       if (mode.flags() & DRM_MODE_FLAG_3D_MASK) {
539         ALOGI("Disabling display mode %s (Modes with 3D flag aren't supported)",
540               mode.name().c_str());
541         disabled = true;
542       }
543
544       /* Add config */
545       hwc_configs_[last_config_id] = {
546           .id = last_config_id,
547           .group_id = group_found,
548           .mode = mode,
549           .disabled = disabled,
550       };
551
552       /* Chwck if the mode is preferred */
553       if ((mode.type() & DRM_MODE_TYPE_PREFERRED) != 0 &&
554           preferred_config_id_ == 0) {
555         preferred_config_id_ = last_config_id;
556         preferred_config_group_id_ = group_found;
557       }
558
559       last_config_id++;
560     }
561
562     /* We must have preferred mode. Set first mode as preferred
563      * in case KMS haven't reported anything. */
564     if (preferred_config_id_ == 0) {
565       preferred_config_id_ = 1;
566       preferred_config_group_id_ = 1;
567     }
568
569     for (int group = 1; group < last_group_id; group++) {
570       bool has_interlaced = false;
571       bool has_progressive = false;
572       for (auto &hwc_config : hwc_configs_) {
573         if (hwc_config.second.group_id != group || hwc_config.second.disabled) {
574           continue;
575         }
576
577         if (hwc_config.second.IsInterlaced()) {
578           has_interlaced = true;
579         } else {
580           has_progressive = true;
581         }
582       }
583
584       bool has_both = has_interlaced && has_progressive;
585       if (!has_both) {
586         continue;
587       }
588
589       bool group_contains_preferred_interlaced = false;
590       if (group == preferred_config_group_id_ &&
591           hwc_configs_[preferred_config_id_].IsInterlaced()) {
592         group_contains_preferred_interlaced = true;
593       }
594
595       for (auto &hwc_config : hwc_configs_) {
596         if (hwc_config.second.group_id != group || hwc_config.second.disabled) {
597           continue;
598         }
599
600         bool disable = group_contains_preferred_interlaced
601                            ? !hwc_config.second.IsInterlaced()
602                            : hwc_config.second.IsInterlaced();
603
604         if (disable) {
605           ALOGI(
606               "Group %i: Disabling display mode %s (This group should consist "
607               "of %s modes)",
608               group, hwc_config.second.mode.name().c_str(),
609               group_contains_preferred_interlaced ? "interlaced"
610                                                   : "progressive");
611
612           hwc_config.second.disabled = true;
613         }
614       }
615     }
616
617     /* Group should not contain 2 modes with FPS delta less than ~1HZ
618      * otherwise android.graphics.cts.SetFrameRateTest CTS will fail
619      */
620     for (int m1 = 1; m1 < last_config_id; m1++) {
621       for (int m2 = 1; m2 < last_config_id; m2++) {
622         if (m1 != m2 &&
623             hwc_configs_[m1].group_id == hwc_configs_[m2].group_id &&
624             !hwc_configs_[m1].disabled && !hwc_configs_[m2].disabled &&
625             fabsf(hwc_configs_[m1].mode.v_refresh() -
626                   hwc_configs_[m2].mode.v_refresh()) < 1.0) {
627           ALOGI(
628               "Group %i: Disabling display mode %s (Refresh rate value is "
629               "too close to existing mode %s)",
630               hwc_configs_[m2].group_id, hwc_configs_[m2].mode.name().c_str(),
631               hwc_configs_[m1].mode.name().c_str());
632
633           hwc_configs_[m2].disabled = true;
634         }
635       }
636     }
637   }
638
639   uint32_t idx = 0;
640   for (auto &hwc_config : hwc_configs_) {
641     if (hwc_config.second.disabled) {
642       continue;
643     }
644
645     if (configs != nullptr) {
646       if (idx >= *num_configs) {
647         break;
648       }
649       configs[idx] = hwc_config.second.id;
650     }
651
652     idx++;
653   }
654   *num_configs = idx;
655   return HWC2::Error::None;
656 }
657
658 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayName(uint32_t *size, char *name) {
659   supported(__func__);
660   std::ostringstream stream;
661   stream << "display-" << connector_->id();
662   std::string string = stream.str();
663   size_t length = string.length();
664   if (!name) {
665     *size = length;
666     return HWC2::Error::None;
667   }
668
669   *size = std::min<uint32_t>(static_cast<uint32_t>(length - 1), *size);
670   strncpy(name, string.c_str(), *size);
671   return HWC2::Error::None;
672 }
673
674 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayRequests(int32_t *display_requests,
675                                                       uint32_t *num_elements,
676                                                       hwc2_layer_t *layers,
677                                                       int32_t *layer_requests) {
678   supported(__func__);
679   // TODO(nobody): I think virtual display should request
680   //      HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here
681   unsupported(__func__, display_requests, num_elements, layers, layer_requests);
682   *num_elements = 0;
683   return HWC2::Error::None;
684 }
685
686 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) {
687   supported(__func__);
688   *type = static_cast<int32_t>(type_);
689   return HWC2::Error::None;
690 }
691
692 HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) {
693   supported(__func__);
694   *support = 0;
695   return HWC2::Error::None;
696 }
697
698 HWC2::Error DrmHwcTwo::HwcDisplay::GetHdrCapabilities(
699     uint32_t *num_types, int32_t * /*types*/, float * /*max_luminance*/,
700     float * /*max_average_luminance*/, float * /*min_luminance*/) {
701   supported(__func__);
702   *num_types = 0;
703   return HWC2::Error::None;
704 }
705
706 /* Find API details at:
707  * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1767
708  */
709 HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements,
710                                                     hwc2_layer_t *layers,
711                                                     int32_t *fences) {
712   supported(__func__);
713   uint32_t num_layers = 0;
714
715   for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
716     ++num_layers;
717     if (layers == nullptr || fences == nullptr)
718       continue;
719
720     if (num_layers > *num_elements) {
721       ALOGW("Overflow num_elements %d/%d", num_layers, *num_elements);
722       return HWC2::Error::None;
723     }
724
725     layers[num_layers - 1] = l.first;
726     fences[num_layers - 1] = l.second.release_fence_.Release();
727   }
728   *num_elements = num_layers;
729   return HWC2::Error::None;
730 }
731
732 HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) {
733   // order the layers by z-order
734   bool use_client_layer = false;
735   uint32_t client_z_order = UINT32_MAX;
736   std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map;
737   for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
738     switch (l.second.validated_type()) {
739       case HWC2::Composition::Device:
740         z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
741         break;
742       case HWC2::Composition::Client:
743         // Place it at the z_order of the lowest client layer
744         use_client_layer = true;
745         client_z_order = std::min(client_z_order, l.second.z_order());
746         break;
747       default:
748         continue;
749     }
750   }
751   if (use_client_layer)
752     z_map.emplace(std::make_pair(client_z_order, &client_layer_));
753
754   if (z_map.empty())
755     return HWC2::Error::BadLayer;
756
757   std::vector<DrmHwcLayer> composition_layers;
758
759   // now that they're ordered by z, add them to the composition
760   for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
761     DrmHwcLayer layer;
762     l.second->PopulateDrmLayer(&layer);
763     int ret = layer.ImportBuffer(drm_);
764     if (ret) {
765       ALOGE("Failed to import layer, ret=%d", ret);
766       return HWC2::Error::NoResources;
767     }
768     composition_layers.emplace_back(std::move(layer));
769   }
770
771   auto composition = std::make_shared<DrmDisplayComposition>(crtc_,
772                                                              planner_.get());
773
774   // TODO(nobody): Don't always assume geometry changed
775   int ret = composition->SetLayers(composition_layers.data(),
776                                    composition_layers.size());
777   if (ret) {
778     ALOGE("Failed to set layers in the composition ret=%d", ret);
779     return HWC2::Error::BadLayer;
780   }
781
782   std::vector<DrmPlane *> primary_planes(primary_planes_);
783   std::vector<DrmPlane *> overlay_planes(overlay_planes_);
784   ret = composition->Plan(&primary_planes, &overlay_planes);
785   if (ret) {
786     ALOGV("Failed to plan the composition ret=%d", ret);
787     return HWC2::Error::BadConfig;
788   }
789
790   // Disable the planes we're not using
791   for (auto i = primary_planes.begin(); i != primary_planes.end();) {
792     composition->AddPlaneDisable(*i);
793     i = primary_planes.erase(i);
794   }
795   for (auto i = overlay_planes.begin(); i != overlay_planes.end();) {
796     composition->AddPlaneDisable(*i);
797     i = overlay_planes.erase(i);
798   }
799
800   a_args.composition = composition;
801   ret = compositor_.ExecuteAtomicCommit(a_args);
802
803   if (ret) {
804     if (!a_args.test_only)
805       ALOGE("Failed to apply the frame composition ret=%d", ret);
806     return HWC2::Error::BadParameter;
807   }
808   return HWC2::Error::None;
809 }
810
811 /* Find API details at:
812  * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1805
813  */
814 HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *present_fence) {
815   supported(__func__);
816   HWC2::Error ret;
817
818   ++total_stats_.total_frames_;
819
820   AtomicCommitArgs a_args{};
821   ret = CreateComposition(a_args);
822
823   if (ret != HWC2::Error::None)
824     ++total_stats_.failed_kms_present_;
825
826   if (ret == HWC2::Error::BadLayer) {
827     // Can we really have no client or device layers?
828     *present_fence = -1;
829     return HWC2::Error::None;
830   }
831   if (ret != HWC2::Error::None)
832     return ret;
833
834   *present_fence = a_args.out_fence.Release();
835
836   ++frame_no_;
837   return HWC2::Error::None;
838 }
839
840 HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
841   supported(__func__);
842
843   int conf = static_cast<int>(config);
844
845   if (hwc_configs_.count(conf) == 0) {
846     ALOGE("Could not find active mode for %d", conf);
847     return HWC2::Error::BadConfig;
848   }
849
850   auto &mode = hwc_configs_[conf].mode;
851
852   AtomicCommitArgs a_args = {
853       .display_mode = mode,
854       .clear_active_composition = true,
855   };
856
857   int err = compositor_.ExecuteAtomicCommit(a_args);
858   if (err != 0) {
859     ALOGE("Failed to queue mode changing commit %d", err);
860     return HWC2::Error::BadConfig;
861   }
862
863   active_config_id_ = conf;
864
865   // Setup the client layer's dimensions
866   hwc_rect_t display_frame = {.left = 0,
867                               .top = 0,
868                               .right = static_cast<int>(mode.h_display()),
869                               .bottom = static_cast<int>(mode.v_display())};
870   client_layer_.SetLayerDisplayFrame(display_frame);
871
872   return HWC2::Error::None;
873 }
874
875 /* Find API details at:
876  * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1861
877  */
878 HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target,
879                                                    int32_t acquire_fence,
880                                                    int32_t dataspace,
881                                                    hwc_region_t /*damage*/) {
882   supported(__func__);
883
884   client_layer_.set_buffer(target);
885   client_layer_.acquire_fence_ = UniqueFd(acquire_fence);
886   client_layer_.SetLayerDataspace(dataspace);
887
888   /* TODO: Do not update source_crop every call.
889    * It makes sense to do it once after every hotplug event. */
890   hwc_drm_bo bo{};
891   BufferInfoGetter::GetInstance()->ConvertBoInfo(target, &bo);
892
893   hwc_frect_t source_crop = {.left = 0.0F,
894                              .top = 0.0F,
895                              .right = static_cast<float>(bo.width),
896                              .bottom = static_cast<float>(bo.height)};
897   client_layer_.SetLayerSourceCrop(source_crop);
898
899   return HWC2::Error::None;
900 }
901
902 HWC2::Error DrmHwcTwo::HwcDisplay::SetColorMode(int32_t mode) {
903   supported(__func__);
904
905   if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
906     return HWC2::Error::BadParameter;
907
908   if (mode != HAL_COLOR_MODE_NATIVE)
909     return HWC2::Error::Unsupported;
910
911   color_mode_ = mode;
912   return HWC2::Error::None;
913 }
914
915 HWC2::Error DrmHwcTwo::HwcDisplay::SetColorTransform(const float *matrix,
916                                                      int32_t hint) {
917   supported(__func__);
918   if (hint < HAL_COLOR_TRANSFORM_IDENTITY ||
919       hint > HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA)
920     return HWC2::Error::BadParameter;
921
922   if (!matrix && hint == HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX)
923     return HWC2::Error::BadParameter;
924
925   color_transform_hint_ = static_cast<android_color_transform_t>(hint);
926   if (color_transform_hint_ == HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX)
927     std::copy(matrix, matrix + MATRIX_SIZE, color_transform_matrix_.begin());
928
929   return HWC2::Error::None;
930 }
931
932 HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t buffer,
933                                                    int32_t release_fence) {
934   supported(__func__);
935   // TODO(nobody): Need virtual display support
936   return unsupported(__func__, buffer, release_fence);
937 }
938
939 HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) {
940   supported(__func__);
941   auto mode = static_cast<HWC2::PowerMode>(mode_in);
942   AtomicCommitArgs a_args{};
943
944   switch (mode) {
945     case HWC2::PowerMode::Off:
946       a_args.active = false;
947       break;
948     case HWC2::PowerMode::On:
949       a_args.active = true;
950       break;
951     case HWC2::PowerMode::Doze:
952     case HWC2::PowerMode::DozeSuspend:
953       return HWC2::Error::Unsupported;
954     default:
955       ALOGI("Power mode %d is unsupported\n", mode);
956       return HWC2::Error::BadParameter;
957   };
958
959   int err = compositor_.ExecuteAtomicCommit(a_args);
960   if (err) {
961     ALOGE("Failed to apply the dpms composition err=%d", err);
962     return HWC2::Error::BadParameter;
963   }
964   return HWC2::Error::None;
965 }
966
967 HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) {
968   supported(__func__);
969   vsync_worker_.VSyncControl(HWC2_VSYNC_ENABLE == enabled);
970   return HWC2::Error::None;
971 }
972
973 HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
974                                                    uint32_t *num_requests) {
975   supported(__func__);
976
977   return backend_->ValidateDisplay(this, num_types, num_requests);
978 }
979
980 std::vector<DrmHwcTwo::HwcLayer *>
981 DrmHwcTwo::HwcDisplay::GetOrderLayersByZPos() {
982   std::vector<DrmHwcTwo::HwcLayer *> ordered_layers;
983   ordered_layers.reserve(layers_.size());
984
985   for (auto &[handle, layer] : layers_) {
986     ordered_layers.emplace_back(&layer);
987   }
988
989   std::sort(std::begin(ordered_layers), std::end(ordered_layers),
990             [](const DrmHwcTwo::HwcLayer *lhs, const DrmHwcTwo::HwcLayer *rhs) {
991               return lhs->z_order() < rhs->z_order();
992             });
993
994   return ordered_layers;
995 }
996
997 #if PLATFORM_SDK_VERSION > 29
998 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConnectionType(uint32_t *outType) {
999   if (connector_->internal())
1000     *outType = static_cast<uint32_t>(HWC2::DisplayConnectionType::Internal);
1001   else if (connector_->external())
1002     *outType = static_cast<uint32_t>(HWC2::DisplayConnectionType::External);
1003   else
1004     return HWC2::Error::BadConfig;
1005
1006   return HWC2::Error::None;
1007 }
1008
1009 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayVsyncPeriod(
1010     hwc2_vsync_period_t *outVsyncPeriod /* ns */) {
1011   supported(__func__);
1012   return GetDisplayAttribute(active_config_id_, HWC2_ATTRIBUTE_VSYNC_PERIOD,
1013                              (int32_t *)(outVsyncPeriod));
1014 }
1015
1016 HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfigWithConstraints(
1017     hwc2_config_t /*config*/,
1018     hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
1019     hwc_vsync_period_change_timeline_t *outTimeline) {
1020   supported(__func__);
1021
1022   if (vsyncPeriodChangeConstraints == nullptr || outTimeline == nullptr) {
1023     return HWC2::Error::BadParameter;
1024   }
1025
1026   return HWC2::Error::BadConfig;
1027 }
1028
1029 HWC2::Error DrmHwcTwo::HwcDisplay::SetAutoLowLatencyMode(bool /*on*/) {
1030   return HWC2::Error::Unsupported;
1031 }
1032
1033 HWC2::Error DrmHwcTwo::HwcDisplay::GetSupportedContentTypes(
1034     uint32_t *outNumSupportedContentTypes,
1035     const uint32_t *outSupportedContentTypes) {
1036   if (outSupportedContentTypes == nullptr)
1037     *outNumSupportedContentTypes = 0;
1038
1039   return HWC2::Error::None;
1040 }
1041
1042 HWC2::Error DrmHwcTwo::HwcDisplay::SetContentType(int32_t contentType) {
1043   supported(__func__);
1044
1045   if (contentType != HWC2_CONTENT_TYPE_NONE)
1046     return HWC2::Error::Unsupported;
1047
1048   /* TODO: Map to the DRM Connector property:
1049    * https://elixir.bootlin.com/linux/v5.4-rc5/source/drivers/gpu/drm/drm_connector.c#L809
1050    */
1051
1052   return HWC2::Error::None;
1053 }
1054 #endif
1055
1056 #if PLATFORM_SDK_VERSION > 28
1057 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayIdentificationData(
1058     uint8_t *outPort, uint32_t *outDataSize, uint8_t *outData) {
1059   supported(__func__);
1060
1061   auto blob = connector_->GetEdidBlob();
1062
1063   if (!blob) {
1064     ALOGE("Failed to get edid property value.");
1065     return HWC2::Error::Unsupported;
1066   }
1067
1068   if (outData) {
1069     *outDataSize = std::min(*outDataSize, blob->length);
1070     memcpy(outData, blob->data, *outDataSize);
1071   } else {
1072     *outDataSize = blob->length;
1073   }
1074   *outPort = connector_->id();
1075
1076   return HWC2::Error::None;
1077 }
1078
1079 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayCapabilities(
1080     uint32_t *outNumCapabilities, uint32_t *outCapabilities) {
1081   unsupported(__func__, outCapabilities);
1082
1083   if (outNumCapabilities == nullptr) {
1084     return HWC2::Error::BadParameter;
1085   }
1086
1087   *outNumCapabilities = 0;
1088
1089   return HWC2::Error::None;
1090 }
1091
1092 HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayBrightnessSupport(
1093     bool *supported) {
1094   *supported = false;
1095   return HWC2::Error::None;
1096 }
1097
1098 HWC2::Error DrmHwcTwo::HwcDisplay::SetDisplayBrightness(
1099     float /* brightness */) {
1100   return HWC2::Error::Unsupported;
1101 }
1102
1103 #endif /* PLATFORM_SDK_VERSION > 28 */
1104
1105 #if PLATFORM_SDK_VERSION > 27
1106
1107 HWC2::Error DrmHwcTwo::HwcDisplay::GetRenderIntents(
1108     int32_t mode, uint32_t *outNumIntents,
1109     int32_t * /*android_render_intent_v1_1_t*/ outIntents) {
1110   if (mode != HAL_COLOR_MODE_NATIVE) {
1111     return HWC2::Error::BadParameter;
1112   }
1113
1114   if (outIntents == nullptr) {
1115     *outNumIntents = 1;
1116     return HWC2::Error::None;
1117   }
1118   *outNumIntents = 1;
1119   outIntents[0] = HAL_RENDER_INTENT_COLORIMETRIC;
1120   return HWC2::Error::None;
1121 }
1122
1123 HWC2::Error DrmHwcTwo::HwcDisplay::SetColorModeWithIntent(int32_t mode,
1124                                                           int32_t intent) {
1125   if (intent < HAL_RENDER_INTENT_COLORIMETRIC ||
1126       intent > HAL_RENDER_INTENT_TONE_MAP_ENHANCE)
1127     return HWC2::Error::BadParameter;
1128
1129   if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_BT2100_HLG)
1130     return HWC2::Error::BadParameter;
1131
1132   if (mode != HAL_COLOR_MODE_NATIVE)
1133     return HWC2::Error::Unsupported;
1134
1135   if (intent != HAL_RENDER_INTENT_COLORIMETRIC)
1136     return HWC2::Error::Unsupported;
1137
1138   color_mode_ = mode;
1139   return HWC2::Error::None;
1140 }
1141
1142 #endif /* PLATFORM_SDK_VERSION > 27 */
1143
1144 HWC2::Error DrmHwcTwo::HwcLayer::SetCursorPosition(int32_t /*x*/,
1145                                                    int32_t /*y*/) {
1146   supported(__func__);
1147   return HWC2::Error::None;
1148 }
1149
1150 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) {
1151   supported(__func__);
1152   switch (static_cast<HWC2::BlendMode>(mode)) {
1153     case HWC2::BlendMode::None:
1154       blending_ = DrmHwcBlending::kNone;
1155       break;
1156     case HWC2::BlendMode::Premultiplied:
1157       blending_ = DrmHwcBlending::kPreMult;
1158       break;
1159     case HWC2::BlendMode::Coverage:
1160       blending_ = DrmHwcBlending::kCoverage;
1161       break;
1162     default:
1163       ALOGE("Unknown blending mode b=%d", blending_);
1164       blending_ = DrmHwcBlending::kNone;
1165       break;
1166   }
1167   return HWC2::Error::None;
1168 }
1169
1170 /* Find API details at:
1171  * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=2314
1172  */
1173 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer,
1174                                                 int32_t acquire_fence) {
1175   supported(__func__);
1176
1177   set_buffer(buffer);
1178   acquire_fence_ = UniqueFd(acquire_fence);
1179   return HWC2::Error::None;
1180 }
1181
1182 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerColor(hwc_color_t /*color*/) {
1183   // TODO(nobody): Put to client composition here?
1184   supported(__func__);
1185   return HWC2::Error::None;
1186 }
1187
1188 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerCompositionType(int32_t type) {
1189   sf_type_ = static_cast<HWC2::Composition>(type);
1190   return HWC2::Error::None;
1191 }
1192
1193 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDataspace(int32_t dataspace) {
1194   supported(__func__);
1195   switch (dataspace & HAL_DATASPACE_STANDARD_MASK) {
1196     case HAL_DATASPACE_STANDARD_BT709:
1197       color_space_ = DrmHwcColorSpace::kItuRec709;
1198       break;
1199     case HAL_DATASPACE_STANDARD_BT601_625:
1200     case HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED:
1201     case HAL_DATASPACE_STANDARD_BT601_525:
1202     case HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED:
1203       color_space_ = DrmHwcColorSpace::kItuRec601;
1204       break;
1205     case HAL_DATASPACE_STANDARD_BT2020:
1206     case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
1207       color_space_ = DrmHwcColorSpace::kItuRec2020;
1208       break;
1209     default:
1210       color_space_ = DrmHwcColorSpace::kUndefined;
1211   }
1212
1213   switch (dataspace & HAL_DATASPACE_RANGE_MASK) {
1214     case HAL_DATASPACE_RANGE_FULL:
1215       sample_range_ = DrmHwcSampleRange::kFullRange;
1216       break;
1217     case HAL_DATASPACE_RANGE_LIMITED:
1218       sample_range_ = DrmHwcSampleRange::kLimitedRange;
1219       break;
1220     default:
1221       sample_range_ = DrmHwcSampleRange::kUndefined;
1222   }
1223   return HWC2::Error::None;
1224 }
1225
1226 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) {
1227   supported(__func__);
1228   display_frame_ = frame;
1229   return HWC2::Error::None;
1230 }
1231
1232 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerPlaneAlpha(float alpha) {
1233   supported(__func__);
1234   alpha_ = alpha;
1235   return HWC2::Error::None;
1236 }
1237
1238 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSidebandStream(
1239     const native_handle_t *stream) {
1240   supported(__func__);
1241   // TODO(nobody): We don't support sideband
1242   return unsupported(__func__, stream);
1243 }
1244
1245 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSourceCrop(hwc_frect_t crop) {
1246   supported(__func__);
1247   source_crop_ = crop;
1248   return HWC2::Error::None;
1249 }
1250
1251 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSurfaceDamage(hwc_region_t damage) {
1252   supported(__func__);
1253   // TODO(nobody): We don't use surface damage, marking as unsupported
1254   unsupported(__func__, damage);
1255   return HWC2::Error::None;
1256 }
1257
1258 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerTransform(int32_t transform) {
1259   supported(__func__);
1260
1261   uint32_t l_transform = 0;
1262
1263   // 270* and 180* cannot be combined with flips. More specifically, they
1264   // already contain both horizontal and vertical flips, so those fields are
1265   // redundant in this case. 90* rotation can be combined with either horizontal
1266   // flip or vertical flip, so treat it differently
1267   if (transform == HWC_TRANSFORM_ROT_270) {
1268     l_transform = DrmHwcTransform::kRotate270;
1269   } else if (transform == HWC_TRANSFORM_ROT_180) {
1270     l_transform = DrmHwcTransform::kRotate180;
1271   } else {
1272     if (transform & HWC_TRANSFORM_FLIP_H)
1273       l_transform |= DrmHwcTransform::kFlipH;
1274     if (transform & HWC_TRANSFORM_FLIP_V)
1275       l_transform |= DrmHwcTransform::kFlipV;
1276     if (transform & HWC_TRANSFORM_ROT_90)
1277       l_transform |= DrmHwcTransform::kRotate90;
1278   }
1279
1280   transform_ = static_cast<DrmHwcTransform>(l_transform);
1281   return HWC2::Error::None;
1282 }
1283
1284 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerVisibleRegion(hwc_region_t visible) {
1285   supported(__func__);
1286   // TODO(nobody): We don't use this information, marking as unsupported
1287   unsupported(__func__, visible);
1288   return HWC2::Error::None;
1289 }
1290
1291 HWC2::Error DrmHwcTwo::HwcLayer::SetLayerZOrder(uint32_t order) {
1292   supported(__func__);
1293   z_order_ = order;
1294   return HWC2::Error::None;
1295 }
1296
1297 void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
1298   supported(__func__);
1299   layer->sf_handle = buffer_;
1300   // TODO(rsglobal): Avoid extra fd duplication
1301   layer->acquire_fence = UniqueFd(fcntl(acquire_fence_.Get(), F_DUPFD_CLOEXEC));
1302   layer->display_frame = display_frame_;
1303   layer->alpha = lround(65535.0F * alpha_);
1304   layer->blending = blending_;
1305   layer->source_crop = source_crop_;
1306   layer->transform = transform_;
1307   layer->color_space = color_space_;
1308   layer->sample_range = sample_range_;
1309 }
1310
1311 void DrmHwcTwo::HandleDisplayHotplug(hwc2_display_t displayid, int state) {
1312   const std::lock_guard<std::mutex> lock(callback_lock_);
1313
1314   if (hotplug_callback_.first != nullptr &&
1315       hotplug_callback_.second != nullptr) {
1316     hotplug_callback_.first(hotplug_callback_.second, displayid,
1317                             state == DRM_MODE_CONNECTED
1318                                 ? HWC2_CONNECTION_CONNECTED
1319                                 : HWC2_CONNECTION_DISCONNECTED);
1320   }
1321 }
1322
1323 void DrmHwcTwo::HandleInitialHotplugState(DrmDevice *drmDevice) {
1324   for (const auto &conn : drmDevice->connectors()) {
1325     if (conn->state() != DRM_MODE_CONNECTED)
1326       continue;
1327     HandleDisplayHotplug(conn->display(), conn->state());
1328   }
1329 }
1330
1331 void DrmHwcTwo::HandleHotplugUEvent() {
1332   for (const auto &drm : resource_manager_.getDrmDevices()) {
1333     for (const auto &conn : drm->connectors()) {
1334       drmModeConnection old_state = conn->state();
1335       drmModeConnection cur_state = conn->UpdateModes()
1336                                         ? DRM_MODE_UNKNOWNCONNECTION
1337                                         : conn->state();
1338
1339       if (cur_state == old_state)
1340         continue;
1341
1342       ALOGI("%s event for connector %u on display %d",
1343             cur_state == DRM_MODE_CONNECTED ? "Plug" : "Unplug", conn->id(),
1344             conn->display());
1345
1346       int display_id = conn->display();
1347       if (cur_state == DRM_MODE_CONNECTED) {
1348         auto &display = displays_.at(display_id);
1349         display.ChosePreferredConfig();
1350       } else {
1351         auto &display = displays_.at(display_id);
1352         display.ClearDisplay();
1353       }
1354
1355       HandleDisplayHotplug(display_id, cur_state);
1356     }
1357   }
1358 }
1359
1360 // static
1361 int DrmHwcTwo::HookDevClose(hw_device_t * /*dev*/) {
1362   unsupported(__func__);
1363   return 0;
1364 }
1365
1366 // static
1367 void DrmHwcTwo::HookDevGetCapabilities(hwc2_device_t * /*dev*/,
1368                                        uint32_t *out_count,
1369                                        int32_t * /*out_capabilities*/) {
1370   supported(__func__);
1371   *out_count = 0;
1372 }
1373
1374 // static
1375 hwc2_function_pointer_t DrmHwcTwo::HookDevGetFunction(
1376     struct hwc2_device * /*dev*/, int32_t descriptor) {
1377   supported(__func__);
1378   auto func = static_cast<HWC2::FunctionDescriptor>(descriptor);
1379   switch (func) {
1380     // Device functions
1381     case HWC2::FunctionDescriptor::CreateVirtualDisplay:
1382       return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
1383           DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay),
1384                      &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t,
1385                      int32_t *, hwc2_display_t *>);
1386     case HWC2::FunctionDescriptor::DestroyVirtualDisplay:
1387       return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
1388           DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay),
1389                      &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>);
1390     case HWC2::FunctionDescriptor::Dump:
1391       return ToHook<HWC2_PFN_DUMP>(
1392           DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump,
1393                      uint32_t *, char *>);
1394     case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
1395       return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
1396           DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount),
1397                      &DrmHwcTwo::GetMaxVirtualDisplayCount>);
1398     case HWC2::FunctionDescriptor::RegisterCallback:
1399       return ToHook<HWC2_PFN_REGISTER_CALLBACK>(
1400           DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback),
1401                      &DrmHwcTwo::RegisterCallback, int32_t,
1402                      hwc2_callback_data_t, hwc2_function_pointer_t>);
1403
1404     // Display functions
1405     case HWC2::FunctionDescriptor::AcceptDisplayChanges:
1406       return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
1407           DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges),
1408                       &HwcDisplay::AcceptDisplayChanges>);
1409     case HWC2::FunctionDescriptor::CreateLayer:
1410       return ToHook<HWC2_PFN_CREATE_LAYER>(
1411           DisplayHook<decltype(&HwcDisplay::CreateLayer),
1412                       &HwcDisplay::CreateLayer, hwc2_layer_t *>);
1413     case HWC2::FunctionDescriptor::DestroyLayer:
1414       return ToHook<HWC2_PFN_DESTROY_LAYER>(
1415           DisplayHook<decltype(&HwcDisplay::DestroyLayer),
1416                       &HwcDisplay::DestroyLayer, hwc2_layer_t>);
1417     case HWC2::FunctionDescriptor::GetActiveConfig:
1418       return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
1419           DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
1420                       &HwcDisplay::GetActiveConfig, hwc2_config_t *>);
1421     case HWC2::FunctionDescriptor::GetChangedCompositionTypes:
1422       return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
1423           DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes),
1424                       &HwcDisplay::GetChangedCompositionTypes, uint32_t *,
1425                       hwc2_layer_t *, int32_t *>);
1426     case HWC2::FunctionDescriptor::GetClientTargetSupport:
1427       return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
1428           DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport),
1429                       &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t,
1430                       int32_t, int32_t>);
1431     case HWC2::FunctionDescriptor::GetColorModes:
1432       return ToHook<HWC2_PFN_GET_COLOR_MODES>(
1433           DisplayHook<decltype(&HwcDisplay::GetColorModes),
1434                       &HwcDisplay::GetColorModes, uint32_t *, int32_t *>);
1435     case HWC2::FunctionDescriptor::GetDisplayAttribute:
1436       return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
1437           DisplayHook<decltype(&HwcDisplay::GetDisplayAttribute),
1438                       &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t,
1439                       int32_t *>);
1440     case HWC2::FunctionDescriptor::GetDisplayConfigs:
1441       return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(
1442           DisplayHook<decltype(&HwcDisplay::GetDisplayConfigs),
1443                       &HwcDisplay::GetDisplayConfigs, uint32_t *,
1444                       hwc2_config_t *>);
1445     case HWC2::FunctionDescriptor::GetDisplayName:
1446       return ToHook<HWC2_PFN_GET_DISPLAY_NAME>(
1447           DisplayHook<decltype(&HwcDisplay::GetDisplayName),
1448                       &HwcDisplay::GetDisplayName, uint32_t *, char *>);
1449     case HWC2::FunctionDescriptor::GetDisplayRequests:
1450       return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>(
1451           DisplayHook<decltype(&HwcDisplay::GetDisplayRequests),
1452                       &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *,
1453                       hwc2_layer_t *, int32_t *>);
1454     case HWC2::FunctionDescriptor::GetDisplayType:
1455       return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>(
1456           DisplayHook<decltype(&HwcDisplay::GetDisplayType),
1457                       &HwcDisplay::GetDisplayType, int32_t *>);
1458     case HWC2::FunctionDescriptor::GetDozeSupport:
1459       return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>(
1460           DisplayHook<decltype(&HwcDisplay::GetDozeSupport),
1461                       &HwcDisplay::GetDozeSupport, int32_t *>);
1462     case HWC2::FunctionDescriptor::GetHdrCapabilities:
1463       return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>(
1464           DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities),
1465                       &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *,
1466                       float *, float *, float *>);
1467     case HWC2::FunctionDescriptor::GetReleaseFences:
1468       return ToHook<HWC2_PFN_GET_RELEASE_FENCES>(
1469           DisplayHook<decltype(&HwcDisplay::GetReleaseFences),
1470                       &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *,
1471                       int32_t *>);
1472     case HWC2::FunctionDescriptor::PresentDisplay:
1473       return ToHook<HWC2_PFN_PRESENT_DISPLAY>(
1474           DisplayHook<decltype(&HwcDisplay::PresentDisplay),
1475                       &HwcDisplay::PresentDisplay, int32_t *>);
1476     case HWC2::FunctionDescriptor::SetActiveConfig:
1477       return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>(
1478           DisplayHook<decltype(&HwcDisplay::SetActiveConfig),
1479                       &HwcDisplay::SetActiveConfig, hwc2_config_t>);
1480     case HWC2::FunctionDescriptor::SetClientTarget:
1481       return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(
1482           DisplayHook<decltype(&HwcDisplay::SetClientTarget),
1483                       &HwcDisplay::SetClientTarget, buffer_handle_t, int32_t,
1484                       int32_t, hwc_region_t>);
1485     case HWC2::FunctionDescriptor::SetColorMode:
1486       return ToHook<HWC2_PFN_SET_COLOR_MODE>(
1487           DisplayHook<decltype(&HwcDisplay::SetColorMode),
1488                       &HwcDisplay::SetColorMode, int32_t>);
1489     case HWC2::FunctionDescriptor::SetColorTransform:
1490       return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
1491           DisplayHook<decltype(&HwcDisplay::SetColorTransform),
1492                       &HwcDisplay::SetColorTransform, const float *, int32_t>);
1493     case HWC2::FunctionDescriptor::SetOutputBuffer:
1494       return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>(
1495           DisplayHook<decltype(&HwcDisplay::SetOutputBuffer),
1496                       &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>);
1497     case HWC2::FunctionDescriptor::SetPowerMode:
1498       return ToHook<HWC2_PFN_SET_POWER_MODE>(
1499           DisplayHook<decltype(&HwcDisplay::SetPowerMode),
1500                       &HwcDisplay::SetPowerMode, int32_t>);
1501     case HWC2::FunctionDescriptor::SetVsyncEnabled:
1502       return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>(
1503           DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled),
1504                       &HwcDisplay::SetVsyncEnabled, int32_t>);
1505     case HWC2::FunctionDescriptor::ValidateDisplay:
1506       return ToHook<HWC2_PFN_VALIDATE_DISPLAY>(
1507           DisplayHook<decltype(&HwcDisplay::ValidateDisplay),
1508                       &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>);
1509 #if PLATFORM_SDK_VERSION > 27
1510     case HWC2::FunctionDescriptor::GetRenderIntents:
1511       return ToHook<HWC2_PFN_GET_RENDER_INTENTS>(
1512           DisplayHook<decltype(&HwcDisplay::GetRenderIntents),
1513                       &HwcDisplay::GetRenderIntents, int32_t, uint32_t *,
1514                       int32_t *>);
1515     case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
1516       return ToHook<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
1517           DisplayHook<decltype(&HwcDisplay::SetColorModeWithIntent),
1518                       &HwcDisplay::SetColorModeWithIntent, int32_t, int32_t>);
1519 #endif
1520 #if PLATFORM_SDK_VERSION > 28
1521     case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
1522       return ToHook<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>(
1523           DisplayHook<decltype(&HwcDisplay::GetDisplayIdentificationData),
1524                       &HwcDisplay::GetDisplayIdentificationData, uint8_t *,
1525                       uint32_t *, uint8_t *>);
1526     case HWC2::FunctionDescriptor::GetDisplayCapabilities:
1527       return ToHook<HWC2_PFN_GET_DISPLAY_CAPABILITIES>(
1528           DisplayHook<decltype(&HwcDisplay::GetDisplayCapabilities),
1529                       &HwcDisplay::GetDisplayCapabilities, uint32_t *,
1530                       uint32_t *>);
1531     case HWC2::FunctionDescriptor::GetDisplayBrightnessSupport:
1532       return ToHook<HWC2_PFN_GET_DISPLAY_BRIGHTNESS_SUPPORT>(
1533           DisplayHook<decltype(&HwcDisplay::GetDisplayBrightnessSupport),
1534                       &HwcDisplay::GetDisplayBrightnessSupport, bool *>);
1535     case HWC2::FunctionDescriptor::SetDisplayBrightness:
1536       return ToHook<HWC2_PFN_SET_DISPLAY_BRIGHTNESS>(
1537           DisplayHook<decltype(&HwcDisplay::SetDisplayBrightness),
1538                       &HwcDisplay::SetDisplayBrightness, float>);
1539 #endif /* PLATFORM_SDK_VERSION > 28 */
1540 #if PLATFORM_SDK_VERSION > 29
1541     case HWC2::FunctionDescriptor::GetDisplayConnectionType:
1542       return ToHook<HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE>(
1543           DisplayHook<decltype(&HwcDisplay::GetDisplayConnectionType),
1544                       &HwcDisplay::GetDisplayConnectionType, uint32_t *>);
1545     case HWC2::FunctionDescriptor::GetDisplayVsyncPeriod:
1546       return ToHook<HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD>(
1547           DisplayHook<decltype(&HwcDisplay::GetDisplayVsyncPeriod),
1548                       &HwcDisplay::GetDisplayVsyncPeriod,
1549                       hwc2_vsync_period_t *>);
1550     case HWC2::FunctionDescriptor::SetActiveConfigWithConstraints:
1551       return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS>(
1552           DisplayHook<decltype(&HwcDisplay::SetActiveConfigWithConstraints),
1553                       &HwcDisplay::SetActiveConfigWithConstraints,
1554                       hwc2_config_t, hwc_vsync_period_change_constraints_t *,
1555                       hwc_vsync_period_change_timeline_t *>);
1556     case HWC2::FunctionDescriptor::SetAutoLowLatencyMode:
1557       return ToHook<HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE>(
1558           DisplayHook<decltype(&HwcDisplay::SetAutoLowLatencyMode),
1559                       &HwcDisplay::SetAutoLowLatencyMode, bool>);
1560     case HWC2::FunctionDescriptor::GetSupportedContentTypes:
1561       return ToHook<HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES>(
1562           DisplayHook<decltype(&HwcDisplay::GetSupportedContentTypes),
1563                       &HwcDisplay::GetSupportedContentTypes, uint32_t *,
1564                       uint32_t *>);
1565     case HWC2::FunctionDescriptor::SetContentType:
1566       return ToHook<HWC2_PFN_SET_CONTENT_TYPE>(
1567           DisplayHook<decltype(&HwcDisplay::SetContentType),
1568                       &HwcDisplay::SetContentType, int32_t>);
1569 #endif
1570     // Layer functions
1571     case HWC2::FunctionDescriptor::SetCursorPosition:
1572       return ToHook<HWC2_PFN_SET_CURSOR_POSITION>(
1573           LayerHook<decltype(&HwcLayer::SetCursorPosition),
1574                     &HwcLayer::SetCursorPosition, int32_t, int32_t>);
1575     case HWC2::FunctionDescriptor::SetLayerBlendMode:
1576       return ToHook<HWC2_PFN_SET_LAYER_BLEND_MODE>(
1577           LayerHook<decltype(&HwcLayer::SetLayerBlendMode),
1578                     &HwcLayer::SetLayerBlendMode, int32_t>);
1579     case HWC2::FunctionDescriptor::SetLayerBuffer:
1580       return ToHook<HWC2_PFN_SET_LAYER_BUFFER>(
1581           LayerHook<decltype(&HwcLayer::SetLayerBuffer),
1582                     &HwcLayer::SetLayerBuffer, buffer_handle_t, int32_t>);
1583     case HWC2::FunctionDescriptor::SetLayerColor:
1584       return ToHook<HWC2_PFN_SET_LAYER_COLOR>(
1585           LayerHook<decltype(&HwcLayer::SetLayerColor),
1586                     &HwcLayer::SetLayerColor, hwc_color_t>);
1587     case HWC2::FunctionDescriptor::SetLayerCompositionType:
1588       return ToHook<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
1589           LayerHook<decltype(&HwcLayer::SetLayerCompositionType),
1590                     &HwcLayer::SetLayerCompositionType, int32_t>);
1591     case HWC2::FunctionDescriptor::SetLayerDataspace:
1592       return ToHook<HWC2_PFN_SET_LAYER_DATASPACE>(
1593           LayerHook<decltype(&HwcLayer::SetLayerDataspace),
1594                     &HwcLayer::SetLayerDataspace, int32_t>);
1595     case HWC2::FunctionDescriptor::SetLayerDisplayFrame:
1596       return ToHook<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
1597           LayerHook<decltype(&HwcLayer::SetLayerDisplayFrame),
1598                     &HwcLayer::SetLayerDisplayFrame, hwc_rect_t>);
1599     case HWC2::FunctionDescriptor::SetLayerPlaneAlpha:
1600       return ToHook<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
1601           LayerHook<decltype(&HwcLayer::SetLayerPlaneAlpha),
1602                     &HwcLayer::SetLayerPlaneAlpha, float>);
1603     case HWC2::FunctionDescriptor::SetLayerSidebandStream:
1604       return ToHook<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
1605           LayerHook<decltype(&HwcLayer::SetLayerSidebandStream),
1606                     &HwcLayer::SetLayerSidebandStream,
1607                     const native_handle_t *>);
1608     case HWC2::FunctionDescriptor::SetLayerSourceCrop:
1609       return ToHook<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
1610           LayerHook<decltype(&HwcLayer::SetLayerSourceCrop),
1611                     &HwcLayer::SetLayerSourceCrop, hwc_frect_t>);
1612     case HWC2::FunctionDescriptor::SetLayerSurfaceDamage:
1613       return ToHook<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
1614           LayerHook<decltype(&HwcLayer::SetLayerSurfaceDamage),
1615                     &HwcLayer::SetLayerSurfaceDamage, hwc_region_t>);
1616     case HWC2::FunctionDescriptor::SetLayerTransform:
1617       return ToHook<HWC2_PFN_SET_LAYER_TRANSFORM>(
1618           LayerHook<decltype(&HwcLayer::SetLayerTransform),
1619                     &HwcLayer::SetLayerTransform, int32_t>);
1620     case HWC2::FunctionDescriptor::SetLayerVisibleRegion:
1621       return ToHook<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
1622           LayerHook<decltype(&HwcLayer::SetLayerVisibleRegion),
1623                     &HwcLayer::SetLayerVisibleRegion, hwc_region_t>);
1624     case HWC2::FunctionDescriptor::SetLayerZOrder:
1625       return ToHook<HWC2_PFN_SET_LAYER_Z_ORDER>(
1626           LayerHook<decltype(&HwcLayer::SetLayerZOrder),
1627                     &HwcLayer::SetLayerZOrder, uint32_t>);
1628     case HWC2::FunctionDescriptor::Invalid:
1629     default:
1630       return nullptr;
1631   }
1632 }
1633
1634 // static
1635 int DrmHwcTwo::HookDevOpen(const struct hw_module_t *module, const char *name,
1636                            struct hw_device_t **dev) {
1637   supported(__func__);
1638   if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
1639     ALOGE("Invalid module name- %s", name);
1640     return -EINVAL;
1641   }
1642
1643   std::unique_ptr<DrmHwcTwo> ctx(new DrmHwcTwo());
1644   if (!ctx) {
1645     ALOGE("Failed to allocate DrmHwcTwo");
1646     return -ENOMEM;
1647   }
1648
1649   HWC2::Error err = ctx->Init();
1650   if (err != HWC2::Error::None) {
1651     ALOGE("Failed to initialize DrmHwcTwo err=%d\n", err);
1652     return -EINVAL;
1653   }
1654
1655   ctx->common.module = (hw_module_t *)module;
1656   *dev = &ctx->common;
1657   ctx.release();  // NOLINT(bugprone-unused-return-value)
1658   return 0;
1659 }
1660 }  // namespace android
1661
1662 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
1663 static struct hw_module_methods_t hwc2_module_methods = {
1664     .open = android::DrmHwcTwo::HookDevOpen,
1665 };
1666
1667 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
1668 hw_module_t HAL_MODULE_INFO_SYM = {
1669     .tag = HARDWARE_MODULE_TAG,
1670     .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0),
1671     .id = HWC_HARDWARE_MODULE_ID,
1672     .name = "DrmHwcTwo module",
1673     .author = "The Android Open Source Project",
1674     .methods = &hwc2_module_methods,
1675     .dso = nullptr,
1676     .reserved = {0},
1677 };