OSDN Git Service

i915: Fall back to GEM_MMAP_GTT if GEM_MMAP fails
[android-x86/external-minigbm.git] / cros_gralloc / cros_gralloc_buffer.cc
index 0301af1..2982505 100644 (file)
 #include <sys/mman.h>
 
 cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo,
-                                        struct cros_gralloc_handle *acquire_handle)
-    : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0)
+                                        struct cros_gralloc_handle *acquire_handle,
+                                        int32_t reserved_region_fd, uint64_t reserved_region_size)
+    : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0),
+      reserved_region_fd_(reserved_region_fd), reserved_region_size_(reserved_region_size),
+      reserved_region_addr_(nullptr)
 {
        assert(bo_);
        num_planes_ = drv_bo_get_num_planes(bo_);
@@ -26,6 +29,9 @@ cros_gralloc_buffer::~cros_gralloc_buffer()
                native_handle_close(&hnd_->base);
                delete hnd_;
        }
+       if (reserved_region_addr_) {
+               munmap(reserved_region_addr_, reserved_region_size_);
+       }
 }
 
 uint32_t cros_gralloc_buffer::get_id() const
@@ -65,7 +71,18 @@ int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_fla
                        drv_bo_invalidate(bo_, lock_data_[0]);
                        vaddr = lock_data_[0]->vma->addr;
                } else {
-                       vaddr = drv_bo_map(bo_, rect, map_flags, &lock_data_[0], 0);
+                       struct rectangle r = *rect;
+
+                       if (!r.width && !r.height && !r.x && !r.y) {
+                               /*
+                                * Android IMapper.hal: An accessRegion of all-zeros means the
+                                * entire buffer.
+                                */
+                               r.width = drv_bo_get_width(bo_);
+                               r.height = drv_bo_get_height(bo_);
+                       }
+
+                       vaddr = drv_bo_map(bo_, &r, map_flags, &lock_data_[0], 0);
                }
 
                if (vaddr == MAP_FAILED) {
@@ -97,3 +114,58 @@ int32_t cros_gralloc_buffer::unlock()
 
        return 0;
 }
+
+int32_t cros_gralloc_buffer::resource_info(uint32_t strides[DRV_MAX_PLANES],
+                                          uint32_t offsets[DRV_MAX_PLANES])
+{
+       return drv_resource_info(bo_, strides, offsets);
+}
+
+int32_t cros_gralloc_buffer::invalidate()
+{
+       if (lockcount_ <= 0) {
+               drv_log("Buffer was not locked.\n");
+               return -EINVAL;
+       }
+
+       if (lock_data_[0]) {
+               return drv_bo_invalidate(bo_, lock_data_[0]);
+       }
+
+       return 0;
+}
+
+int32_t cros_gralloc_buffer::flush()
+{
+       if (lockcount_ <= 0) {
+               drv_log("Buffer was not locked.\n");
+               return -EINVAL;
+       }
+
+       if (lock_data_[0]) {
+               return drv_bo_flush(bo_, lock_data_[0]);
+       }
+
+       return 0;
+}
+
+int32_t cros_gralloc_buffer::get_reserved_region(void **addr, uint64_t *size)
+{
+       if (reserved_region_fd_ <= 0) {
+               drv_log("Buffer does not have reserved region.\n");
+               return -EINVAL;
+       }
+
+       if (!reserved_region_addr_) {
+               reserved_region_addr_ = mmap(nullptr, reserved_region_size_, PROT_WRITE | PROT_READ,
+                                            MAP_SHARED, reserved_region_fd_, 0);
+               if (reserved_region_addr_ == MAP_FAILED) {
+                       drv_log("Failed to mmap reserved region: %s.\n", strerror(errno));
+                       return -errno;
+               }
+       }
+
+       *addr = reserved_region_addr_;
+       *size = reserved_region_size_;
+       return 0;
+}