| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2017 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #define LOG_TAG "AHardwareBuffer" | 
|  | 18 |  | 
|  | 19 | #include <android/hardware_buffer.h> | 
|  | 20 |  | 
|  | 21 | #include <errno.h> | 
|  | 22 | #include <sys/socket.h> | 
|  | 23 | #include <memory> | 
|  | 24 |  | 
|  | 25 | #include <cutils/native_handle.h> | 
|  | 26 | #include <log/log.h> | 
|  | 27 | #include <utils/StrongPointer.h> | 
|  | 28 | #include <ui/GraphicBuffer.h> | 
|  | 29 | #include <system/graphics.h> | 
|  | 30 | #include <hardware/gralloc1.h> | 
|  | 31 |  | 
|  | 32 | #include <private/android/AHardwareBufferHelpers.h> | 
|  | 33 |  | 
|  | 34 |  | 
|  | 35 | static constexpr int kDataBufferSize = 64 * sizeof(int);  // 64 ints | 
|  | 36 |  | 
|  | 37 | using namespace android; | 
|  | 38 |  | 
|  | 39 | // ---------------------------------------------------------------------------- | 
|  | 40 | // Public functions | 
|  | 41 | // ---------------------------------------------------------------------------- | 
|  | 42 |  | 
|  | 43 | int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer) { | 
|  | 44 | if (!outBuffer || !desc) | 
|  | 45 | return BAD_VALUE; | 
|  | 46 |  | 
|  | 47 | int format = AHardwareBuffer_convertToPixelFormat(desc->format); | 
|  | 48 | if (format == 0) { | 
|  | 49 | ALOGE("Invalid pixel format %u", desc->format); | 
|  | 50 | return BAD_VALUE; | 
|  | 51 | } | 
|  | 52 |  | 
|  | 53 | if (desc->format == AHARDWAREBUFFER_FORMAT_BLOB && desc->height != 1) { | 
|  | 54 | ALOGE("Height must be 1 when using the AHARDWAREBUFFER_FORMAT_BLOB format"); | 
|  | 55 | return BAD_VALUE; | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | uint64_t producerUsage = 0; | 
|  | 59 | uint64_t consumerUsage = 0; | 
|  | 60 | AHardwareBuffer_convertToGrallocUsageBits(desc->usage0, &producerUsage, &consumerUsage); | 
|  | 61 |  | 
|  | 62 | sp<GraphicBuffer> gbuffer(new GraphicBuffer( | 
|  | 63 | desc->width, desc->height, format, desc->layers, producerUsage, consumerUsage, | 
|  | 64 | std::string("AHardwareBuffer pid [") + std::to_string(getpid()) + "]")); | 
|  | 65 |  | 
|  | 66 | status_t err = gbuffer->initCheck(); | 
|  | 67 | if (err != 0 || gbuffer->handle == 0) { | 
|  | 68 | if (err == NO_MEMORY) { | 
|  | 69 | GraphicBuffer::dumpAllocationsToSystemLog(); | 
|  | 70 | } | 
|  | 71 | ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) failed (%s), handle=%p", | 
|  | 72 | desc->width, desc->height, desc->layers, strerror(-err), gbuffer->handle); | 
|  | 73 | return err; | 
|  | 74 | } | 
|  | 75 |  | 
|  | 76 | *outBuffer = AHardwareBuffer_from_GraphicBuffer(gbuffer.get()); | 
|  | 77 |  | 
|  | 78 | // Ensure the buffer doesn't get destroyed when the sp<> goes away. | 
|  | 79 | AHardwareBuffer_acquire(*outBuffer); | 
|  | 80 | return NO_ERROR; | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | void AHardwareBuffer_acquire(AHardwareBuffer* buffer) { | 
|  | 84 | AHardwareBuffer_to_GraphicBuffer(buffer)->incStrong((void*)AHardwareBuffer_acquire); | 
|  | 85 | } | 
|  | 86 |  | 
|  | 87 | void AHardwareBuffer_release(AHardwareBuffer* buffer) { | 
|  | 88 | AHardwareBuffer_to_GraphicBuffer(buffer)->decStrong((void*)AHardwareBuffer_release); | 
|  | 89 | } | 
|  | 90 |  | 
|  | 91 | void AHardwareBuffer_describe(const AHardwareBuffer* buffer, | 
|  | 92 | AHardwareBuffer_Desc* outDesc) { | 
|  | 93 | if (!buffer || !outDesc) return; | 
|  | 94 |  | 
|  | 95 | const GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer); | 
|  | 96 |  | 
|  | 97 | outDesc->width = gbuffer->getWidth(); | 
|  | 98 | outDesc->height = gbuffer->getHeight(); | 
|  | 99 | outDesc->layers = gbuffer->getLayerCount(); | 
|  | 100 | outDesc->usage0 = AHardwareBuffer_convertFromGrallocUsageBits( | 
|  | 101 | gbuffer->getUsage(), gbuffer->getUsage()); | 
|  | 102 | outDesc->usage1 = 0; | 
|  | 103 | outDesc->format = AHardwareBuffer_convertFromPixelFormat( | 
|  | 104 | static_cast<uint32_t>(gbuffer->getPixelFormat())); | 
|  | 105 | } | 
|  | 106 |  | 
|  | 107 | int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage0, | 
|  | 108 | int32_t fence, const ARect* rect, void** outVirtualAddress) { | 
|  | 109 | if (!buffer) return BAD_VALUE; | 
|  | 110 |  | 
|  | 111 | if (usage0 & ~(AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN | | 
|  | 112 | AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN)) { | 
|  | 113 | ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only " | 
|  | 114 | " AHARDWAREBUFFER_USAGE0_CPU_* flags are allowed"); | 
|  | 115 | return BAD_VALUE; | 
|  | 116 | } | 
|  | 117 |  | 
|  | 118 | uint64_t producerUsage = 0; | 
|  | 119 | uint64_t consumerUsage = 0; | 
|  | 120 | AHardwareBuffer_convertToGrallocUsageBits(usage0, &producerUsage, &consumerUsage); | 
|  | 121 | GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer); | 
|  | 122 | Rect bounds; | 
|  | 123 | if (!rect) { | 
|  | 124 | bounds.set(Rect(gBuffer->getWidth(), gBuffer->getHeight())); | 
|  | 125 | } else { | 
|  | 126 | bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom)); | 
|  | 127 | } | 
|  | 128 | return gBuffer->lockAsync(producerUsage, consumerUsage, bounds, | 
|  | 129 | outVirtualAddress, fence); | 
|  | 130 | } | 
|  | 131 |  | 
|  | 132 | int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) { | 
|  | 133 | if (!buffer) return BAD_VALUE; | 
|  | 134 |  | 
|  | 135 | GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer); | 
|  | 136 | return gBuffer->unlockAsync(fence); | 
|  | 137 | } | 
|  | 138 |  | 
|  | 139 | int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, | 
|  | 140 | int socketFd) { | 
|  | 141 | if (!buffer) return BAD_VALUE; | 
|  | 142 | const GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer); | 
|  | 143 |  | 
|  | 144 | size_t flattenedSize = gBuffer->getFlattenedSize(); | 
|  | 145 | size_t fdCount = gBuffer->getFdCount(); | 
|  | 146 |  | 
|  | 147 | std::unique_ptr<uint8_t[]> data(new uint8_t[flattenedSize]); | 
|  | 148 | std::unique_ptr<int[]> fds(new int[fdCount]); | 
|  | 149 |  | 
|  | 150 | // Make copies of needed items since flatten modifies them, and we don't | 
|  | 151 | // want to send anything if there's an error during flatten. | 
|  | 152 | size_t flattenedSizeCopy = flattenedSize; | 
|  | 153 | size_t fdCountCopy = fdCount; | 
|  | 154 | void* dataStart = data.get(); | 
|  | 155 | int* fdsStart = fds.get(); | 
|  | 156 | status_t err = gBuffer->flatten(dataStart, flattenedSizeCopy, fdsStart, | 
|  | 157 | fdCountCopy); | 
|  | 158 | if (err != NO_ERROR) { | 
|  | 159 | return err; | 
|  | 160 | } | 
|  | 161 |  | 
|  | 162 | struct iovec iov[1]; | 
|  | 163 | iov[0].iov_base = data.get(); | 
|  | 164 | iov[0].iov_len = flattenedSize; | 
|  | 165 |  | 
|  | 166 | char buf[CMSG_SPACE(kDataBufferSize)]; | 
|  | 167 | struct msghdr msg = { | 
|  | 168 | .msg_control = buf, | 
|  | 169 | .msg_controllen = sizeof(buf), | 
|  | 170 | .msg_iov = &iov[0], | 
|  | 171 | .msg_iovlen = 1, | 
|  | 172 | }; | 
|  | 173 |  | 
|  | 174 | struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); | 
|  | 175 | cmsg->cmsg_level = SOL_SOCKET; | 
|  | 176 | cmsg->cmsg_type = SCM_RIGHTS; | 
|  | 177 | cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount); | 
|  | 178 | int* fdData = reinterpret_cast<int*>(CMSG_DATA(cmsg)); | 
|  | 179 | memcpy(fdData, fds.get(), sizeof(int) * fdCount); | 
|  | 180 | msg.msg_controllen = cmsg->cmsg_len; | 
|  | 181 |  | 
|  | 182 | int result = sendmsg(socketFd, &msg, 0); | 
|  | 183 | if (result <= 0) { | 
|  | 184 | ALOGE("Error writing AHardwareBuffer to socket: error %#x (%s)", | 
|  | 185 | result, strerror(errno)); | 
|  | 186 | return result; | 
|  | 187 | } | 
|  | 188 | return NO_ERROR; | 
|  | 189 | } | 
|  | 190 |  | 
|  | 191 | int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, | 
|  | 192 | AHardwareBuffer** outBuffer) { | 
|  | 193 | if (!outBuffer) return BAD_VALUE; | 
|  | 194 |  | 
|  | 195 | char dataBuf[CMSG_SPACE(kDataBufferSize)]; | 
|  | 196 | char fdBuf[CMSG_SPACE(kDataBufferSize)]; | 
|  | 197 | struct iovec iov[1]; | 
|  | 198 | iov[0].iov_base = dataBuf; | 
|  | 199 | iov[0].iov_len = sizeof(dataBuf); | 
|  | 200 |  | 
|  | 201 | struct msghdr msg = { | 
|  | 202 | .msg_control = fdBuf, | 
|  | 203 | .msg_controllen = sizeof(fdBuf), | 
|  | 204 | .msg_iov = &iov[0], | 
|  | 205 | .msg_iovlen = 1, | 
|  | 206 | }; | 
|  | 207 |  | 
|  | 208 | int result = recvmsg(socketFd, &msg, 0); | 
|  | 209 | if (result <= 0) { | 
|  | 210 | ALOGE("Error reading AHardwareBuffer from socket: error %#x (%s)", | 
|  | 211 | result, strerror(errno)); | 
|  | 212 | return result; | 
|  | 213 | } | 
|  | 214 |  | 
|  | 215 | if (msg.msg_iovlen != 1) { | 
|  | 216 | ALOGE("Error reading AHardwareBuffer from socket: bad data length"); | 
|  | 217 | return INVALID_OPERATION; | 
|  | 218 | } | 
|  | 219 |  | 
|  | 220 | if (msg.msg_controllen % sizeof(int) != 0) { | 
|  | 221 | ALOGE("Error reading AHardwareBuffer from socket: bad fd length"); | 
|  | 222 | return INVALID_OPERATION; | 
|  | 223 | } | 
|  | 224 |  | 
|  | 225 | size_t dataLen = msg.msg_iov[0].iov_len; | 
|  | 226 | const void* data = static_cast<const void*>(msg.msg_iov[0].iov_base); | 
|  | 227 | if (!data) { | 
|  | 228 | ALOGE("Error reading AHardwareBuffer from socket: no buffer data"); | 
|  | 229 | return INVALID_OPERATION; | 
|  | 230 | } | 
|  | 231 |  | 
|  | 232 | struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); | 
|  | 233 | if (!cmsg) { | 
|  | 234 | ALOGE("Error reading AHardwareBuffer from socket: no fd header"); | 
|  | 235 | return INVALID_OPERATION; | 
|  | 236 | } | 
|  | 237 |  | 
|  | 238 | size_t fdCount = msg.msg_controllen >> 2; | 
|  | 239 | const int* fdData = reinterpret_cast<const int*>(CMSG_DATA(cmsg)); | 
|  | 240 | if (!fdData) { | 
|  | 241 | ALOGE("Error reading AHardwareBuffer from socket: no fd data"); | 
|  | 242 | return INVALID_OPERATION; | 
|  | 243 | } | 
|  | 244 |  | 
|  | 245 | GraphicBuffer* gBuffer = new GraphicBuffer(); | 
|  | 246 | status_t err = gBuffer->unflatten(data, dataLen, fdData, fdCount); | 
|  | 247 | if (err != NO_ERROR) { | 
|  | 248 | return err; | 
|  | 249 | } | 
|  | 250 | *outBuffer = AHardwareBuffer_from_GraphicBuffer(gBuffer); | 
|  | 251 | // Ensure the buffer has a positive ref-count. | 
|  | 252 | AHardwareBuffer_acquire(*outBuffer); | 
|  | 253 |  | 
|  | 254 | return NO_ERROR; | 
|  | 255 | } | 
|  | 256 |  | 
|  | 257 | const struct native_handle* AHardwareBuffer_getNativeHandle( | 
|  | 258 | const AHardwareBuffer* buffer) { | 
|  | 259 | if (!buffer) return nullptr; | 
|  | 260 | const GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer); | 
|  | 261 | return gbuffer->handle; | 
|  | 262 | } | 
|  | 263 |  | 
|  | 264 |  | 
|  | 265 | // ---------------------------------------------------------------------------- | 
|  | 266 | // Helpers implementation | 
|  | 267 | // ---------------------------------------------------------------------------- | 
|  | 268 |  | 
|  | 269 | namespace android { | 
|  | 270 |  | 
|  | 271 | static inline bool containsBits(uint64_t mask, uint64_t bitsToCheck) { | 
|  | 272 | return (mask & bitsToCheck) == bitsToCheck; | 
|  | 273 | } | 
|  | 274 |  | 
|  | 275 | uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format) { | 
|  | 276 | switch (format) { | 
|  | 277 | case HAL_PIXEL_FORMAT_RGBA_8888:    return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; | 
|  | 278 | case HAL_PIXEL_FORMAT_RGBX_8888:    return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM; | 
|  | 279 | case HAL_PIXEL_FORMAT_RGB_565:      return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM; | 
|  | 280 | case HAL_PIXEL_FORMAT_RGB_888:      return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM; | 
|  | 281 | case HAL_PIXEL_FORMAT_RGBA_FP16:    return AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT; | 
|  | 282 | case HAL_PIXEL_FORMAT_RGBA_1010102: return AHARDWAREBUFFER_FORMAT_A2R10G10B10_UNORM_PACK32; | 
|  | 283 | case HAL_PIXEL_FORMAT_BLOB:         return AHARDWAREBUFFER_FORMAT_BLOB; | 
|  | 284 | default:ALOGE("Unknown pixel format %u", format); | 
|  | 285 | return 0; | 
|  | 286 | } | 
|  | 287 | } | 
|  | 288 |  | 
|  | 289 | uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format) { | 
|  | 290 | switch (format) { | 
|  | 291 | case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:         return HAL_PIXEL_FORMAT_RGBA_8888; | 
|  | 292 | case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:         return HAL_PIXEL_FORMAT_RGBX_8888; | 
|  | 293 | case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:           return HAL_PIXEL_FORMAT_RGB_565; | 
|  | 294 | case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:           return HAL_PIXEL_FORMAT_RGB_888; | 
|  | 295 | case AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT:    return HAL_PIXEL_FORMAT_RGBA_FP16; | 
|  | 296 | case AHARDWAREBUFFER_FORMAT_A2R10G10B10_UNORM_PACK32: return HAL_PIXEL_FORMAT_RGBA_1010102; | 
|  | 297 | case AHARDWAREBUFFER_FORMAT_BLOB:                   return HAL_PIXEL_FORMAT_BLOB; | 
|  | 298 | default:ALOGE("Unknown AHardwareBuffer format %u", format); | 
|  | 299 | return 0; | 
|  | 300 | } | 
|  | 301 | } | 
|  | 302 |  | 
|  | 303 | void AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage, uint64_t* outProducerUsage, | 
|  | 304 | uint64_t* outConsumerUsage) { | 
|  | 305 | *outProducerUsage = 0; | 
|  | 306 | *outConsumerUsage = 0; | 
|  | 307 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_READ)) | 
|  | 308 | *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ; | 
|  | 309 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN)) | 
|  | 310 | *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN; | 
|  | 311 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_WRITE)) | 
|  | 312 | *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE; | 
|  | 313 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN)) | 
|  | 314 | *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN; | 
|  | 315 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE)) | 
|  | 316 | *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE; | 
|  | 317 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT)) | 
|  | 318 | *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET; | 
|  | 319 | // Not sure what this should be. | 
|  | 320 | //if (containsBits(usage0, AHARDWAREBUFFER_USAGE0_GPU_CUBEMAP)) bits |= 0; | 
|  | 321 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER)) | 
|  | 322 | *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER; | 
|  | 323 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE)) | 
|  | 324 | *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER; | 
|  | 325 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT)) | 
|  | 326 | *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_PROTECTED; | 
|  | 327 | if (containsBits(usage, AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA)) | 
|  | 328 | *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA; | 
|  | 329 | } | 
|  | 330 |  | 
|  | 331 | uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t producerUsage, uint64_t consumerUsage) { | 
|  | 332 | uint64_t bits = 0; | 
|  | 333 | if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_CPU_READ)) | 
|  | 334 | bits |= AHARDWAREBUFFER_USAGE0_CPU_READ; | 
|  | 335 | if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN)) | 
|  | 336 | bits |= AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN; | 
|  | 337 | if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) | 
|  | 338 | bits |= AHARDWAREBUFFER_USAGE0_CPU_WRITE; | 
|  | 339 | if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) | 
|  | 340 | bits |= AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN; | 
|  | 341 | if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE)) | 
|  | 342 | bits |= AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE; | 
|  | 343 | if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) | 
|  | 344 | bits |= AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT; | 
|  | 345 | if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER)) | 
|  | 346 | bits |= AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER; | 
|  | 347 | if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER)) | 
|  | 348 | bits |= AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE; | 
|  | 349 | if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_PROTECTED)) | 
|  | 350 | bits |= AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT; | 
|  | 351 | if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA)) | 
|  | 352 | bits |= AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA; | 
|  | 353 |  | 
|  | 354 | return bits; | 
|  | 355 | } | 
|  | 356 |  | 
|  | 357 | const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) { | 
|  | 358 | return reinterpret_cast<const GraphicBuffer*>(buffer); | 
|  | 359 | } | 
|  | 360 |  | 
|  | 361 | GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(AHardwareBuffer* buffer) { | 
|  | 362 | return reinterpret_cast<GraphicBuffer*>(buffer); | 
|  | 363 | } | 
|  | 364 |  | 
|  | 365 | AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer) { | 
|  | 366 | return reinterpret_cast<AHardwareBuffer*>(buffer); | 
|  | 367 | } | 
|  | 368 |  | 
|  | 369 | } // namespace android |