blob: 710b78f78ed4d2c6b8f2fac8bdcf9408dcd0b122 [file] [log] [blame]
Gurchetan Singhd6b8b032017-05-31 14:31:31 -07001/*
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
Gurchetan Singh83501e62017-09-14 14:49:03 -070012cros_gralloc_buffer::cros_gralloc_buffer(uint32_t id, struct bo *acquire_bo,
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070013 struct cros_gralloc_handle *acquire_handle)
Gurchetan Singh83501e62017-09-14 14:49:03 -070014 : id_(id), bo_(acquire_bo), hnd_(acquire_handle), refcount_(1), lockcount_(0)
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070015{
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
22cros_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
31uint32_t cros_gralloc_buffer::get_id() const
32{
33 return id_;
34}
35
36int32_t cros_gralloc_buffer::increase_refcount()
37{
38 return ++refcount_;
39}
40
41int32_t cros_gralloc_buffer::decrease_refcount()
42{
43 assert(refcount_ > 0);
44 return --refcount_;
45}
46
47int32_t cros_gralloc_buffer::lock(uint64_t flags, uint8_t *addr[DRV_MAX_PLANES])
48{
Tomasz Figac6d8da12017-07-28 17:23:56 +090049 void *vaddr = nullptr;
50
Tomasz Figa889b9942017-07-28 17:19:44 +090051 memset(addr, 0, DRV_MAX_PLANES * sizeof(*addr));
52
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070053 /*
54 * Gralloc consumers don't support more than one kernel buffer per buffer object yet, so
55 * just use the first kernel buffer.
56 */
57 if (drv_num_buffers_per_bo(bo_) != 1) {
58 cros_gralloc_error("Can only support one buffer per bo.");
Tomasz Figa90bb7432017-07-21 17:54:05 +090059 return -EINVAL;
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070060 }
61
62 if (flags) {
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070063 if (lock_data_[0]) {
64 vaddr = lock_data_[0]->addr;
65 } else {
66 vaddr = drv_bo_map(bo_, 0, 0, drv_bo_get_width(bo_), drv_bo_get_height(bo_),
Joe Kniss65705852017-06-29 15:02:46 -070067 BO_TRANSFER_READ_WRITE, &lock_data_[0], 0);
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070068 }
69
70 if (vaddr == MAP_FAILED) {
71 cros_gralloc_error("Mapping failed.");
Tomasz Figa90bb7432017-07-21 17:54:05 +090072 return -EFAULT;
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070073 }
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070074 }
75
76 for (uint32_t plane = 0; plane < num_planes_; plane++)
Tomasz Figac6d8da12017-07-28 17:23:56 +090077 addr[plane] = static_cast<uint8_t *>(vaddr) + drv_bo_get_plane_offset(bo_, plane);
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070078
79 lockcount_++;
Tomasz Figa90bb7432017-07-21 17:54:05 +090080 return 0;
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070081}
82
83int32_t cros_gralloc_buffer::unlock()
84{
85 if (lockcount_ <= 0) {
86 cros_gralloc_error("Buffer was not locked.");
Tomasz Figa90bb7432017-07-21 17:54:05 +090087 return -EINVAL;
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070088 }
89
Gurchetan Singh254dbb12017-09-14 15:16:15 -070090 --lockcount_;
91 if (lock_data_[0])
92 return drv_bo_flush(bo_, lock_data_[0]);
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070093
Tomasz Figa90bb7432017-07-21 17:54:05 +090094 return 0;
Gurchetan Singhd6b8b032017-05-31 14:31:31 -070095}