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/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