blob: 3fb3f3c6ff1102918c6a5a9a3ce78a9feaed7e7c [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <private/dvr/ion_buffer.h>
Mark Urbanus8a71b132017-03-16 11:06:51 -07002#include <ui/GraphicBufferMapper.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08003
Alex Vakulenko4fe60582017-02-02 11:35:59 -08004#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08005#define ATRACE_TAG ATRACE_TAG_GRAPHICS
6#include <utils/Trace.h>
7
8#include <mutex>
9
10namespace android {
11namespace dvr {
12
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080013IonBuffer::IonBuffer() : IonBuffer(nullptr, 0, 0, 0, 0, 0, 0, 0) {}
14
15IonBuffer::IonBuffer(int width, int height, int format, int usage)
16 : IonBuffer() {
17 Alloc(width, height, format, usage);
18}
19
20IonBuffer::IonBuffer(buffer_handle_t handle, int width, int height, int stride,
21 int format, int usage)
22 : IonBuffer(handle, width, height, 1, stride, 0, format, usage) {}
23
Mark Urbanus8a71b132017-03-16 11:06:51 -070024
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080025IonBuffer::IonBuffer(buffer_handle_t handle, int width, int height,
26 int layer_count, int stride, int layer_stride, int format,
27 int usage)
Mark Urbanus8a71b132017-03-16 11:06:51 -070028 : buffer_(nullptr) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080029 ALOGD_IF(TRACE,
Mark Urbanus8a71b132017-03-16 11:06:51 -070030 "IonBuffer::IonBuffer: handle=%p width=%d height=%d layer_count=%d "
31 "stride=%d layer stride=%d format=%d usage=%d",
32 handle, width, height, layer_count, stride, layer_stride,
33 format, usage);
34 if (handle != 0) {
35 Import(handle, width, height, stride, format, usage);
36 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080037}
38
39IonBuffer::~IonBuffer() {
40 ALOGD_IF(TRACE,
41 "IonBuffer::~IonBuffer: handle=%p width=%d height=%d stride=%d "
42 "format=%d usage=%d",
Mark Urbanus8a71b132017-03-16 11:06:51 -070043 handle() , width(), height(), stride(), format(), usage());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080044 FreeHandle();
45}
46
47IonBuffer::IonBuffer(IonBuffer&& other) : IonBuffer() {
48 *this = std::move(other);
49}
50
51IonBuffer& IonBuffer::operator=(IonBuffer&& other) {
Mark Urbanus8a71b132017-03-16 11:06:51 -070052 ALOGD_IF(TRACE, "IonBuffer::operator=: handle_=%p other.handle_=%p", handle(),
53 other.handle());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080054
55 if (this != &other) {
Mark Urbanus8a71b132017-03-16 11:06:51 -070056 buffer_ = other.buffer_;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080057 other.FreeHandle();
58 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080059 return *this;
60}
61
62void IonBuffer::FreeHandle() {
Mark Urbanus8a71b132017-03-16 11:06:51 -070063 if (buffer_.get()) {
64 // GraphicBuffer unregisters and cleans up the handle if needed
65 buffer_ = nullptr;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080066 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080067}
68
69int IonBuffer::Alloc(int width, int height, int format, int usage) {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080070 ALOGD_IF(TRACE, "IonBuffer::Alloc: width=%d height=%d format=%d usage=%d",
71 width, height, format, usage);
72
Mark Urbanus8a71b132017-03-16 11:06:51 -070073 GraphicBufferMapper& mapper = GraphicBufferMapper::get();
74 buffer_ = new GraphicBuffer(width, height, format, usage);
75 if (mapper.registerBuffer(buffer_.get()) != OK) {
76 ALOGE("IonBuffer::Aloc: Failed to register buffer");
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080077 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080078 return 0;
79}
80
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080081void IonBuffer::Reset(buffer_handle_t handle, int width, int height, int stride,
82 int format, int usage) {
83 ALOGD_IF(TRACE,
84 "IonBuffer::Reset: handle=%p width=%d height=%d stride=%d format=%d "
85 "usage=%d",
86 handle, width, height, stride, format, usage);
Mark Urbanus8a71b132017-03-16 11:06:51 -070087 Import(handle, width, height, stride, format, usage);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080088}
89
90int IonBuffer::Import(buffer_handle_t handle, int width, int height, int stride,
91 int format, int usage) {
92 ATRACE_NAME("IonBuffer::Import1");
93 ALOGD_IF(
94 TRACE,
95 "IonBuffer::Import: handle=%p width=%d height=%d stride=%d format=%d "
96 "usage=%d",
97 handle, width, height, stride, format, usage);
Mark Urbanus8a71b132017-03-16 11:06:51 -070098 FreeHandle();
99 GraphicBufferMapper& mapper = GraphicBufferMapper::get();
100 buffer_ = new GraphicBuffer(width, height, format, 1, usage,
101 stride, (native_handle_t*)handle, true);
102 if (mapper.registerBuffer(buffer_.get()) != OK) {
103 ALOGE("IonBuffer::Import: Failed to register cloned buffer");
104 return -EINVAL;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800105 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800106 return 0;
107}
108
109int IonBuffer::Import(const int* fd_array, int fd_count, const int* int_array,
110 int int_count, int width, int height, int stride,
111 int format, int usage) {
112 ATRACE_NAME("IonBuffer::Import2");
113 ALOGD_IF(TRACE,
114 "IonBuffer::Import: fd_count=%d int_count=%d width=%d height=%d "
115 "stride=%d format=%d usage=%d",
116 fd_count, int_count, width, height, stride, format, usage);
117
118 if (fd_count < 0 || int_count < 0) {
119 ALOGE("IonBuffer::Import: invalid arguments.");
120 return -EINVAL;
121 }
122
123 native_handle_t* handle = native_handle_create(fd_count, int_count);
124 if (!handle) {
125 ALOGE("IonBuffer::Import: failed to create new native handle.");
126 return -ENOMEM;
127 }
128
129 // Copy fd_array into the first part of handle->data and int_array right
130 // after it.
131 memcpy(handle->data, fd_array, sizeof(int) * fd_count);
132 memcpy(handle->data + fd_count, int_array, sizeof(int) * int_count);
133
134 int ret = Import(handle, width, height, stride, format, usage);
135 if (ret < 0) {
136 ALOGE("IonBuffer::Import: failed to import raw native handle: %s",
137 strerror(-ret));
138 native_handle_close(handle);
139 native_handle_delete(handle);
140 }
141
142 return ret;
143}
144
145int IonBuffer::Duplicate(const IonBuffer* other) {
146 if (!other->handle())
147 return -EINVAL;
148
149 const int fd_count = other->handle()->numFds;
150 const int int_count = other->handle()->numInts;
151
152 if (fd_count < 0 || int_count < 0)
153 return -EINVAL;
154
155 native_handle_t* handle = native_handle_create(fd_count, int_count);
156 if (!handle) {
157 ALOGE("IonBuffer::Duplicate: Failed to create new native handle.");
158 return -ENOMEM;
159 }
160
161 // Duplicate the file descriptors from the other native handle.
162 for (int i = 0; i < fd_count; i++)
163 handle->data[i] = dup(other->handle()->data[i]);
164
165 // Copy the ints after the file descriptors.
166 memcpy(handle->data + fd_count, other->handle()->data + fd_count,
167 sizeof(int) * int_count);
168
169 const int ret = Import(handle, other->width(), other->height(),
170 other->stride(), other->format(), other->usage());
171 if (ret < 0) {
172 ALOGE("IonBuffer::Duplicate: Failed to import duplicate native handle: %s",
173 strerror(-ret));
174 native_handle_close(handle);
175 native_handle_delete(handle);
176 }
177
178 return ret;
179}
180
181int IonBuffer::Lock(int usage, int x, int y, int width, int height,
182 void** address) {
183 ATRACE_NAME("IonBuffer::Lock");
184 ALOGD_IF(TRACE,
185 "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d "
186 "address=%p",
Mark Urbanus8a71b132017-03-16 11:06:51 -0700187 handle(), usage, x, y, width, height, address);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800188
Mark Urbanus8a71b132017-03-16 11:06:51 -0700189 status_t err = buffer_->lock(usage, Rect(x, y, x + width, y + height),
190 address);
191 if (err != NO_ERROR)
192 return -EINVAL;
193 else
194 return 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800195}
196
197int IonBuffer::LockYUV(int usage, int x, int y, int width, int height,
198 struct android_ycbcr* yuv) {
199 ATRACE_NAME("IonBuffer::LockYUV");
200 ALOGD_IF(TRACE,
201 "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d",
Mark Urbanus8a71b132017-03-16 11:06:51 -0700202 handle(), usage, x, y, width, height);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800203
Mark Urbanus8a71b132017-03-16 11:06:51 -0700204 status_t err = buffer_->lockYCbCr(usage, Rect(x, y, x + width, y + height),
205 yuv);
206 if (err != NO_ERROR)
207 return -EINVAL;
208 else
209 return 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800210}
211
212int IonBuffer::Unlock() {
213 ATRACE_NAME("IonBuffer::Unlock");
Mark Urbanus8a71b132017-03-16 11:06:51 -0700214 ALOGD_IF(TRACE, "IonBuffer::Unlock: handle=%p", handle());
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800215
Mark Urbanus8a71b132017-03-16 11:06:51 -0700216 status_t err = buffer_->unlock();
217 if (err != NO_ERROR)
218 return -EINVAL;
219 else
220 return 0;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800221}
Mark Urbanus8a71b132017-03-16 11:06:51 -0700222} // namespace dvr
223} // namespace android