OSDN Git Service

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