drm_hwcomposer: refactor platform directory

Motivation:

Platform term meaning used in drm_hwcomposer does not correspond to the
content of the platform directory. Platform directory consists of:
1. Buffer information getters for different gralloc (currently called platform).
2. Composition planner logic (which has flaws and should be reworked into
   layer->plane mapping during validation stage logic).
3. DrmGenericImpoter with reference counting logic.

Android-11 IMapper@4 metadata API offers a generic way to access buffer
information which makes other gralloc buffer information getters obsolete.
Legacy getters should be maintained for some time until all known users
will migrate to Mapper@4 API.

Implementation:

1. Split 'PlatformImporter' logic to 'Importer' only and 'Buffer Getter' logic.
   a. Remove buffer_handle_t parameter from ImportBuffer(). Instead user should
      get BufferInfo using ConvertBoInfo to struct hwc_drm_bo_t, then use it for
      ImportBuffer().
   b. Move DrmGenericImporter.{cpp/h} into the drm directory.

2. Isolate planner code in single file and move it to compositor directory as
   compositor/Planner.{cpp/h}

3. Rename platform definition
   a. Rename platform directory to bufferinfo.
   b. Rename/move bufferinfo/platorm*.{cpp,h} getters to
      bufferinfo/legacy/BufferInfo*.{cpp,h}. Align class names/includes.

4. Split legacy/metadata getters logic.
   a. Apply existing bufferinfogetter base class only for legacy getters.
   b. Combine legacy/generic gettera under new base class.
   c. Create a placeholder for generic(metadata) getter.

Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com>
diff --git a/drm/DrmDevice.cpp b/drm/DrmDevice.cpp
index 28ecfda..bf1a5e2 100644
--- a/drm/DrmDevice.cpp
+++ b/drm/DrmDevice.cpp
@@ -29,6 +29,7 @@
 #include <algorithm>
 #include <array>
 #include <cinttypes>
+#include <sstream>
 #include <string>
 
 static void trim_left(std::string &str) {
diff --git a/drm/DrmDevice.h b/drm/DrmDevice.h
index d7ea359..be68aa6 100644
--- a/drm/DrmDevice.h
+++ b/drm/DrmDevice.h
@@ -19,6 +19,7 @@
 
 #include <stdint.h>
 
+#include <map>
 #include <tuple>
 
 #include "DrmConnector.h"
@@ -26,7 +27,6 @@
 #include "DrmEncoder.h"
 #include "DrmEventListener.h"
 #include "DrmPlane.h"
-#include "platform/platform.h"
 
 namespace android {
 
diff --git a/drm/DrmGenericImporter.cpp b/drm/DrmGenericImporter.cpp
new file mode 100644
index 0000000..b4dc063
--- /dev/null
+++ b/drm/DrmGenericImporter.cpp
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "hwc-platform-drm-generic"
+
+#include "DrmGenericImporter.h"
+
+#include <cutils/properties.h>
+#include <gralloc_handle.h>
+#include <hardware/gralloc.h>
+#include <log/log.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+namespace android {
+
+DrmGenericImporter::DrmGenericImporter(DrmDevice *drm) : drm_(drm) {
+}
+
+DrmGenericImporter::~DrmGenericImporter() {
+}
+
+int DrmGenericImporter::ImportBuffer(hwc_drm_bo_t *bo) {
+  int ret = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[0],
+                               &bo->gem_handles[0]);
+  if (ret) {
+    ALOGE("failed to import prime fd %d ret=%d", bo->prime_fds[0], ret);
+    return ret;
+  }
+
+  for (int i = 1; i < HWC_DRM_BO_MAX_PLANES; i++) {
+    int fd = bo->prime_fds[i];
+    if (fd != 0) {
+      if (fd != bo->prime_fds[0]) {
+        ALOGE("Multiplanar FBs are not supported by this version of composer");
+        return -ENOTSUP;
+      }
+      bo->gem_handles[i] = bo->gem_handles[0];
+    }
+  }
+
+  if (!bo->with_modifiers)
+    ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
+                        bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id,
+                        0);
+  else
+    ret = drmModeAddFB2WithModifiers(drm_->fd(), bo->width, bo->height,
+                                     bo->format, bo->gem_handles, bo->pitches,
+                                     bo->offsets, bo->modifiers, &bo->fb_id,
+                                     bo->modifiers[0] ? DRM_MODE_FB_MODIFIERS
+                                                      : 0);
+
+  if (ret) {
+    ALOGE("could not create drm fb %d", ret);
+    return ret;
+  }
+
+  ImportHandle(bo->gem_handles[0]);
+
+  return ret;
+}
+
+int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
+  if (bo->fb_id)
+    if (drmModeRmFB(drm_->fd(), bo->fb_id))
+      ALOGE("Failed to rm fb");
+
+  for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
+    if (!bo->gem_handles[i])
+      continue;
+
+    if (ReleaseHandle(bo->gem_handles[i])) {
+      ALOGE("Failed to release gem handle %d", bo->gem_handles[i]);
+    } else {
+      for (int j = i + 1; j < HWC_DRM_BO_MAX_PLANES; j++)
+        if (bo->gem_handles[j] == bo->gem_handles[i])
+          bo->gem_handles[j] = 0;
+      bo->gem_handles[i] = 0;
+    }
+  }
+  return 0;
+}
+
+int DrmGenericImporter::ImportHandle(uint32_t gem_handle) {
+  gem_refcount_[gem_handle]++;
+
+  return 0;
+}
+
+int DrmGenericImporter::ReleaseHandle(uint32_t gem_handle) {
+  if (--gem_refcount_[gem_handle])
+    return 0;
+
+  gem_refcount_.erase(gem_handle);
+
+  return CloseHandle(gem_handle);
+}
+
+int DrmGenericImporter::CloseHandle(uint32_t gem_handle) {
+  struct drm_gem_close gem_close;
+
+  memset(&gem_close, 0, sizeof(gem_close));
+
+  gem_close.handle = gem_handle;
+  int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
+  if (ret)
+    ALOGE("Failed to close gem handle %d %d", gem_handle, ret);
+
+  return ret;
+}
+}  // namespace android
diff --git a/drm/DrmGenericImporter.h b/drm/DrmGenericImporter.h
new file mode 100644
index 0000000..efda6be
--- /dev/null
+++ b/drm/DrmGenericImporter.h
@@ -0,0 +1,72 @@
+/*
+ * 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_PLATFORM_DRM_GENERIC_H_
+#define ANDROID_PLATFORM_DRM_GENERIC_H_
+
+#include <drm/drm_fourcc.h>
+#include <hardware/gralloc.h>
+
+#include <map>
+
+#include "drm/DrmDevice.h"
+#include "drmhwcgralloc.h"
+
+#ifndef DRM_FORMAT_INVALID
+#define DRM_FORMAT_INVALID 0
+#endif
+
+namespace android {
+
+class Importer {
+ public:
+  virtual ~Importer() {
+  }
+
+  // Imports the buffer referred to by handle into bo.
+  //
+  // Note: This can be called from a different thread than ReleaseBuffer. The
+  //       implementation is responsible for ensuring thread safety.
+  virtual int ImportBuffer(hwc_drm_bo_t *bo) = 0;
+
+  // Releases the buffer object (ie: does the inverse of ImportBuffer)
+  //
+  // Note: This can be called from a different thread than ImportBuffer. The
+  //       implementation is responsible for ensuring thread safety.
+  virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0;
+};
+
+class DrmGenericImporter : public Importer {
+ public:
+  DrmGenericImporter(DrmDevice *drm);
+  ~DrmGenericImporter() override;
+
+  int ImportBuffer(hwc_drm_bo_t *bo) override;
+  int ReleaseBuffer(hwc_drm_bo_t *bo) override;
+  int ImportHandle(uint32_t gem_handle);
+  int ReleaseHandle(uint32_t gem_handle);
+
+ protected:
+  DrmDevice *drm_;
+
+ private:
+  int CloseHandle(uint32_t gem_handle);
+  std::map<uint32_t, int> gem_refcount_;
+};
+
+}  // namespace android
+
+#endif
diff --git a/drm/ResourceManager.cpp b/drm/ResourceManager.cpp
index 67ef7f8..fc24aea 100644
--- a/drm/ResourceManager.cpp
+++ b/drm/ResourceManager.cpp
@@ -24,6 +24,8 @@
 
 #include <sstream>
 
+#include "bufferinfo/BufferInfoGetter.h"
+
 namespace android {
 
 ResourceManager::ResourceManager() : num_displays_(0), gralloc_(NULL) {
@@ -62,6 +64,11 @@
   property_get("vendor.hwc.drm.scale_with_gpu", scale_with_gpu, "0");
   scale_with_gpu_ = bool(strncmp(scale_with_gpu, "0", 1));
 
+  if (!BufferInfoGetter::GetInstance()) {
+    ALOGE("Failed to initialize BufferInfoGetter");
+    return -EINVAL;
+  }
+
   return hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
                        (const hw_module_t **)&gralloc_);
 }
@@ -73,7 +80,7 @@
   if (ret)
     return ret;
   std::shared_ptr<Importer> importer;
-  importer.reset(Importer::CreateInstance(drm.get()));
+  importer.reset(new DrmGenericImporter(drm.get()));
   if (!importer) {
     ALOGE("Failed to create importer instance");
     return -ENODEV;
diff --git a/drm/ResourceManager.h b/drm/ResourceManager.h
index 94ba43e..7102cea 100644
--- a/drm/ResourceManager.h
+++ b/drm/ResourceManager.h
@@ -20,7 +20,7 @@
 #include <string.h>
 
 #include "DrmDevice.h"
-#include "platform/platform.h"
+#include "DrmGenericImporter.h"
 
 namespace android {