OSDN Git Service

Merge 'aosp/upstream-master' into 'aosp/master' am: 24cb462579 am: 88b0a4235a am...
[android-x86/external-minigbm.git] / cros_gralloc / cros_gralloc_buffer.cc
1 /*
2  * Copyright 2017 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 #include "cros_gralloc_buffer.h"
8
9 #include <assert.h>
10 #include <sys/mman.h>
11
12 cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo,
13                                          struct cros_gralloc_handle *acquire_handle)
14     : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0)
15 {
16         assert(bo_);
17         num_planes_ = drv_bo_get_num_planes(bo_);
18         for (uint32_t plane = 0; plane < num_planes_; plane++)
19                 lock_data_[plane] = nullptr;
20 }
21
22 cros_gralloc_buffer::~cros_gralloc_buffer()
23 {
24         drv_bo_destroy(bo_);
25         if (hnd_) {
26                 native_handle_close(&hnd_->base);
27                 delete hnd_;
28         }
29 }
30
31 uint32_t cros_gralloc_buffer::get_id() const
32 {
33         return id_;
34 }
35
36 int32_t cros_gralloc_buffer::increase_refcount()
37 {
38         return ++refcount_;
39 }
40
41 int32_t cros_gralloc_buffer::decrease_refcount()
42 {
43         assert(refcount_ > 0);
44         return --refcount_;
45 }
46
47 int32_t cros_gralloc_buffer::lock(const struct rectangle *rect, uint32_t map_flags,
48                                   uint8_t *addr[DRV_MAX_PLANES])
49 {
50         void *vaddr = nullptr;
51
52         memset(addr, 0, DRV_MAX_PLANES * sizeof(*addr));
53
54         /*
55          * Gralloc consumers don't support more than one kernel buffer per buffer object yet, so
56          * just use the first kernel buffer.
57          */
58         if (drv_num_buffers_per_bo(bo_) != 1) {
59                 drv_log("Can only support one buffer per bo.\n");
60                 return -EINVAL;
61         }
62
63         if (map_flags) {
64                 if (lock_data_[0]) {
65                         drv_bo_invalidate(bo_, lock_data_[0]);
66                         vaddr = lock_data_[0]->vma->addr;
67                 } else {
68                         struct rectangle r = *rect;
69
70                         if (!r.width && !r.height && !r.x && !r.y) {
71                                 /*
72                                  * Android IMapper.hal: An accessRegion of all-zeros means the
73                                  * entire buffer.
74                                  */
75                                 r.width = drv_bo_get_width(bo_);
76                                 r.height = drv_bo_get_height(bo_);
77                         }
78
79                         vaddr = drv_bo_map(bo_, &r, map_flags, &lock_data_[0], 0);
80                 }
81
82                 if (vaddr == MAP_FAILED) {
83                         drv_log("Mapping failed.\n");
84                         return -EFAULT;
85                 }
86         }
87
88         for (uint32_t plane = 0; plane < num_planes_; plane++)
89                 addr[plane] = static_cast<uint8_t *>(vaddr) + drv_bo_get_plane_offset(bo_, plane);
90
91         lockcount_++;
92         return 0;
93 }
94
95 int32_t cros_gralloc_buffer::unlock()
96 {
97         if (lockcount_ <= 0) {
98                 drv_log("Buffer was not locked.\n");
99                 return -EINVAL;
100         }
101
102         if (!--lockcount_) {
103                 if (lock_data_[0]) {
104                         drv_bo_flush_or_unmap(bo_, lock_data_[0]);
105                         lock_data_[0] = nullptr;
106                 }
107         }
108
109         return 0;
110 }