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 <vndk/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
31#include <private/android/AHardwareBufferHelpers.h>
32#include <android/hardware/graphics/common/1.0/types.h>
33
34
35static constexpr int kFdBufferSize = 128 * sizeof(int);  // 128 ints
36
37using namespace android;
38
39// ----------------------------------------------------------------------------
40// Public functions
41// ----------------------------------------------------------------------------
42
43int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer) {
44    if (!outBuffer || !desc)
45        return BAD_VALUE;
46
47    if (!AHardwareBuffer_isValidPixelFormat(desc->format)) {
48        ALOGE("Invalid AHardwareBuffer pixel format %u (%#x))", desc->format, desc->format);
49        return BAD_VALUE;
50    }
51
52    int format = AHardwareBuffer_convertToPixelFormat(desc->format);
53    if (desc->rfu0 != 0 || desc->rfu1 != 0) {
54        ALOGE("AHardwareBuffer_Desc::rfu fields must be 0");
55        return BAD_VALUE;
56    }
57
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
63    uint64_t usage =  AHardwareBuffer_convertToGrallocUsageBits(desc->usage);
64    sp<GraphicBuffer> gbuffer(new GraphicBuffer(
65            desc->width, desc->height, format, desc->layers, usage,
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        }
73        ALOGE("GraphicBuffer(w=%u, h=%u, lc=%u) failed (%s), handle=%p",
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
85void AHardwareBuffer_acquire(AHardwareBuffer* buffer) {
86    // incStrong/decStrong token must be the same, doesn't matter what it is
87    AHardwareBuffer_to_GraphicBuffer(buffer)->incStrong((void*)AHardwareBuffer_acquire);
88}
89
90void AHardwareBuffer_release(AHardwareBuffer* buffer) {
91    // incStrong/decStrong token must be the same, doesn't matter what it is
92    AHardwareBuffer_to_GraphicBuffer(buffer)->decStrong((void*)AHardwareBuffer_acquire);
93}
94
95void 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();
104    outDesc->format = AHardwareBuffer_convertFromPixelFormat(uint32_t(gbuffer->getPixelFormat()));
105    outDesc->usage = AHardwareBuffer_convertFromGrallocUsageBits(gbuffer->getUsage());
106    outDesc->stride = gbuffer->getStride();
107    outDesc->rfu0 = 0;
108    outDesc->rfu1 = 0;
109}
110
111int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage,
112        int32_t fence, const ARect* rect, void** outVirtualAddress) {
113    if (!buffer) return BAD_VALUE;
114
115    if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
116                  AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) {
117        ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only "
118                " AHARDWAREBUFFER_USAGE_CPU_* flags are allowed");
119        return BAD_VALUE;
120    }
121
122    usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
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    }
130    return gBuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence);
131}
132
133int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) {
134    if (!buffer) return BAD_VALUE;
135
136    GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
137    if (fence == nullptr)
138        return gBuffer->unlock();
139    else
140        return gBuffer->unlockAsync(fence);
141}
142
143int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) {
144    if (!buffer) return BAD_VALUE;
145    const GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
146
147    size_t flattenedSize = gBuffer->getFlattenedSize();
148    size_t fdCount = gBuffer->getFdCount();
149
150    std::unique_ptr<uint8_t[]> data(new uint8_t[flattenedSize]);
151    std::unique_ptr<int[]> fds(new int[fdCount]);
152
153    // Make copies of needed items since flatten modifies them, and we don't
154    // want to send anything if there's an error during flatten.
155    size_t flattenedSizeCopy = flattenedSize;
156    size_t fdCountCopy = fdCount;
157    void* dataStart = data.get();
158    int* fdsStart = fds.get();
159    status_t err = gBuffer->flatten(dataStart, flattenedSizeCopy, fdsStart,
160            fdCountCopy);
161    if (err != NO_ERROR) {
162        return err;
163    }
164
165    struct iovec iov[1];
166    iov[0].iov_base = data.get();
167    iov[0].iov_len = flattenedSize;
168
169    char buf[CMSG_SPACE(kFdBufferSize)];
170    struct msghdr msg = {
171            .msg_control = buf,
172            .msg_controllen = sizeof(buf),
173            .msg_iov = &iov[0],
174            .msg_iovlen = 1,
175    };
176
177    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
178    cmsg->cmsg_level = SOL_SOCKET;
179    cmsg->cmsg_type = SCM_RIGHTS;
180    cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount);
181    int* fdData = reinterpret_cast<int*>(CMSG_DATA(cmsg));
182    memcpy(fdData, fds.get(), sizeof(int) * fdCount);
183    msg.msg_controllen = cmsg->cmsg_len;
184
185    int result;
186    do {
187        result = sendmsg(socketFd, &msg, 0);
188    } while (result == -1 && errno == EINTR);
189    if (result == -1) {
190        result = errno;
191        ALOGE("Error writing AHardwareBuffer to socket: error %#x (%s)",
192                result, strerror(result));
193        return -result;
194    }
195
196    return NO_ERROR;
197}
198
199int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer) {
200    if (!outBuffer) return BAD_VALUE;
201
202    static constexpr int kMessageBufferSize = 4096 * sizeof(int);
203
204    std::unique_ptr<char[]> dataBuf(new char[kMessageBufferSize]);
205    char fdBuf[CMSG_SPACE(kFdBufferSize)];
206    struct iovec iov[1];
207    iov[0].iov_base = dataBuf.get();
208    iov[0].iov_len = kMessageBufferSize;
209
210    struct msghdr msg = {
211            .msg_control = fdBuf,
212            .msg_controllen = sizeof(fdBuf),
213            .msg_iov = &iov[0],
214            .msg_iovlen = 1,
215    };
216
217    int result;
218    do {
219        result = recvmsg(socketFd, &msg, 0);
220    } while (result == -1 && errno == EINTR);
221    if (result == -1) {
222        result = errno;
223        ALOGE("Error reading AHardwareBuffer from socket: error %#x (%s)",
224                result, strerror(result));
225        return -result;
226    }
227
228    if (msg.msg_iovlen != 1) {
229        ALOGE("Error reading AHardwareBuffer from socket: bad data length");
230        return INVALID_OPERATION;
231    }
232
233    if (msg.msg_controllen % sizeof(int) != 0) {
234        ALOGE("Error reading AHardwareBuffer from socket: bad fd length");
235        return INVALID_OPERATION;
236    }
237
238    size_t dataLen = msg.msg_iov[0].iov_len;
239    const void* data = static_cast<const void*>(msg.msg_iov[0].iov_base);
240    if (!data) {
241        ALOGE("Error reading AHardwareBuffer from socket: no buffer data");
242        return INVALID_OPERATION;
243    }
244
245    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
246    if (!cmsg) {
247        ALOGE("Error reading AHardwareBuffer from socket: no fd header");
248        return INVALID_OPERATION;
249    }
250
251    size_t fdCount = msg.msg_controllen >> 2;
252    const int* fdData = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
253    if (!fdData) {
254        ALOGE("Error reading AHardwareBuffer from socket: no fd data");
255        return INVALID_OPERATION;
256    }
257
258    GraphicBuffer* gBuffer = new GraphicBuffer();
259    status_t err = gBuffer->unflatten(data, dataLen, fdData, fdCount);
260    if (err != NO_ERROR) {
261        return err;
262    }
263    *outBuffer = AHardwareBuffer_from_GraphicBuffer(gBuffer);
264    // Ensure the buffer has a positive ref-count.
265    AHardwareBuffer_acquire(*outBuffer);
266
267    return NO_ERROR;
268}
269
270
271// ----------------------------------------------------------------------------
272// VNDK functions
273// ----------------------------------------------------------------------------
274
275const native_handle_t* AHardwareBuffer_getNativeHandle(
276        const AHardwareBuffer* buffer) {
277    if (!buffer) return nullptr;
278    const GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
279    return gbuffer->handle;
280}
281
282
283// ----------------------------------------------------------------------------
284// Helpers implementation
285// ----------------------------------------------------------------------------
286
287namespace android {
288
289// A 1:1 mapping of AHardwaqreBuffer bitmasks to gralloc1 bitmasks.
290struct UsageMaskMapping {
291    uint64_t hardwareBufferMask;
292    uint64_t grallocMask;
293};
294
295static inline bool containsBits(uint64_t mask, uint64_t bitsToCheck) {
296    return (mask & bitsToCheck) == bitsToCheck && bitsToCheck;
297}
298
299bool AHardwareBuffer_isValidPixelFormat(uint32_t format) {
300    static_assert(HAL_PIXEL_FORMAT_RGBA_8888 == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
301            "HAL and AHardwareBuffer pixel format don't match");
302    static_assert(HAL_PIXEL_FORMAT_RGBX_8888 == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM,
303            "HAL and AHardwareBuffer pixel format don't match");
304    static_assert(HAL_PIXEL_FORMAT_RGB_565 == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM,
305            "HAL and AHardwareBuffer pixel format don't match");
306    static_assert(HAL_PIXEL_FORMAT_RGB_888 == AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM,
307            "HAL and AHardwareBuffer pixel format don't match");
308    static_assert(HAL_PIXEL_FORMAT_RGBA_FP16 == AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT,
309            "HAL and AHardwareBuffer pixel format don't match");
310    static_assert(HAL_PIXEL_FORMAT_RGBA_1010102 == AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM,
311            "HAL and AHardwareBuffer pixel format don't match");
312    static_assert(HAL_PIXEL_FORMAT_BLOB == AHARDWAREBUFFER_FORMAT_BLOB,
313            "HAL and AHardwareBuffer pixel format don't match");
314    static_assert(HAL_PIXEL_FORMAT_BGRA_8888 == AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM,
315            "HAL and AHardwareBuffer pixel format don't match");
316    static_assert(HAL_PIXEL_FORMAT_YV12 == AHARDWAREBUFFER_FORMAT_YV12,
317            "HAL and AHardwareBuffer pixel format don't match");
318    static_assert(HAL_PIXEL_FORMAT_Y8 == AHARDWAREBUFFER_FORMAT_Y8,
319            "HAL and AHardwareBuffer pixel format don't match");
320    static_assert(HAL_PIXEL_FORMAT_Y16 == AHARDWAREBUFFER_FORMAT_Y16,
321            "HAL and AHardwareBuffer pixel format don't match");
322    static_assert(HAL_PIXEL_FORMAT_RAW16 == AHARDWAREBUFFER_FORMAT_RAW16,
323            "HAL and AHardwareBuffer pixel format don't match");
324    static_assert(HAL_PIXEL_FORMAT_RAW10 == AHARDWAREBUFFER_FORMAT_RAW10,
325            "HAL and AHardwareBuffer pixel format don't match");
326    static_assert(HAL_PIXEL_FORMAT_RAW12 == AHARDWAREBUFFER_FORMAT_RAW12,
327            "HAL and AHardwareBuffer pixel format don't match");
328    static_assert(HAL_PIXEL_FORMAT_RAW_OPAQUE == AHARDWAREBUFFER_FORMAT_RAW_OPAQUE,
329            "HAL and AHardwareBuffer pixel format don't match");
330    static_assert(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED,
331            "HAL and AHardwareBuffer pixel format don't match");
332    static_assert(HAL_PIXEL_FORMAT_YCBCR_420_888 == AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
333            "HAL and AHardwareBuffer pixel format don't match");
334    static_assert(HAL_PIXEL_FORMAT_YCBCR_422_888 == AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_422,
335            "HAL and AHardwareBuffer pixel format don't match");
336    static_assert(HAL_PIXEL_FORMAT_YCBCR_444_888 == AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_444,
337            "HAL and AHardwareBuffer pixel format don't match");
338    static_assert(HAL_PIXEL_FORMAT_FLEX_RGB_888 == AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8,
339            "HAL and AHardwareBuffer pixel format don't match");
340    static_assert(HAL_PIXEL_FORMAT_FLEX_RGBA_8888 == AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8A8,
341            "HAL and AHardwareBuffer pixel format don't match");
342    static_assert(HAL_PIXEL_FORMAT_YCBCR_422_SP == AHARDWAREBUFFER_FORMAT_YCbCr_422_SP,
343            "HAL and AHardwareBuffer pixel format don't match");
344    static_assert(HAL_PIXEL_FORMAT_YCRCB_420_SP == AHARDWAREBUFFER_FORMAT_YCrCb_420_SP,
345            "HAL and AHardwareBuffer pixel format don't match");
346    static_assert(HAL_PIXEL_FORMAT_YCBCR_422_I == AHARDWAREBUFFER_FORMAT_YCbCr_422_I,
347            "HAL and AHardwareBuffer pixel format don't match");
348
349    switch (format) {
350        case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
351        case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
352        case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
353        case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
354        case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
355        case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
356        case AHARDWAREBUFFER_FORMAT_BLOB:
357            // VNDK formats only -- unfortunately we can't differentiate from where we're called
358        case AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM:
359        case AHARDWAREBUFFER_FORMAT_YV12:
360        case AHARDWAREBUFFER_FORMAT_Y8:
361        case AHARDWAREBUFFER_FORMAT_Y16:
362        case AHARDWAREBUFFER_FORMAT_RAW16:
363        case AHARDWAREBUFFER_FORMAT_RAW10:
364        case AHARDWAREBUFFER_FORMAT_RAW12:
365        case AHARDWAREBUFFER_FORMAT_RAW_OPAQUE:
366        case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
367        case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
368        case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_422:
369        case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_444:
370        case AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8:
371        case AHARDWAREBUFFER_FORMAT_FLEX_R8G8B8A8:
372        case AHARDWAREBUFFER_FORMAT_YCbCr_422_SP:
373        case AHARDWAREBUFFER_FORMAT_YCrCb_420_SP:
374        case AHARDWAREBUFFER_FORMAT_YCbCr_422_I:
375            return true;
376
377        default:
378            return false;
379    }
380}
381
382uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t hal_format) {
383    return hal_format;
384}
385
386uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t ahardwarebuffer_format) {
387    return ahardwarebuffer_format;
388}
389
390uint64_t AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage) {
391    using android::hardware::graphics::common::V1_0::BufferUsage;
392    static_assert(AHARDWAREBUFFER_USAGE_CPU_READ_NEVER == (uint64_t)BufferUsage::CPU_READ_NEVER,
393            "gralloc and AHardwareBuffer flags don't match");
394    static_assert(AHARDWAREBUFFER_USAGE_CPU_READ_RARELY == (uint64_t)BufferUsage::CPU_READ_RARELY,
395            "gralloc and AHardwareBuffer flags don't match");
396    static_assert(AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN == (uint64_t)BufferUsage::CPU_READ_OFTEN,
397            "gralloc and AHardwareBuffer flags don't match");
398    static_assert(AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER == (uint64_t)BufferUsage::CPU_WRITE_NEVER,
399            "gralloc and AHardwareBuffer flags don't match");
400    static_assert(AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY == (uint64_t)BufferUsage::CPU_WRITE_RARELY,
401            "gralloc and AHardwareBuffer flags don't match");
402    static_assert(AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN == (uint64_t)BufferUsage::CPU_WRITE_OFTEN,
403            "gralloc and AHardwareBuffer flags don't match");
404    static_assert(AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE == (uint64_t)BufferUsage::GPU_TEXTURE,
405            "gralloc and AHardwareBuffer flags don't match");
406    static_assert(AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT == (uint64_t)BufferUsage::GPU_RENDER_TARGET,
407            "gralloc and AHardwareBuffer flags don't match");
408    static_assert(AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT == (uint64_t)BufferUsage::PROTECTED,
409            "gralloc and AHardwareBuffer flags don't match");
410    static_assert(AHARDWAREBUFFER_USAGE_VIDEO_ENCODE == (uint64_t)BufferUsage::VIDEO_ENCODER,
411            "gralloc and AHardwareBuffer flags don't match");
412    static_assert(AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER == (uint64_t)BufferUsage::GPU_DATA_BUFFER,
413            "gralloc and AHardwareBuffer flags don't match");
414    static_assert(AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA == (uint64_t)BufferUsage::SENSOR_DIRECT_DATA,
415            "gralloc and AHardwareBuffer flags don't match");
416    return usage;
417}
418
419uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t usage) {
420    return usage;
421}
422
423const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) {
424    return reinterpret_cast<const GraphicBuffer*>(buffer);
425}
426
427GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(AHardwareBuffer* buffer) {
428    return reinterpret_cast<GraphicBuffer*>(buffer);
429}
430
431const ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(const AHardwareBuffer* buffer) {
432    return AHardwareBuffer_to_GraphicBuffer(buffer)->getNativeBuffer();
433}
434
435ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(AHardwareBuffer* buffer) {
436    return AHardwareBuffer_to_GraphicBuffer(buffer)->getNativeBuffer();
437}
438
439AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer) {
440    return reinterpret_cast<AHardwareBuffer*>(buffer);
441}
442
443} // namespace android
444