ion_buffer.cpp revision cd52dd9f1b301854b4e1734e3741d9cef8f784b1
1#include <private/dvr/ion_buffer.h> 2 3#include <log/log.h> 4#define ATRACE_TAG ATRACE_TAG_GRAPHICS 5#include <utils/Trace.h> 6 7#include <mutex> 8 9namespace { 10 11constexpr uint32_t kDefaultGraphicBufferLayerCount = 1; 12 13} // anonymous namespace 14 15namespace android { 16namespace dvr { 17 18IonBuffer::IonBuffer() : IonBuffer(nullptr, 0, 0, 0, 0, 0, 0, 0) {} 19 20IonBuffer::IonBuffer(uint32_t width, uint32_t height, uint32_t format, 21 uint32_t usage) 22 : IonBuffer(width, height, format, usage, usage) {} 23 24IonBuffer::IonBuffer(uint32_t width, uint32_t height, uint32_t format, 25 uint64_t producer_usage, uint64_t consumer_usage) 26 : IonBuffer() { 27 Alloc(width, height, format, producer_usage, consumer_usage); 28} 29 30IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height, 31 uint32_t stride, uint32_t format, uint32_t usage) 32 : IonBuffer(handle, width, height, 1, stride, 0, format, usage) {} 33 34IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height, 35 uint32_t layer_count, uint32_t stride, 36 uint32_t layer_stride, uint32_t format, uint32_t usage) 37 : IonBuffer(handle, width, height, layer_count, stride, layer_stride, 38 format, usage, usage) {} 39 40IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height, 41 uint32_t layer_count, uint32_t stride, 42 uint32_t layer_stride, uint32_t format, 43 uint64_t producer_usage, uint64_t consumer_usage) 44 : buffer_(nullptr) { 45 ALOGD_IF(TRACE, 46 "IonBuffer::IonBuffer: handle=%p width=%u height=%u layer_count=%u " 47 "stride=%u layer stride=%u format=%u producer_usage=%" PRIx64 48 " consumer_usage=%" PRIx64, 49 handle, width, height, layer_count, stride, layer_stride, format, 50 producer_usage, consumer_usage); 51 if (handle != 0) { 52 Import(handle, width, height, stride, format, producer_usage, 53 consumer_usage); 54 } 55} 56 57IonBuffer::~IonBuffer() { 58 ALOGD_IF(TRACE, 59 "IonBuffer::~IonBuffer: handle=%p width=%u height=%u stride=%u " 60 "format=%u usage=%x", 61 handle(), width(), height(), stride(), format(), usage()); 62 FreeHandle(); 63} 64 65IonBuffer::IonBuffer(IonBuffer&& other) : IonBuffer() { 66 *this = std::move(other); 67} 68 69IonBuffer& IonBuffer::operator=(IonBuffer&& other) { 70 ALOGD_IF(TRACE, "IonBuffer::operator=: handle_=%p other.handle_=%p", handle(), 71 other.handle()); 72 73 if (this != &other) { 74 buffer_ = other.buffer_; 75 other.FreeHandle(); 76 } 77 return *this; 78} 79 80void IonBuffer::FreeHandle() { 81 if (buffer_.get()) { 82 // GraphicBuffer unregisters and cleans up the handle if needed 83 buffer_ = nullptr; 84 producer_usage_ = 0; 85 consumer_usage_ = 0; 86 } 87} 88 89int IonBuffer::Alloc(uint32_t width, uint32_t height, uint32_t format, 90 uint32_t usage) { 91 return Alloc(width, height, format, usage, usage); 92} 93 94int IonBuffer::Alloc(uint32_t width, uint32_t height, uint32_t format, 95 uint64_t producer_usage, uint64_t consumer_usage) { 96 ALOGD_IF( 97 TRACE, 98 "IonBuffer::Alloc: width=%u height=%u format=%u producer_usage=%" PRIx64 99 " consumer_usage=%" PRIx64, 100 width, height, format, producer_usage, consumer_usage); 101 102 sp<GraphicBuffer> buffer = 103 new GraphicBuffer(width, height, format, kDefaultGraphicBufferLayerCount, 104 producer_usage, consumer_usage); 105 if (buffer->initCheck() != OK) { 106 ALOGE("IonBuffer::Aloc: Failed to allocate buffer"); 107 return -EINVAL; 108 } else { 109 buffer_ = buffer; 110 producer_usage_ = producer_usage; 111 consumer_usage_ = consumer_usage; 112 return 0; 113 } 114} 115 116void IonBuffer::Reset(buffer_handle_t handle, uint32_t width, uint32_t height, 117 uint32_t stride, uint32_t format, uint32_t usage) { 118 Reset(handle, width, height, stride, format, usage, usage); 119} 120 121void IonBuffer::Reset(buffer_handle_t handle, uint32_t width, uint32_t height, 122 uint32_t stride, uint32_t format, uint64_t producer_usage, 123 uint64_t consumer_usage) { 124 ALOGD_IF(TRACE, 125 "IonBuffer::Reset: handle=%p width=%u height=%u stride=%u format=%u " 126 "producer_usage=%" PRIx64 " consumer_usage=%" PRIx64, 127 handle, width, height, stride, format, producer_usage, 128 consumer_usage); 129 Import(handle, width, height, stride, format, producer_usage, consumer_usage); 130} 131 132int IonBuffer::Import(buffer_handle_t handle, uint32_t width, uint32_t height, 133 uint32_t stride, uint32_t format, uint32_t usage) { 134 return Import(handle, width, height, stride, format, usage, usage); 135} 136 137int IonBuffer::Import(buffer_handle_t handle, uint32_t width, uint32_t height, 138 uint32_t stride, uint32_t format, uint64_t producer_usage, 139 uint64_t consumer_usage) { 140 ATRACE_NAME("IonBuffer::Import1"); 141 ALOGD_IF( 142 TRACE, 143 "IonBuffer::Import: handle=%p width=%u height=%u stride=%u format=%u " 144 "producer_usage=%" PRIx64 " consumer_usage=%" PRIx64, 145 handle, width, height, stride, format, producer_usage, consumer_usage); 146 FreeHandle(); 147 sp<GraphicBuffer> buffer = new GraphicBuffer( 148 handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE, width, height, format, 149 kDefaultGraphicBufferLayerCount, producer_usage, consumer_usage, stride); 150 if (buffer->initCheck() != OK) { 151 ALOGE("IonBuffer::Import: Failed to import buffer"); 152 return -EINVAL; 153 } else { 154 buffer_ = buffer; 155 producer_usage_ = producer_usage; 156 consumer_usage_ = consumer_usage; 157 return 0; 158 } 159} 160 161int IonBuffer::Import(const int* fd_array, int fd_count, const int* int_array, 162 int int_count, uint32_t width, uint32_t height, 163 uint32_t stride, uint32_t format, uint32_t usage) { 164 return Import(fd_array, fd_count, int_array, int_count, width, height, stride, 165 format, usage, usage); 166} 167 168int IonBuffer::Import(const int* fd_array, int fd_count, const int* int_array, 169 int int_count, uint32_t width, uint32_t height, 170 uint32_t stride, uint32_t format, uint64_t producer_usage, 171 uint64_t consumer_usage) { 172 ATRACE_NAME("IonBuffer::Import2"); 173 ALOGD_IF(TRACE, 174 "IonBuffer::Import: fd_count=%d int_count=%d width=%u height=%u " 175 "stride=%u format=%u producer_usage=%" PRIx64 176 " consumer_usage=%" PRIx64, 177 fd_count, int_count, width, height, stride, format, producer_usage, 178 consumer_usage); 179 180 if (fd_count < 0 || int_count < 0) { 181 ALOGE("IonBuffer::Import: invalid arguments."); 182 return -EINVAL; 183 } 184 185 native_handle_t* handle = native_handle_create(fd_count, int_count); 186 if (!handle) { 187 ALOGE("IonBuffer::Import: failed to create new native handle."); 188 return -ENOMEM; 189 } 190 191 // Copy fd_array into the first part of handle->data and int_array right 192 // after it. 193 memcpy(handle->data, fd_array, sizeof(int) * fd_count); 194 memcpy(handle->data + fd_count, int_array, sizeof(int) * int_count); 195 196 const int ret = Import(handle, width, height, stride, format, producer_usage, 197 consumer_usage); 198 if (ret < 0) { 199 ALOGE("IonBuffer::Import: failed to import raw native handle: %s", 200 strerror(-ret)); 201 native_handle_close(handle); 202 native_handle_delete(handle); 203 } 204 205 return ret; 206} 207 208int IonBuffer::Duplicate(const IonBuffer* other) { 209 if (!other->handle()) 210 return -EINVAL; 211 212 const int fd_count = other->handle()->numFds; 213 const int int_count = other->handle()->numInts; 214 215 if (fd_count < 0 || int_count < 0) 216 return -EINVAL; 217 218 native_handle_t* handle = native_handle_create(fd_count, int_count); 219 if (!handle) { 220 ALOGE("IonBuffer::Duplicate: Failed to create new native handle."); 221 return -ENOMEM; 222 } 223 224 // Duplicate the file descriptors from the other native handle. 225 for (int i = 0; i < fd_count; i++) 226 handle->data[i] = dup(other->handle()->data[i]); 227 228 // Copy the ints after the file descriptors. 229 memcpy(handle->data + fd_count, other->handle()->data + fd_count, 230 sizeof(int) * int_count); 231 232 const int ret = 233 Import(handle, other->width(), other->height(), other->stride(), 234 other->format(), other->producer_usage(), other->consumer_usage()); 235 if (ret < 0) { 236 ALOGE("IonBuffer::Duplicate: Failed to import duplicate native handle: %s", 237 strerror(-ret)); 238 native_handle_close(handle); 239 native_handle_delete(handle); 240 } 241 242 return ret; 243} 244 245int IonBuffer::Lock(uint32_t usage, int x, int y, int width, int height, 246 void** address) { 247 ATRACE_NAME("IonBuffer::Lock"); 248 ALOGD_IF(TRACE, 249 "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d " 250 "address=%p", 251 handle(), usage, x, y, width, height, address); 252 253 status_t err = 254 buffer_->lock(usage, Rect(x, y, x + width, y + height), address); 255 if (err != NO_ERROR) 256 return -EINVAL; 257 else 258 return 0; 259} 260 261int IonBuffer::LockYUV(uint32_t usage, int x, int y, int width, int height, 262 struct android_ycbcr* yuv) { 263 ATRACE_NAME("IonBuffer::LockYUV"); 264 ALOGD_IF(TRACE, 265 "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d", 266 handle(), usage, x, y, width, height); 267 268 status_t err = 269 buffer_->lockYCbCr(usage, Rect(x, y, x + width, y + height), yuv); 270 if (err != NO_ERROR) 271 return -EINVAL; 272 else 273 return 0; 274} 275 276int IonBuffer::Unlock() { 277 ATRACE_NAME("IonBuffer::Unlock"); 278 ALOGD_IF(TRACE, "IonBuffer::Unlock: handle=%p", handle()); 279 280 status_t err = buffer_->unlock(); 281 if (err != NO_ERROR) 282 return -EINVAL; 283 else 284 return 0; 285} 286} // namespace dvr 287} // namespace android 288