blob: 196541010e6aa9b12ba627d58f44910ea761254c [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <private/dvr/ion_buffer.h>
2
Alex Vakulenko4fe60582017-02-02 11:35:59 -08003#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08004#define ATRACE_TAG ATRACE_TAG_GRAPHICS
5#include <utils/Trace.h>
6
7#include <mutex>
8
Corey Tabakacd52dd92017-04-07 18:03:57 -07009namespace {
10
11constexpr uint32_t kDefaultGraphicBufferLayerCount = 1;
12
13} // anonymous namespace
14
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080015namespace android {
16namespace dvr {
17
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070018IonBuffer::IonBuffer() : IonBuffer(nullptr, 0, 0, 0, 0, 0, 0) {}
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080019
Corey Tabakacd52dd92017-04-07 18:03:57 -070020IonBuffer::IonBuffer(uint32_t width, uint32_t height, uint32_t format,
Jiwen 'Steve' Cai044963e2017-05-01 22:43:21 -070021 uint64_t usage)
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080022 : IonBuffer() {
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070023 Alloc(width, height, kDefaultGraphicBufferLayerCount, format, usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080024}
25
Corey Tabakacd52dd92017-04-07 18:03:57 -070026IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
Jiwen 'Steve' Cai044963e2017-05-01 22:43:21 -070027 uint32_t stride, uint32_t format, uint64_t usage)
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070028 : IonBuffer(handle, width, height, kDefaultGraphicBufferLayerCount, stride,
29 format, usage) {}
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080030
Corey Tabakacd52dd92017-04-07 18:03:57 -070031IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070032 uint32_t layer_count, uint32_t stride, uint32_t format,
33 uint64_t usage)
Mark Urbanus8a71b132017-03-16 11:06:51 -070034 : buffer_(nullptr) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080035 ALOGD_IF(TRACE,
Corey Tabakacd52dd92017-04-07 18:03:57 -070036 "IonBuffer::IonBuffer: handle=%p width=%u height=%u layer_count=%u "
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070037 "stride=%u format=%u usage=%" PRIx64,
38 handle, width, height, layer_count, stride, format, usage);
Mark Urbanus8a71b132017-03-16 11:06:51 -070039 if (handle != 0) {
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070040 Import(handle, width, height, layer_count, stride, format, usage);
Mark Urbanus8a71b132017-03-16 11:06:51 -070041 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080042}
43
44IonBuffer::~IonBuffer() {
45 ALOGD_IF(TRACE,
Corey Tabakacd52dd92017-04-07 18:03:57 -070046 "IonBuffer::~IonBuffer: handle=%p width=%u height=%u stride=%u "
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070047 "format=%u usage=%" PRIx64,
Corey Tabakacd52dd92017-04-07 18:03:57 -070048 handle(), width(), height(), stride(), format(), usage());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080049 FreeHandle();
50}
51
Chih-Hung Hsieh5bc849f2018-09-25 14:21:50 -070052IonBuffer::IonBuffer(IonBuffer&& other) noexcept : IonBuffer() {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080053 *this = std::move(other);
54}
55
Chih-Hung Hsieh5bc849f2018-09-25 14:21:50 -070056IonBuffer& IonBuffer::operator=(IonBuffer&& other) noexcept {
Mark Urbanus8a71b132017-03-16 11:06:51 -070057 ALOGD_IF(TRACE, "IonBuffer::operator=: handle_=%p other.handle_=%p", handle(),
58 other.handle());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080059
60 if (this != &other) {
Mark Urbanus8a71b132017-03-16 11:06:51 -070061 buffer_ = other.buffer_;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080062 other.FreeHandle();
63 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080064 return *this;
65}
66
67void IonBuffer::FreeHandle() {
Mark Urbanus8a71b132017-03-16 11:06:51 -070068 if (buffer_.get()) {
69 // GraphicBuffer unregisters and cleans up the handle if needed
70 buffer_ = nullptr;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080071 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080072}
73
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070074int IonBuffer::Alloc(uint32_t width, uint32_t height, uint32_t layer_count,
75 uint32_t format, uint64_t usage) {
Jiwen 'Steve' Cai044963e2017-05-01 22:43:21 -070076 ALOGD_IF(TRACE,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070077 "IonBuffer::Alloc: width=%u height=%u layer_count=%u format=%u "
78 "usage=%" PRIx64, width, height, layer_count, format, usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080079
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070080 sp<GraphicBuffer> buffer =
81 new GraphicBuffer(width, height, format, layer_count, usage);
Corey Tabakacd52dd92017-04-07 18:03:57 -070082 if (buffer->initCheck() != OK) {
Chia-I Wub42f1712017-03-21 13:15:39 -070083 ALOGE("IonBuffer::Aloc: Failed to allocate buffer");
Corey Tabakacd52dd92017-04-07 18:03:57 -070084 return -EINVAL;
85 } else {
86 buffer_ = buffer;
Corey Tabakacd52dd92017-04-07 18:03:57 -070087 return 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080088 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080089}
90
Corey Tabakacd52dd92017-04-07 18:03:57 -070091void IonBuffer::Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070092 uint32_t layer_count, uint32_t stride, uint32_t format,
93 uint64_t usage) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080094 ALOGD_IF(TRACE,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -070095 "IonBuffer::Reset: handle=%p width=%u height=%u layer_count=%u "
96 "stride=%u format=%u usage=%" PRIx64,
97 handle, width, height, layer_count, stride, format, usage);
98 Import(handle, width, height, layer_count, stride, format, usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080099}
100
Corey Tabakacd52dd92017-04-07 18:03:57 -0700101int IonBuffer::Import(buffer_handle_t handle, uint32_t width, uint32_t height,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700102 uint32_t layer_count, uint32_t stride, uint32_t format,
103 uint64_t usage) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800104 ATRACE_NAME("IonBuffer::Import1");
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700105 ALOGD_IF(TRACE,
106 "IonBuffer::Import: handle=%p width=%u height=%u layer_count=%u "
107 "stride=%u format=%u usage=%" PRIx64,
108 handle, width, height, layer_count, stride, format, usage);
Mark Urbanus8a71b132017-03-16 11:06:51 -0700109 FreeHandle();
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700110 sp<GraphicBuffer> buffer =
111 new GraphicBuffer(handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE, width,
112 height, format, layer_count, usage, stride);
Corey Tabakacd52dd92017-04-07 18:03:57 -0700113 if (buffer->initCheck() != OK) {
Chia-I Wub42f1712017-03-21 13:15:39 -0700114 ALOGE("IonBuffer::Import: Failed to import buffer");
Mark Urbanus8a71b132017-03-16 11:06:51 -0700115 return -EINVAL;
Corey Tabakacd52dd92017-04-07 18:03:57 -0700116 } else {
117 buffer_ = buffer;
Corey Tabakacd52dd92017-04-07 18:03:57 -0700118 return 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800119 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800120}
121
122int IonBuffer::Import(const int* fd_array, int fd_count, const int* int_array,
Corey Tabakacd52dd92017-04-07 18:03:57 -0700123 int int_count, uint32_t width, uint32_t height,
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700124 uint32_t layer_count, uint32_t stride, uint32_t format,
125 uint64_t usage) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800126 ATRACE_NAME("IonBuffer::Import2");
127 ALOGD_IF(TRACE,
Corey Tabakacd52dd92017-04-07 18:03:57 -0700128 "IonBuffer::Import: fd_count=%d int_count=%d width=%u height=%u "
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700129 "layer_count=%u stride=%u format=%u usage=%" PRIx64,
130 fd_count, int_count, width, height, layer_count, stride, format,
131 usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800132
133 if (fd_count < 0 || int_count < 0) {
134 ALOGE("IonBuffer::Import: invalid arguments.");
135 return -EINVAL;
136 }
137
138 native_handle_t* handle = native_handle_create(fd_count, int_count);
139 if (!handle) {
140 ALOGE("IonBuffer::Import: failed to create new native handle.");
141 return -ENOMEM;
142 }
143
144 // Copy fd_array into the first part of handle->data and int_array right
145 // after it.
146 memcpy(handle->data, fd_array, sizeof(int) * fd_count);
147 memcpy(handle->data + fd_count, int_array, sizeof(int) * int_count);
148
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700149 const int ret =
150 Import(handle, width, height, layer_count, stride, format, usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800151 if (ret < 0) {
152 ALOGE("IonBuffer::Import: failed to import raw native handle: %s",
153 strerror(-ret));
154 native_handle_close(handle);
155 native_handle_delete(handle);
156 }
157
158 return ret;
159}
160
161int IonBuffer::Duplicate(const IonBuffer* other) {
162 if (!other->handle())
163 return -EINVAL;
164
165 const int fd_count = other->handle()->numFds;
166 const int int_count = other->handle()->numInts;
167
168 if (fd_count < 0 || int_count < 0)
169 return -EINVAL;
170
171 native_handle_t* handle = native_handle_create(fd_count, int_count);
172 if (!handle) {
173 ALOGE("IonBuffer::Duplicate: Failed to create new native handle.");
174 return -ENOMEM;
175 }
176
177 // Duplicate the file descriptors from the other native handle.
178 for (int i = 0; i < fd_count; i++)
179 handle->data[i] = dup(other->handle()->data[i]);
180
181 // Copy the ints after the file descriptors.
182 memcpy(handle->data + fd_count, other->handle()->data + fd_count,
183 sizeof(int) * int_count);
184
Corey Tabakacd52dd92017-04-07 18:03:57 -0700185 const int ret =
Hendrik Wagenaar108e84f2017-05-07 22:19:17 -0700186 Import(handle, other->width(), other->height(), other->layer_count(),
187 other->stride(), other->format(), other->usage());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800188 if (ret < 0) {
189 ALOGE("IonBuffer::Duplicate: Failed to import duplicate native handle: %s",
190 strerror(-ret));
191 native_handle_close(handle);
192 native_handle_delete(handle);
193 }
194
195 return ret;
196}
197
Corey Tabakacd52dd92017-04-07 18:03:57 -0700198int IonBuffer::Lock(uint32_t usage, int x, int y, int width, int height,
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800199 void** address) {
200 ATRACE_NAME("IonBuffer::Lock");
201 ALOGD_IF(TRACE,
202 "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d "
203 "address=%p",
Mark Urbanus8a71b132017-03-16 11:06:51 -0700204 handle(), usage, x, y, width, height, address);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800205
Corey Tabakacd52dd92017-04-07 18:03:57 -0700206 status_t err =
207 buffer_->lock(usage, Rect(x, y, x + width, y + height), address);
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800208 if (err != OK)
Mark Urbanus8a71b132017-03-16 11:06:51 -0700209 return -EINVAL;
210 else
211 return 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800212}
213
Corey Tabakacd52dd92017-04-07 18:03:57 -0700214int IonBuffer::LockYUV(uint32_t usage, int x, int y, int width, int height,
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800215 struct android_ycbcr* yuv) {
216 ATRACE_NAME("IonBuffer::LockYUV");
217 ALOGD_IF(TRACE,
218 "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d",
Mark Urbanus8a71b132017-03-16 11:06:51 -0700219 handle(), usage, x, y, width, height);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800220
Corey Tabakacd52dd92017-04-07 18:03:57 -0700221 status_t err =
222 buffer_->lockYCbCr(usage, Rect(x, y, x + width, y + height), yuv);
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800223 if (err != OK)
Mark Urbanus8a71b132017-03-16 11:06:51 -0700224 return -EINVAL;
225 else
226 return 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800227}
228
229int IonBuffer::Unlock() {
230 ATRACE_NAME("IonBuffer::Unlock");
Mark Urbanus8a71b132017-03-16 11:06:51 -0700231 ALOGD_IF(TRACE, "IonBuffer::Unlock: handle=%p", handle());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800232
Mark Urbanus8a71b132017-03-16 11:06:51 -0700233 status_t err = buffer_->unlock();
Tianyu Jiang932fb4f2018-11-15 11:09:58 -0800234 if (err != OK)
Mark Urbanus8a71b132017-03-16 11:06:51 -0700235 return -EINVAL;
236 else
237 return 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800238}
Corey Tabakacd52dd92017-04-07 18:03:57 -0700239} // namespace dvr
240} // namespace android