| 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 |  | 
| Jesse Hall | 1ee859f | 2017-04-17 08:52:32 -0700 | [diff] [blame] | 19 | #include <vndk/hardware_buffer.h> | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 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> | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 30 |  | 
 | 31 | #include <private/android/AHardwareBufferHelpers.h> | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 32 | #include <android/hardware/graphics/common/1.0/types.h> | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 33 |  | 
 | 34 |  | 
| Craig Donner | 1b1d300 | 2017-04-12 18:38:07 -0700 | [diff] [blame] | 35 | static constexpr int kFdBufferSize = 128 * sizeof(int);  // 128 ints | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 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 |  | 
| Mathias Agopian | 07b920e | 2017-04-25 17:38:08 -0700 | [diff] [blame] | 53 |     if (desc->rfu0 != 0 || desc->rfu1 != 0) { | 
 | 54 |         ALOGE("AHardwareBuffer_Desc::rfu fields must be 0"); | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 55 |         return BAD_VALUE; | 
 | 56 |     } | 
 | 57 |  | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 58 |     if (desc->format == AHARDWAREBUFFER_FORMAT_BLOB && desc->height != 1) { | 
 | 59 |         ALOGE("Height must be 1 when using the AHARDWAREBUFFER_FORMAT_BLOB format"); | 
 | 60 |         return BAD_VALUE; | 
 | 61 |     } | 
 | 62 |  | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 63 |     uint64_t usage =  AHardwareBuffer_convertToGrallocUsageBits(desc->usage); | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 64 |     sp<GraphicBuffer> gbuffer(new GraphicBuffer( | 
| Chris Forbes | d410630 | 2017-04-20 12:43:04 -0700 | [diff] [blame] | 65 |             desc->width, desc->height, format, desc->layers, usage, | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 66 |             std::string("AHardwareBuffer pid [") + std::to_string(getpid()) + "]")); | 
 | 67 |  | 
 | 68 |     status_t err = gbuffer->initCheck(); | 
 | 69 |     if (err != 0 || gbuffer->handle == 0) { | 
 | 70 |         if (err == NO_MEMORY) { | 
 | 71 |             GraphicBuffer::dumpAllocationsToSystemLog(); | 
 | 72 |         } | 
| Mathias Agopian | 0556d79 | 2017-03-22 15:49:32 -0700 | [diff] [blame] | 73 |         ALOGE("GraphicBuffer(w=%u, h=%u, lc=%u) failed (%s), handle=%p", | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 74 |                 desc->width, desc->height, desc->layers, strerror(-err), gbuffer->handle); | 
 | 75 |         return err; | 
 | 76 |     } | 
 | 77 |  | 
 | 78 |     *outBuffer = AHardwareBuffer_from_GraphicBuffer(gbuffer.get()); | 
 | 79 |  | 
 | 80 |     // Ensure the buffer doesn't get destroyed when the sp<> goes away. | 
 | 81 |     AHardwareBuffer_acquire(*outBuffer); | 
 | 82 |     return NO_ERROR; | 
 | 83 | } | 
 | 84 |  | 
 | 85 | void AHardwareBuffer_acquire(AHardwareBuffer* buffer) { | 
| Mathias Agopian | 000879a | 2017-03-20 18:07:26 -0700 | [diff] [blame] | 86 |     // incStrong/decStrong token must be the same, doesn't matter what it is | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 87 |     AHardwareBuffer_to_GraphicBuffer(buffer)->incStrong((void*)AHardwareBuffer_acquire); | 
 | 88 | } | 
 | 89 |  | 
 | 90 | void AHardwareBuffer_release(AHardwareBuffer* buffer) { | 
| Mathias Agopian | 000879a | 2017-03-20 18:07:26 -0700 | [diff] [blame] | 91 |     // incStrong/decStrong token must be the same, doesn't matter what it is | 
 | 92 |     AHardwareBuffer_to_GraphicBuffer(buffer)->decStrong((void*)AHardwareBuffer_acquire); | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 93 | } | 
 | 94 |  | 
 | 95 | void AHardwareBuffer_describe(const AHardwareBuffer* buffer, | 
 | 96 |         AHardwareBuffer_Desc* outDesc) { | 
 | 97 |     if (!buffer || !outDesc) return; | 
 | 98 |  | 
 | 99 |     const GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer); | 
 | 100 |  | 
 | 101 |     outDesc->width = gbuffer->getWidth(); | 
 | 102 |     outDesc->height = gbuffer->getHeight(); | 
 | 103 |     outDesc->layers = gbuffer->getLayerCount(); | 
| Mathias Agopian | 07b920e | 2017-04-25 17:38:08 -0700 | [diff] [blame] | 104 |     outDesc->format = AHardwareBuffer_convertFromPixelFormat(uint32_t(gbuffer->getPixelFormat())); | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 105 |     outDesc->usage = AHardwareBuffer_convertFromGrallocUsageBits(gbuffer->getUsage()); | 
| Mathias Agopian | 07b920e | 2017-04-25 17:38:08 -0700 | [diff] [blame] | 106 |     outDesc->stride = gbuffer->getStride(); | 
 | 107 |     outDesc->rfu0 = 0; | 
 | 108 |     outDesc->rfu1 = 0; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 109 | } | 
 | 110 |  | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 111 | int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage, | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 112 |         int32_t fence, const ARect* rect, void** outVirtualAddress) { | 
 | 113 |     if (!buffer) return BAD_VALUE; | 
 | 114 |  | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 115 |     if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK | | 
 | 116 |                   AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) { | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 117 |         ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only " | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 118 |                 " AHARDWAREBUFFER_USAGE_CPU_* flags are allowed"); | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 119 |         return BAD_VALUE; | 
 | 120 |     } | 
 | 121 |  | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 122 |     usage = AHardwareBuffer_convertToGrallocUsageBits(usage); | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 123 |     GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer); | 
 | 124 |     Rect bounds; | 
 | 125 |     if (!rect) { | 
 | 126 |         bounds.set(Rect(gBuffer->getWidth(), gBuffer->getHeight())); | 
 | 127 |     } else { | 
 | 128 |         bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom)); | 
 | 129 |     } | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 130 |     return gBuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence); | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 131 | } | 
 | 132 |  | 
 | 133 | int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) { | 
 | 134 |     if (!buffer) return BAD_VALUE; | 
 | 135 |  | 
 | 136 |     GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer); | 
 | 137 |     return gBuffer->unlockAsync(fence); | 
 | 138 | } | 
 | 139 |  | 
| Mathias Agopian | 000879a | 2017-03-20 18:07:26 -0700 | [diff] [blame] | 140 | int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) { | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 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 |  | 
| Craig Donner | 1b1d300 | 2017-04-12 18:38:07 -0700 | [diff] [blame] | 166 |     char buf[CMSG_SPACE(kFdBufferSize)]; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 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 |  | 
| Jesse Hall | 81d3197 | 2017-05-15 14:14:01 -0700 | [diff] [blame] | 182 |     int result; | 
 | 183 |     do { | 
 | 184 |         result = sendmsg(socketFd, &msg, 0); | 
 | 185 |     } while (result == -1 && errno == EINTR); | 
 | 186 |     if (result == -1) { | 
 | 187 |         result = errno; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 188 |         ALOGE("Error writing AHardwareBuffer to socket: error %#x (%s)", | 
| Jesse Hall | 81d3197 | 2017-05-15 14:14:01 -0700 | [diff] [blame] | 189 |                 result, strerror(result)); | 
 | 190 |         return -result; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 191 |     } | 
| Jesse Hall | 81d3197 | 2017-05-15 14:14:01 -0700 | [diff] [blame] | 192 |  | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 193 |     return NO_ERROR; | 
 | 194 | } | 
 | 195 |  | 
| Mathias Agopian | 000879a | 2017-03-20 18:07:26 -0700 | [diff] [blame] | 196 | int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer) { | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 197 |     if (!outBuffer) return BAD_VALUE; | 
 | 198 |  | 
| Craig Donner | 1b1d300 | 2017-04-12 18:38:07 -0700 | [diff] [blame] | 199 |     static constexpr int kMessageBufferSize = 4096 * sizeof(int); | 
 | 200 |  | 
 | 201 |     std::unique_ptr<char[]> dataBuf(new char[kMessageBufferSize]); | 
 | 202 |     char fdBuf[CMSG_SPACE(kFdBufferSize)]; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 203 |     struct iovec iov[1]; | 
| Craig Donner | 1b1d300 | 2017-04-12 18:38:07 -0700 | [diff] [blame] | 204 |     iov[0].iov_base = dataBuf.get(); | 
 | 205 |     iov[0].iov_len = kMessageBufferSize; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 206 |  | 
 | 207 |     struct msghdr msg = { | 
 | 208 |             .msg_control = fdBuf, | 
 | 209 |             .msg_controllen = sizeof(fdBuf), | 
 | 210 |             .msg_iov = &iov[0], | 
 | 211 |             .msg_iovlen = 1, | 
 | 212 |     }; | 
 | 213 |  | 
| Jesse Hall | 81d3197 | 2017-05-15 14:14:01 -0700 | [diff] [blame] | 214 |     int result; | 
 | 215 |     do { | 
 | 216 |         result = recvmsg(socketFd, &msg, 0); | 
 | 217 |     } while (result == -1 && errno == EINTR); | 
 | 218 |     if (result == -1) { | 
 | 219 |         result = errno; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 220 |         ALOGE("Error reading AHardwareBuffer from socket: error %#x (%s)", | 
| Jesse Hall | 81d3197 | 2017-05-15 14:14:01 -0700 | [diff] [blame] | 221 |                 result, strerror(result)); | 
 | 222 |         return -result; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 223 |     } | 
 | 224 |  | 
 | 225 |     if (msg.msg_iovlen != 1) { | 
 | 226 |         ALOGE("Error reading AHardwareBuffer from socket: bad data length"); | 
 | 227 |         return INVALID_OPERATION; | 
 | 228 |     } | 
 | 229 |  | 
 | 230 |     if (msg.msg_controllen % sizeof(int) != 0) { | 
 | 231 |         ALOGE("Error reading AHardwareBuffer from socket: bad fd length"); | 
 | 232 |         return INVALID_OPERATION; | 
 | 233 |     } | 
 | 234 |  | 
 | 235 |     size_t dataLen = msg.msg_iov[0].iov_len; | 
 | 236 |     const void* data = static_cast<const void*>(msg.msg_iov[0].iov_base); | 
 | 237 |     if (!data) { | 
 | 238 |         ALOGE("Error reading AHardwareBuffer from socket: no buffer data"); | 
 | 239 |         return INVALID_OPERATION; | 
 | 240 |     } | 
 | 241 |  | 
 | 242 |     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); | 
 | 243 |     if (!cmsg) { | 
 | 244 |         ALOGE("Error reading AHardwareBuffer from socket: no fd header"); | 
 | 245 |         return INVALID_OPERATION; | 
 | 246 |     } | 
 | 247 |  | 
 | 248 |     size_t fdCount = msg.msg_controllen >> 2; | 
 | 249 |     const int* fdData = reinterpret_cast<const int*>(CMSG_DATA(cmsg)); | 
 | 250 |     if (!fdData) { | 
 | 251 |         ALOGE("Error reading AHardwareBuffer from socket: no fd data"); | 
 | 252 |         return INVALID_OPERATION; | 
 | 253 |     } | 
 | 254 |  | 
 | 255 |     GraphicBuffer* gBuffer = new GraphicBuffer(); | 
 | 256 |     status_t err = gBuffer->unflatten(data, dataLen, fdData, fdCount); | 
 | 257 |     if (err != NO_ERROR) { | 
 | 258 |         return err; | 
 | 259 |     } | 
 | 260 |     *outBuffer = AHardwareBuffer_from_GraphicBuffer(gBuffer); | 
 | 261 |     // Ensure the buffer has a positive ref-count. | 
 | 262 |     AHardwareBuffer_acquire(*outBuffer); | 
 | 263 |  | 
 | 264 |     return NO_ERROR; | 
 | 265 | } | 
 | 266 |  | 
| Jesse Hall | 1ee859f | 2017-04-17 08:52:32 -0700 | [diff] [blame] | 267 |  | 
 | 268 | // ---------------------------------------------------------------------------- | 
 | 269 | // VNDK functions | 
 | 270 | // ---------------------------------------------------------------------------- | 
 | 271 |  | 
 | 272 | const native_handle_t* AHardwareBuffer_getNativeHandle( | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 273 |         const AHardwareBuffer* buffer) { | 
 | 274 |     if (!buffer) return nullptr; | 
 | 275 |     const GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer); | 
 | 276 |     return gbuffer->handle; | 
 | 277 | } | 
 | 278 |  | 
 | 279 |  | 
 | 280 | // ---------------------------------------------------------------------------- | 
 | 281 | // Helpers implementation | 
 | 282 | // ---------------------------------------------------------------------------- | 
 | 283 |  | 
 | 284 | namespace android { | 
 | 285 |  | 
| Craig Donner | a5a719e | 2017-02-24 16:02:08 -0800 | [diff] [blame] | 286 | // A 1:1 mapping of AHardwaqreBuffer bitmasks to gralloc1 bitmasks. | 
 | 287 | struct UsageMaskMapping { | 
 | 288 |     uint64_t hardwareBufferMask; | 
 | 289 |     uint64_t grallocMask; | 
 | 290 | }; | 
 | 291 |  | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 292 | static inline bool containsBits(uint64_t mask, uint64_t bitsToCheck) { | 
| Craig Donner | a5a719e | 2017-02-24 16:02:08 -0800 | [diff] [blame] | 293 |     return (mask & bitsToCheck) == bitsToCheck && bitsToCheck; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 294 | } | 
 | 295 |  | 
 | 296 | uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format) { | 
 | 297 |     switch (format) { | 
 | 298 |         case HAL_PIXEL_FORMAT_RGBA_8888:    return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; | 
 | 299 |         case HAL_PIXEL_FORMAT_RGBX_8888:    return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM; | 
 | 300 |         case HAL_PIXEL_FORMAT_RGB_565:      return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM; | 
 | 301 |         case HAL_PIXEL_FORMAT_RGB_888:      return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM; | 
| Jesse Hall | 577aa75 | 2017-04-19 15:43:02 -0700 | [diff] [blame] | 302 |         case HAL_PIXEL_FORMAT_RGBA_FP16:    return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT; | 
 | 303 |         case HAL_PIXEL_FORMAT_RGBA_1010102: return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 304 |         case HAL_PIXEL_FORMAT_BLOB:         return AHARDWAREBUFFER_FORMAT_BLOB; | 
 | 305 |         default:ALOGE("Unknown pixel format %u", format); | 
 | 306 |             return 0; | 
 | 307 |     } | 
 | 308 | } | 
 | 309 |  | 
 | 310 | uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format) { | 
 | 311 |     switch (format) { | 
 | 312 |         case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:         return HAL_PIXEL_FORMAT_RGBA_8888; | 
 | 313 |         case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:         return HAL_PIXEL_FORMAT_RGBX_8888; | 
 | 314 |         case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:           return HAL_PIXEL_FORMAT_RGB_565; | 
 | 315 |         case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:           return HAL_PIXEL_FORMAT_RGB_888; | 
| Jesse Hall | 577aa75 | 2017-04-19 15:43:02 -0700 | [diff] [blame] | 316 |         case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:     return HAL_PIXEL_FORMAT_RGBA_FP16; | 
 | 317 |         case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:      return HAL_PIXEL_FORMAT_RGBA_1010102; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 318 |         case AHARDWAREBUFFER_FORMAT_BLOB:                   return HAL_PIXEL_FORMAT_BLOB; | 
 | 319 |         default:ALOGE("Unknown AHardwareBuffer format %u", format); | 
 | 320 |             return 0; | 
 | 321 |     } | 
 | 322 | } | 
 | 323 |  | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 324 | uint64_t AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage) { | 
 | 325 |     using android::hardware::graphics::common::V1_0::BufferUsage; | 
 | 326 |     static_assert(AHARDWAREBUFFER_USAGE_CPU_READ_NEVER == (uint64_t)BufferUsage::CPU_READ_NEVER, | 
 | 327 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 328 |     static_assert(AHARDWAREBUFFER_USAGE_CPU_READ_RARELY == (uint64_t)BufferUsage::CPU_READ_RARELY, | 
 | 329 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 330 |     static_assert(AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN == (uint64_t)BufferUsage::CPU_READ_OFTEN, | 
 | 331 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 332 |     static_assert(AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER == (uint64_t)BufferUsage::CPU_WRITE_NEVER, | 
 | 333 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 334 |     static_assert(AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY == (uint64_t)BufferUsage::CPU_WRITE_RARELY, | 
 | 335 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 336 |     static_assert(AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN == (uint64_t)BufferUsage::CPU_WRITE_OFTEN, | 
 | 337 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 338 |     static_assert(AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE == (uint64_t)BufferUsage::GPU_TEXTURE, | 
 | 339 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 340 |     static_assert(AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT == (uint64_t)BufferUsage::GPU_RENDER_TARGET, | 
 | 341 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 342 |     static_assert(AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT == (uint64_t)BufferUsage::PROTECTED, | 
 | 343 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 344 |     static_assert(AHARDWAREBUFFER_USAGE_VIDEO_ENCODE == (uint64_t)BufferUsage::VIDEO_ENCODER, | 
 | 345 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 346 |     static_assert(AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER == (uint64_t)BufferUsage::GPU_DATA_BUFFER, | 
 | 347 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 348 |     static_assert(AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA == (uint64_t)BufferUsage::SENSOR_DIRECT_DATA, | 
 | 349 |             "gralloc and AHardwareBuffer flags don't match"); | 
 | 350 |     return usage; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 351 | } | 
 | 352 |  | 
| Mathias Agopian | 2c38b56 | 2017-04-20 16:35:39 -0700 | [diff] [blame] | 353 | uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t usage) { | 
 | 354 |     return usage; | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 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 |  | 
| Mathias Agopian | 6196340 | 2017-02-24 16:38:15 -0800 | [diff] [blame] | 365 | const ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(const AHardwareBuffer* buffer) { | 
 | 366 |     return AHardwareBuffer_to_GraphicBuffer(buffer)->getNativeBuffer(); | 
 | 367 | } | 
 | 368 |  | 
 | 369 | ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(AHardwareBuffer* buffer) { | 
 | 370 |     return AHardwareBuffer_to_GraphicBuffer(buffer)->getNativeBuffer(); | 
 | 371 | } | 
 | 372 |  | 
| Mathias Agopian | 89ed4c8 | 2017-02-09 18:48:34 -0800 | [diff] [blame] | 373 | AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer) { | 
 | 374 |     return reinterpret_cast<AHardwareBuffer*>(buffer); | 
 | 375 | } | 
 | 376 |  | 
 | 377 | } // namespace android |