OSDN Git Service

resolve merge conflicts of 42ca6159e52c5a2217825da02a26cf504998301b to stage-aosp...
[android-x86/external-minigbm.git] / cros_gralloc / cros_gralloc_driver.cc
index 62b43d4..ab7c654 100644 (file)
@@ -5,12 +5,16 @@
  */
 
 #include "cros_gralloc_driver.h"
-#include "../util.h"
 
 #include <cstdlib>
 #include <fcntl.h>
+#include <sys/mman.h>
 #include <xf86drm.h>
 
+#include "../drv_priv.h"
+#include "../helpers.h"
+#include "../util.h"
+
 cros_gralloc_driver::cros_gralloc_driver() : drv_(nullptr)
 {
 }
@@ -51,7 +55,7 @@ int32_t cros_gralloc_driver::init()
                        if (asprintf(&node, str, DRM_DIR_NAME, j) < 0)
                                continue;
 
-                       fd = open(node, O_RDWR, 0);
+                       fd = open(node, O_RDWR | O_CLOEXEC);
                        free(node);
 
                        if (fd < 0)
@@ -90,15 +94,43 @@ bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descript
        return (combo != nullptr);
 }
 
+int32_t create_reserved_region(const std::string &buffer_name, uint64_t reserved_region_size)
+{
+       std::string reserved_region_name = buffer_name + " reserved region";
+
+#ifdef __NR_memfd_create
+       int32_t reserved_region_fd = memfd_create(reserved_region_name.c_str(), FD_CLOEXEC);
+       if (reserved_region_fd == -1) {
+               drv_log("Failed to create reserved region fd: %s.\n", strerror(errno));
+               return -errno;
+       }
+
+       if (ftruncate(reserved_region_fd, reserved_region_size)) {
+               drv_log("Failed to set reserved region size: %s.\n", strerror(errno));
+               return -errno;
+       }
+
+       return reserved_region_fd;
+#else
+       drv_log("Failed to create reserved region '%s': memfd_create not available.",
+               reserved_region_name.c_str());
+       return -1;
+#endif
+}
+
 int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descriptor *descriptor,
                                      buffer_handle_t *out_handle)
 {
        uint32_t id;
-       uint64_t mod;
        size_t num_planes;
+       size_t num_fds;
+       size_t num_ints;
+       size_t num_bytes;
        uint32_t resolved_format;
        uint32_t bytes_per_pixel;
        uint64_t use_flags;
+       int32_t reserved_region_fd;
+       char *name;
 
        struct bo *bo;
        struct cros_gralloc_handle *hnd;
@@ -140,41 +172,73 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
                return -EINVAL;
        }
 
-       hnd = new cros_gralloc_handle();
        num_planes = drv_bo_get_num_planes(bo);
+       num_fds = num_planes;
+
+       if (descriptor->reserved_region_size > 0) {
+               reserved_region_fd =
+                   create_reserved_region(descriptor->name, descriptor->reserved_region_size);
+               if (reserved_region_fd < 0) {
+                       drv_bo_destroy(bo);
+                       return reserved_region_fd;
+               }
+               num_fds += 1;
+       } else {
+               reserved_region_fd = -1;
+       }
 
+       num_bytes = sizeof(struct cros_gralloc_handle);
+       num_bytes += (descriptor->name.size() + 1);
+       /*
+        * Ensure that the total number of bytes is a multiple of sizeof(int) as
+        * native_handle_clone() copies data based on hnd->base.numInts.
+        */
+       num_bytes = ALIGN(num_bytes, sizeof(int));
+       num_ints = num_bytes - sizeof(native_handle_t) - num_fds;
+       /*
+        * Malloc is used as handles are ultimately destroyed via free in
+        * native_handle_delete().
+        */
+       hnd = static_cast<struct cros_gralloc_handle *>(malloc(num_bytes));
        hnd->base.version = sizeof(hnd->base);
-       hnd->base.numFds = num_planes;
-       hnd->base.numInts = handle_data_size - num_planes;
-
+       hnd->base.numFds = num_fds;
+       hnd->base.numInts = num_ints;
+       hnd->num_planes = num_planes;
        for (size_t plane = 0; plane < num_planes; plane++) {
                hnd->fds[plane] = drv_bo_get_plane_fd(bo, plane);
                hnd->strides[plane] = drv_bo_get_plane_stride(bo, plane);
                hnd->offsets[plane] = drv_bo_get_plane_offset(bo, plane);
-
-               mod = drv_bo_get_plane_format_modifier(bo, plane);
-               hnd->format_modifiers[2 * plane] = static_cast<uint32_t>(mod >> 32);
-               hnd->format_modifiers[2 * plane + 1] = static_cast<uint32_t>(mod);
+               hnd->sizes[plane] = drv_bo_get_plane_size(bo, plane);
        }
-
+       hnd->fds[hnd->num_planes] = reserved_region_fd;
+       hnd->reserved_region_size = descriptor->reserved_region_size;
+       static std::atomic<uint32_t> next_buffer_id{ 1 };
+       hnd->id = next_buffer_id++;
        hnd->width = drv_bo_get_width(bo);
        hnd->height = drv_bo_get_height(bo);
        hnd->format = drv_bo_get_format(bo);
-       hnd->use_flags[0] = static_cast<uint32_t>(descriptor->use_flags >> 32);
-       hnd->use_flags[1] = static_cast<uint32_t>(descriptor->use_flags);
+       hnd->tiling = bo->meta.tiling;
+       hnd->format_modifier = drv_bo_get_plane_format_modifier(bo, 0);
+       hnd->use_flags = descriptor->use_flags;
        bytes_per_pixel = drv_bytes_per_pixel_from_format(hnd->format, 0);
        hnd->pixel_stride = DIV_ROUND_UP(hnd->strides[0], bytes_per_pixel);
        hnd->magic = cros_gralloc_magic;
        hnd->droid_format = descriptor->droid_format;
-       hnd->usage = descriptor->producer_usage;
+       hnd->usage = descriptor->droid_usage;
+       hnd->total_size = descriptor->reserved_region_size + bo->meta.total_size;
+       hnd->name_offset = handle_data_size;
+
+       name = (char *)(&hnd->base.data[hnd->name_offset]);
+       snprintf(name, descriptor->name.size() + 1, "%s", descriptor->name.c_str());
 
        id = drv_bo_get_plane_handle(bo, 0).u32;
-       auto buffer = new cros_gralloc_buffer(id, bo, hnd);
+       auto buffer = new cros_gralloc_buffer(id, bo, hnd, hnd->fds[hnd->num_planes],
+                                             hnd->reserved_region_size);
 
        std::lock_guard<std::mutex> lock(mutex_);
        buffers_.emplace(id, buffer);
        handles_.emplace(hnd, std::make_pair(buffer, 1));
-       *out_handle = &hnd->base;
+       *out_handle = reinterpret_cast<buffer_handle_t>(hnd);
        return 0;
 }
 
@@ -208,18 +272,17 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
                struct bo *bo;
                struct drv_import_fd_data data;
                data.format = hnd->format;
+               data.tiling = hnd->tiling;
+
                data.width = hnd->width;
                data.height = hnd->height;
-               data.use_flags = static_cast<uint64_t>(hnd->use_flags[0]) << 32;
-               data.use_flags |= hnd->use_flags[1];
+               data.use_flags = hnd->use_flags;
 
                memcpy(data.fds, hnd->fds, sizeof(data.fds));
                memcpy(data.strides, hnd->strides, sizeof(data.strides));
                memcpy(data.offsets, hnd->offsets, sizeof(data.offsets));
                for (uint32_t plane = 0; plane < DRV_MAX_PLANES; plane++) {
-                       data.format_modifiers[plane] =
-                           static_cast<uint64_t>(hnd->format_modifiers[2 * plane]) << 32;
-                       data.format_modifiers[plane] |= hnd->format_modifiers[2 * plane + 1];
+                       data.format_modifiers[plane] = hnd->format_modifier;
                }
 
                bo = drv_bo_import(drv_, &data);
@@ -228,7 +291,8 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
 
                id = drv_bo_get_plane_handle(bo, 0).u32;
 
-               buffer = new cros_gralloc_buffer(id, bo, nullptr);
+               buffer = new cros_gralloc_buffer(id, bo, nullptr, hnd->fds[hnd->num_planes],
+                                                hnd->reserved_region_size);
                buffers_.emplace(id, buffer);
        }
 
@@ -264,10 +328,10 @@ int32_t cros_gralloc_driver::release(buffer_handle_t handle)
 }
 
 int32_t cros_gralloc_driver::lock(buffer_handle_t handle, int32_t acquire_fence,
-                                 const struct rectangle *rect, uint32_t map_flags,
-                                 uint8_t *addr[DRV_MAX_PLANES])
+                                 bool close_acquire_fence, const struct rectangle *rect,
+                                 uint32_t map_flags, uint8_t *addr[DRV_MAX_PLANES])
 {
-       int32_t ret = cros_gralloc_sync_wait(acquire_fence);
+       int32_t ret = cros_gralloc_sync_wait(acquire_fence, close_acquire_fence);
        if (ret)
                return ret;
 
@@ -313,6 +377,51 @@ int32_t cros_gralloc_driver::unlock(buffer_handle_t handle, int32_t *release_fen
        return buffer->unlock();
 }
 
+int32_t cros_gralloc_driver::invalidate(buffer_handle_t handle)
+{
+       std::lock_guard<std::mutex> lock(mutex_);
+
+       auto hnd = cros_gralloc_convert_handle(handle);
+       if (!hnd) {
+               drv_log("Invalid handle.\n");
+               return -EINVAL;
+       }
+
+       auto buffer = get_buffer(hnd);
+       if (!buffer) {
+               drv_log("Invalid Reference.\n");
+               return -EINVAL;
+       }
+
+       return buffer->invalidate();
+}
+
+int32_t cros_gralloc_driver::flush(buffer_handle_t handle, int32_t *release_fence)
+{
+       std::lock_guard<std::mutex> lock(mutex_);
+
+       auto hnd = cros_gralloc_convert_handle(handle);
+       if (!hnd) {
+               drv_log("Invalid handle.\n");
+               return -EINVAL;
+       }
+
+       auto buffer = get_buffer(hnd);
+       if (!buffer) {
+               drv_log("Invalid Reference.\n");
+               return -EINVAL;
+       }
+
+       /*
+        * From the ANativeWindow::dequeueBuffer documentation:
+        *
+        * "A value of -1 indicates that the caller may access the buffer immediately without
+        * waiting on a fence."
+        */
+       *release_fence = -1;
+       return buffer->flush();
+}
+
 int32_t cros_gralloc_driver::get_backing_store(buffer_handle_t handle, uint64_t *out_store)
 {
        std::lock_guard<std::mutex> lock(mutex_);
@@ -353,6 +462,32 @@ int32_t cros_gralloc_driver::resource_info(buffer_handle_t handle, uint32_t stri
        return buffer->resource_info(strides, offsets);
 }
 
+int32_t cros_gralloc_driver::get_reserved_region(buffer_handle_t handle,
+                                                void **reserved_region_addr,
+                                                uint64_t *reserved_region_size)
+{
+       std::lock_guard<std::mutex> lock(mutex_);
+
+       auto hnd = cros_gralloc_convert_handle(handle);
+       if (!hnd) {
+               drv_log("Invalid handle.\n");
+               return -EINVAL;
+       }
+
+       auto buffer = get_buffer(hnd);
+       if (!buffer) {
+               drv_log("Invalid Reference.\n");
+               return -EINVAL;
+       }
+
+       return buffer->get_reserved_region(reserved_region_addr, reserved_region_size);
+}
+
+uint32_t cros_gralloc_driver::get_resolved_drm_format(uint32_t drm_format, uint64_t usage)
+{
+       return drv_resolve_format(drv_, drm_format, usage);
+}
+
 cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd)
 {
        /* Assumes driver mutex is held. */
@@ -361,3 +496,13 @@ cros_gralloc_buffer *cros_gralloc_driver::get_buffer(cros_gralloc_handle_t hnd)
 
        return nullptr;
 }
+
+void cros_gralloc_driver::for_each_handle(
+    const std::function<void(cros_gralloc_handle_t)> &function)
+{
+       std::lock_guard<std::mutex> lock(mutex_);
+
+       for (const auto &pair : handles_) {
+               function(pair.first);
+       }
+}