OSDN Git Service

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