ion_buffer.cpp revision 8a71b13127f737a46c55ba94d31ba0262e7cbf8a
1#include <private/dvr/ion_buffer.h> 2#include <ui/GraphicBufferMapper.h> 3 4#include <log/log.h> 5#define ATRACE_TAG ATRACE_TAG_GRAPHICS 6#include <utils/Trace.h> 7 8#include <mutex> 9 10namespace android { 11namespace dvr { 12 13IonBuffer::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 24 25IonBuffer::IonBuffer(buffer_handle_t handle, int width, int height, 26 int layer_count, int stride, int layer_stride, int format, 27 int usage) 28 : buffer_(nullptr) { 29 ALOGD_IF(TRACE, 30 "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 } 37} 38 39IonBuffer::~IonBuffer() { 40 ALOGD_IF(TRACE, 41 "IonBuffer::~IonBuffer: handle=%p width=%d height=%d stride=%d " 42 "format=%d usage=%d", 43 handle() , width(), height(), stride(), format(), usage()); 44 FreeHandle(); 45} 46 47IonBuffer::IonBuffer(IonBuffer&& other) : IonBuffer() { 48 *this = std::move(other); 49} 50 51IonBuffer& IonBuffer::operator=(IonBuffer&& other) { 52 ALOGD_IF(TRACE, "IonBuffer::operator=: handle_=%p other.handle_=%p", handle(), 53 other.handle()); 54 55 if (this != &other) { 56 buffer_ = other.buffer_; 57 other.FreeHandle(); 58 } 59 return *this; 60} 61 62void IonBuffer::FreeHandle() { 63 if (buffer_.get()) { 64 // GraphicBuffer unregisters and cleans up the handle if needed 65 buffer_ = nullptr; 66 } 67} 68 69int IonBuffer::Alloc(int width, int height, int format, int usage) { 70 ALOGD_IF(TRACE, "IonBuffer::Alloc: width=%d height=%d format=%d usage=%d", 71 width, height, format, usage); 72 73 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"); 77 } 78 return 0; 79} 80 81void 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); 87 Import(handle, width, height, stride, format, usage); 88} 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); 98 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; 105 } 106 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", 187 handle(), usage, x, y, width, height, address); 188 189 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; 195} 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", 202 handle(), usage, x, y, width, height); 203 204 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; 210} 211 212int IonBuffer::Unlock() { 213 ATRACE_NAME("IonBuffer::Unlock"); 214 ALOGD_IF(TRACE, "IonBuffer::Unlock: handle=%p", handle()); 215 216 status_t err = buffer_->unlock(); 217 if (err != NO_ERROR) 218 return -EINVAL; 219 else 220 return 0; 221} 222} // namespace dvr 223} // namespace android 224