drm_hwcomposer: Add backend-dependent validation for HwcDisplay class

Different DRM/KMS backends have a variable set of limitations, which is
not always exposed via DRM ioctls.

This implementation of backend-dependent validation provides a register
of platform-specific inherited backend class to the map by BackendManager
class. ValidateDisplay function is moved to generic backend
implementantion and separated into 2 additional methods.

The map key is a string that contains the corresponding DRM driver name.
During DrmHwcTwo class initialization the vendor.hwc.backend_override
system property and driver name will be checked and a backend will be set
for the appropriate display. If the map does not have any backend for the
named driver, the generic backend will be used.

Signed-off-by: Matvii Zorin <matvii.zorin@globallogic.com>
diff --git a/include/backend.h b/include/backend.h
new file mode 100644
index 0000000..cd9d8cd
--- /dev/null
+++ b/include/backend.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BACKEND_H
+#define ANDROID_BACKEND_H
+
+#include "drmhwctwo.h"
+
+namespace android {
+
+class Backend {
+ public:
+  virtual ~Backend() = default;
+  virtual HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
+                                      uint32_t *num_types,
+                                      uint32_t *num_requests);
+  virtual std::tuple<int, int> GetClientLayers(
+      DrmHwcTwo::HwcDisplay *display,
+      const std::map<uint32_t, DrmHwcTwo::HwcLayer *> &z_map);
+  virtual bool IsClientLayer(DrmHwcTwo::HwcDisplay *display,
+                             DrmHwcTwo::HwcLayer *layer);
+};
+}  // namespace android
+
+#endif
diff --git a/include/backendmanager.h b/include/backendmanager.h
new file mode 100644
index 0000000..d141652
--- /dev/null
+++ b/include/backendmanager.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BACKEND_MANAGER_H
+#define ANDROID_BACKEND_MANAGER_H
+
+#include "backend.h"
+#include "drmhwctwo.h"
+
+#include <functional>
+#include <map>
+#include <string>
+#include <vector>
+
+#define REGISTER_BACKEND(name_str_, backend_)                               \
+  static int                                                                \
+      backend = BackendManager::GetInstance()                               \
+                    .RegisterBackend(name_str_,                             \
+                                     []() -> std::unique_ptr<Backend> {     \
+                                       return std::make_unique<backend_>(); \
+                                     });
+
+namespace android {
+
+class BackendManager {
+ public:
+  using backend_constructor_t = std::function<std::unique_ptr<Backend>()>;
+  static BackendManager &GetInstance();
+  int RegisterBackend(const std::string &name,
+                      backend_constructor_t backend_constructor);
+  int SetBackendForDisplay(DrmHwcTwo::HwcDisplay *display);
+  std::unique_ptr<Backend> GetBackendByName(std::string &name);
+  HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
+                              uint32_t *num_types, uint32_t *num_requests);
+
+ private:
+  BackendManager() = default;
+
+  static const std::vector<std::string> client_devices_;
+
+  std::map<std::string, backend_constructor_t> available_backends_;
+};
+}  // namespace android
+
+#endif
diff --git a/include/drmdevice.h b/include/drmdevice.h
index 91dd38b..1f08f20 100644
--- a/include/drmdevice.h
+++ b/include/drmdevice.h
@@ -70,6 +70,8 @@
   int GetConnectorProperty(const DrmConnector &connector, const char *prop_name,
                            DrmProperty *property);
 
+  const std::string GetName() const;
+
   const std::vector<std::unique_ptr<DrmCrtc>> &crtcs() const;
   uint32_t next_mode_id();
 
diff --git a/include/drmhwctwo.h b/include/drmhwctwo.h
index df75c41..8b1be4b 100644
--- a/include/drmhwctwo.h
+++ b/include/drmhwctwo.h
@@ -31,6 +31,8 @@
 
 namespace android {
 
+class Backend;
+
 class DrmHwcTwo : public hwc2_device_t {
  public:
   static int HookDevOpen(const struct hw_module_t *module, const char *name,
@@ -256,6 +258,13 @@
       uint32_t frames_flattened_ = 0;
     };
 
+    const Backend *backend() const {
+      return backend_.get();
+    }
+    void set_backend(std::unique_ptr<Backend> backend) {
+      backend_ = std::move(backend);
+    }
+
     const std::vector<DrmPlane *> &primary_planes() const {
       return primary_planes_;
     }
@@ -310,6 +319,8 @@
     std::vector<DrmPlane *> primary_planes_;
     std::vector<DrmPlane *> overlay_planes_;
 
+    std::unique_ptr<Backend> backend_;
+
     VSyncWorker vsync_worker_;
     DrmConnector *connector_ = NULL;
     DrmCrtc *crtc_ = NULL;