OSDN Git Service

Merge "atrace: Enable sched_waking if available" into oc-dev
[android-x86/frameworks-native.git] / libs / nativewindow / AHardwareBuffer.cpp
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
35 static constexpr int kFdBufferSize = 128 * sizeof(int);  // 128 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->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
85 void 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
90 void 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
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();
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
111 int 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
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
140 int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, 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(kFdBufferSize)];
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;
183     do {
184         result = sendmsg(socketFd, &msg, 0);
185     } while (result == -1 && errno == EINTR);
186     if (result == -1) {
187         result = errno;
188         ALOGE("Error writing AHardwareBuffer to socket: error %#x (%s)",
189                 result, strerror(result));
190         return -result;
191     }
192
193     return NO_ERROR;
194 }
195
196 int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer) {
197     if (!outBuffer) return BAD_VALUE;
198
199     static constexpr int kMessageBufferSize = 4096 * sizeof(int);
200
201     std::unique_ptr<char[]> dataBuf(new char[kMessageBufferSize]);
202     char fdBuf[CMSG_SPACE(kFdBufferSize)];
203     struct iovec iov[1];
204     iov[0].iov_base = dataBuf.get();
205     iov[0].iov_len = kMessageBufferSize;
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
214     int result;
215     do {
216         result = recvmsg(socketFd, &msg, 0);
217     } while (result == -1 && errno == EINTR);
218     if (result == -1) {
219         result = errno;
220         ALOGE("Error reading AHardwareBuffer from socket: error %#x (%s)",
221                 result, strerror(result));
222         return -result;
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
267
268 // ----------------------------------------------------------------------------
269 // VNDK functions
270 // ----------------------------------------------------------------------------
271
272 const native_handle_t* AHardwareBuffer_getNativeHandle(
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
286 // A 1:1 mapping of AHardwaqreBuffer bitmasks to gralloc1 bitmasks.
287 struct UsageMaskMapping {
288     uint64_t hardwareBufferMask;
289     uint64_t grallocMask;
290 };
291
292 static inline bool containsBits(uint64_t mask, uint64_t bitsToCheck) {
293     return (mask & bitsToCheck) == bitsToCheck && bitsToCheck;
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;
302         case HAL_PIXEL_FORMAT_RGBA_FP16:    return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
303         case HAL_PIXEL_FORMAT_RGBA_1010102: return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
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;
316         case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:     return HAL_PIXEL_FORMAT_RGBA_FP16;
317         case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:      return HAL_PIXEL_FORMAT_RGBA_1010102;
318         case AHARDWAREBUFFER_FORMAT_BLOB:                   return HAL_PIXEL_FORMAT_BLOB;
319         default:ALOGE("Unknown AHardwareBuffer format %u", format);
320             return 0;
321     }
322 }
323
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;
351 }
352
353 uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t usage) {
354     return usage;
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 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
373 AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer) {
374     return reinterpret_cast<AHardwareBuffer*>(buffer);
375 }
376
377 } // namespace android