OSDN Git Service

drm_hwcomposer: Improve Mapper@4 metadata API fds index guessing logic
authorRoman Stratiienko <roman.o.stratiienko@globallogic.com>
Fri, 22 Oct 2021 09:34:36 +0000 (12:34 +0300)
committerRoman Stratiienko <roman.o.stratiienko@globallogic.com>
Fri, 22 Oct 2021 20:05:06 +0000 (23:05 +0300)
Unfortunately Mapper@4.0 metadata API doesn't allow to query fd index or
getting fd another way for every layout plane, therefore users have to
provide their custom additional metadata API.

We are doing all our best to minimize custom per-platform logic in
drm_hwcomposer. So it was decided to implement primitive guessing logic,
allowing users to extend it with out-of-tree code if necessary.

As was reported by John Stultz in [1] our primitive logic has some flaws.

New guessing logic are using inputs from layout data (offsets, sizes),
and should be more precise.

[1]: https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer/-/merge_requests/159
Signed-off-by: Roman Stratiienko <roman.o.stratiienko@globallogic.com>
bufferinfo/BufferInfoMapperMetadata.cpp
include/drmhwcgralloc.h

index 23a9072..a8e95e7 100644 (file)
@@ -47,30 +47,42 @@ BufferInfoGetter *BufferInfoMapperMetadata::CreateInstance() {
  */
 int __attribute__((weak))
 BufferInfoMapperMetadata::GetFds(buffer_handle_t handle, hwc_drm_bo_t *bo) {
-  int num_fds = handle->numFds;
+  int fd_index = 0;
 
-  if (num_fds >= 1 && num_fds <= 2) {
-    if (IsDrmFormatRgb(bo->format)) {
-      bo->prime_fds[0] = handle->data[0];
-    } else {
-      bo->prime_fds[0] = bo->prime_fds[1] = bo->prime_fds[2] = handle->data[0];
-    }
-    if (bo->prime_fds[0] <= 0) {
-      ALOGE("Encountered invalid fd %d", bo->prime_fds[0]);
-      return android::BAD_VALUE;
+  if (handle->numFds <= 0) {
+    ALOGE("Handle has no fds");
+    return android::BAD_VALUE;
+  }
+
+  for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
+    /* If no size, we're out of usable planes */
+    if (bo->sizes[i] <= 0) {
+      if (i == 0) {
+        ALOGE("Bad handle metadata");
+        return android::BAD_VALUE;
+      }
+      break;
     }
 
-  } else if (num_fds >= 3) {
-    bo->prime_fds[0] = handle->data[0];
-    bo->prime_fds[1] = handle->data[1];
-    bo->prime_fds[2] = handle->data[2];
-    for (int i = 0; i < 3; i++) {
-      if (bo->prime_fds[i] <= 0) {
-        ALOGE("Encountered invalid fd %d", bo->prime_fds[i]);
+    /*
+     * If the offset is zero, its multi-buffer
+     * so move to the next fd
+     */
+    if (i != 0 && bo->offsets[i] == 0) {
+      fd_index++;
+      if (fd_index >= handle->numFds) {
+        ALOGE("Handle has no more fds");
         return android::BAD_VALUE;
       }
     }
+
+    bo->prime_fds[i] = handle->data[fd_index];
+    if (bo->prime_fds[i] <= 0) {
+      ALOGE("Invalid prime fd");
+      return android::BAD_VALUE;
+    }
   }
+
   return 0;
 }
 
@@ -135,6 +147,7 @@ int BufferInfoMapperMetadata::ConvertBoInfo(buffer_handle_t handle,
     bo->modifiers[i] = bo->modifiers[0];
     bo->pitches[i] = layouts[i].strideInBytes;
     bo->offsets[i] = layouts[i].offsetInBytes;
+    bo->sizes[i] = layouts[i].totalSizeInBytes;
   }
 
   return GetFds(handle, bo);
index 57685d1..09c7499 100644 (file)
@@ -28,6 +28,8 @@ typedef struct hwc_drm_bo {
   uint32_t usage;
   uint32_t pitches[HWC_DRM_BO_MAX_PLANES];
   uint32_t offsets[HWC_DRM_BO_MAX_PLANES];
+  /* sizes[] is used only by mapper@4 metadata getter for internal purposes */
+  uint32_t sizes[HWC_DRM_BO_MAX_PLANES];
   int prime_fds[HWC_DRM_BO_MAX_PLANES];
   uint64_t modifiers[HWC_DRM_BO_MAX_PLANES];
   int acquire_fence_fd;