blob: e2647bedd161f0acf88daf420bc6ba21637988e1 [file] [log] [blame]
Mathias Agopian89ed4c82017-02-09 18:48:34 -08001/*
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 Hall1ee859f2017-04-17 08:52:32 -070019#include <vndk/hardware_buffer.h>
Mathias Agopian89ed4c82017-02-09 18:48:34 -080020
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>
Jiwen 'Steve' Cai3ff77232017-03-31 16:34:45 -070031#include <grallocusage/GrallocUsageConversion.h>
Mathias Agopian89ed4c82017-02-09 18:48:34 -080032
33#include <private/android/AHardwareBufferHelpers.h>
34
35
Craig Donner1b1d3002017-04-12 18:38:07 -070036static constexpr int kFdBufferSize = 128 * sizeof(int); // 128 ints
Mathias Agopian89ed4c82017-02-09 18:48:34 -080037
38using namespace android;
39
40// ----------------------------------------------------------------------------
41// Public functions
42// ----------------------------------------------------------------------------
43
44int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer) {
45 if (!outBuffer || !desc)
46 return BAD_VALUE;
47
48 int format = AHardwareBuffer_convertToPixelFormat(desc->format);
49 if (format == 0) {
50 ALOGE("Invalid pixel format %u", desc->format);
51 return BAD_VALUE;
52 }
53
54 if (desc->format == AHARDWAREBUFFER_FORMAT_BLOB && desc->height != 1) {
55 ALOGE("Height must be 1 when using the AHARDWAREBUFFER_FORMAT_BLOB format");
56 return BAD_VALUE;
57 }
58
59 uint64_t producerUsage = 0;
60 uint64_t consumerUsage = 0;
Craig Donnera5a719e2017-02-24 16:02:08 -080061 AHardwareBuffer_convertToGrallocUsageBits(&producerUsage, &consumerUsage, desc->usage0,
62 desc->usage1);
Chris Forbesd4106302017-04-20 12:43:04 -070063 uint32_t usage = android_convertGralloc1To0Usage(producerUsage, consumerUsage);
Mathias Agopian89ed4c82017-02-09 18:48:34 -080064
65 sp<GraphicBuffer> gbuffer(new GraphicBuffer(
Chris Forbesd4106302017-04-20 12:43:04 -070066 desc->width, desc->height, format, desc->layers, usage,
Mathias Agopian89ed4c82017-02-09 18:48:34 -080067 std::string("AHardwareBuffer pid [") + std::to_string(getpid()) + "]"));
68
69 status_t err = gbuffer->initCheck();
70 if (err != 0 || gbuffer->handle == 0) {
71 if (err == NO_MEMORY) {
72 GraphicBuffer::dumpAllocationsToSystemLog();
73 }
Mathias Agopian0556d792017-03-22 15:49:32 -070074 ALOGE("GraphicBuffer(w=%u, h=%u, lc=%u) failed (%s), handle=%p",
Mathias Agopian89ed4c82017-02-09 18:48:34 -080075 desc->width, desc->height, desc->layers, strerror(-err), gbuffer->handle);
76 return err;
77 }
78
79 *outBuffer = AHardwareBuffer_from_GraphicBuffer(gbuffer.get());
80
81 // Ensure the buffer doesn't get destroyed when the sp<> goes away.
82 AHardwareBuffer_acquire(*outBuffer);
83 return NO_ERROR;
84}
85
86void AHardwareBuffer_acquire(AHardwareBuffer* buffer) {
Mathias Agopian000879a2017-03-20 18:07:26 -070087 // incStrong/decStrong token must be the same, doesn't matter what it is
Mathias Agopian89ed4c82017-02-09 18:48:34 -080088 AHardwareBuffer_to_GraphicBuffer(buffer)->incStrong((void*)AHardwareBuffer_acquire);
89}
90
91void AHardwareBuffer_release(AHardwareBuffer* buffer) {
Mathias Agopian000879a2017-03-20 18:07:26 -070092 // incStrong/decStrong token must be the same, doesn't matter what it is
93 AHardwareBuffer_to_GraphicBuffer(buffer)->decStrong((void*)AHardwareBuffer_acquire);
Mathias Agopian89ed4c82017-02-09 18:48:34 -080094}
95
96void AHardwareBuffer_describe(const AHardwareBuffer* buffer,
97 AHardwareBuffer_Desc* outDesc) {
98 if (!buffer || !outDesc) return;
99
100 const GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
101
102 outDesc->width = gbuffer->getWidth();
103 outDesc->height = gbuffer->getHeight();
104 outDesc->layers = gbuffer->getLayerCount();
Jiwen 'Steve' Cai3ff77232017-03-31 16:34:45 -0700105
106 uint64_t producerUsage = 0;
107 uint64_t consumerUsage = 0;
108 android_convertGralloc0To1Usage(gbuffer->getUsage(), &producerUsage, &consumerUsage);
Craig Donnera5a719e2017-02-24 16:02:08 -0800109 AHardwareBuffer_convertFromGrallocUsageBits(&outDesc->usage0, &outDesc->usage1,
Jiwen 'Steve' Cai3ff77232017-03-31 16:34:45 -0700110 producerUsage, consumerUsage);
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800111 outDesc->format = AHardwareBuffer_convertFromPixelFormat(
112 static_cast<uint32_t>(gbuffer->getPixelFormat()));
113}
114
115int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage0,
116 int32_t fence, const ARect* rect, void** outVirtualAddress) {
117 if (!buffer) return BAD_VALUE;
118
119 if (usage0 & ~(AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN |
120 AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN)) {
121 ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only "
122 " AHARDWAREBUFFER_USAGE0_CPU_* flags are allowed");
123 return BAD_VALUE;
124 }
125
126 uint64_t producerUsage = 0;
127 uint64_t consumerUsage = 0;
Craig Donnera5a719e2017-02-24 16:02:08 -0800128 AHardwareBuffer_convertToGrallocUsageBits(&producerUsage, &consumerUsage, usage0, 0);
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800129 GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
130 Rect bounds;
131 if (!rect) {
132 bounds.set(Rect(gBuffer->getWidth(), gBuffer->getHeight()));
133 } else {
134 bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom));
135 }
136 return gBuffer->lockAsync(producerUsage, consumerUsage, bounds,
137 outVirtualAddress, fence);
138}
139
140int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) {
141 if (!buffer) return BAD_VALUE;
142
143 GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
144 return gBuffer->unlockAsync(fence);
145}
146
Mathias Agopian000879a2017-03-20 18:07:26 -0700147int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) {
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800148 if (!buffer) return BAD_VALUE;
149 const GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
150
151 size_t flattenedSize = gBuffer->getFlattenedSize();
152 size_t fdCount = gBuffer->getFdCount();
153
154 std::unique_ptr<uint8_t[]> data(new uint8_t[flattenedSize]);
155 std::unique_ptr<int[]> fds(new int[fdCount]);
156
157 // Make copies of needed items since flatten modifies them, and we don't
158 // want to send anything if there's an error during flatten.
159 size_t flattenedSizeCopy = flattenedSize;
160 size_t fdCountCopy = fdCount;
161 void* dataStart = data.get();
162 int* fdsStart = fds.get();
163 status_t err = gBuffer->flatten(dataStart, flattenedSizeCopy, fdsStart,
164 fdCountCopy);
165 if (err != NO_ERROR) {
166 return err;
167 }
168
169 struct iovec iov[1];
170 iov[0].iov_base = data.get();
171 iov[0].iov_len = flattenedSize;
172
Craig Donner1b1d3002017-04-12 18:38:07 -0700173 char buf[CMSG_SPACE(kFdBufferSize)];
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800174 struct msghdr msg = {
175 .msg_control = buf,
176 .msg_controllen = sizeof(buf),
177 .msg_iov = &iov[0],
178 .msg_iovlen = 1,
179 };
180
181 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
182 cmsg->cmsg_level = SOL_SOCKET;
183 cmsg->cmsg_type = SCM_RIGHTS;
184 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount);
185 int* fdData = reinterpret_cast<int*>(CMSG_DATA(cmsg));
186 memcpy(fdData, fds.get(), sizeof(int) * fdCount);
187 msg.msg_controllen = cmsg->cmsg_len;
188
189 int result = sendmsg(socketFd, &msg, 0);
190 if (result <= 0) {
191 ALOGE("Error writing AHardwareBuffer to socket: error %#x (%s)",
192 result, strerror(errno));
193 return result;
194 }
195 return NO_ERROR;
196}
197
Mathias Agopian000879a2017-03-20 18:07:26 -0700198int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer) {
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800199 if (!outBuffer) return BAD_VALUE;
200
Craig Donner1b1d3002017-04-12 18:38:07 -0700201 static constexpr int kMessageBufferSize = 4096 * sizeof(int);
202
203 std::unique_ptr<char[]> dataBuf(new char[kMessageBufferSize]);
204 char fdBuf[CMSG_SPACE(kFdBufferSize)];
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800205 struct iovec iov[1];
Craig Donner1b1d3002017-04-12 18:38:07 -0700206 iov[0].iov_base = dataBuf.get();
207 iov[0].iov_len = kMessageBufferSize;
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800208
209 struct msghdr msg = {
210 .msg_control = fdBuf,
211 .msg_controllen = sizeof(fdBuf),
212 .msg_iov = &iov[0],
213 .msg_iovlen = 1,
214 };
215
216 int result = recvmsg(socketFd, &msg, 0);
217 if (result <= 0) {
218 ALOGE("Error reading AHardwareBuffer from socket: error %#x (%s)",
219 result, strerror(errno));
220 return result;
221 }
222
223 if (msg.msg_iovlen != 1) {
224 ALOGE("Error reading AHardwareBuffer from socket: bad data length");
225 return INVALID_OPERATION;
226 }
227
228 if (msg.msg_controllen % sizeof(int) != 0) {
229 ALOGE("Error reading AHardwareBuffer from socket: bad fd length");
230 return INVALID_OPERATION;
231 }
232
233 size_t dataLen = msg.msg_iov[0].iov_len;
234 const void* data = static_cast<const void*>(msg.msg_iov[0].iov_base);
235 if (!data) {
236 ALOGE("Error reading AHardwareBuffer from socket: no buffer data");
237 return INVALID_OPERATION;
238 }
239
240 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
241 if (!cmsg) {
242 ALOGE("Error reading AHardwareBuffer from socket: no fd header");
243 return INVALID_OPERATION;
244 }
245
246 size_t fdCount = msg.msg_controllen >> 2;
247 const int* fdData = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
248 if (!fdData) {
249 ALOGE("Error reading AHardwareBuffer from socket: no fd data");
250 return INVALID_OPERATION;
251 }
252
253 GraphicBuffer* gBuffer = new GraphicBuffer();
254 status_t err = gBuffer->unflatten(data, dataLen, fdData, fdCount);
255 if (err != NO_ERROR) {
256 return err;
257 }
258 *outBuffer = AHardwareBuffer_from_GraphicBuffer(gBuffer);
259 // Ensure the buffer has a positive ref-count.
260 AHardwareBuffer_acquire(*outBuffer);
261
262 return NO_ERROR;
263}
264
Jesse Hall1ee859f2017-04-17 08:52:32 -0700265
266// ----------------------------------------------------------------------------
267// VNDK functions
268// ----------------------------------------------------------------------------
269
270const native_handle_t* AHardwareBuffer_getNativeHandle(
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800271 const AHardwareBuffer* buffer) {
272 if (!buffer) return nullptr;
273 const GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
274 return gbuffer->handle;
275}
276
277
278// ----------------------------------------------------------------------------
279// Helpers implementation
280// ----------------------------------------------------------------------------
281
282namespace android {
283
Craig Donnera5a719e2017-02-24 16:02:08 -0800284// A 1:1 mapping of AHardwaqreBuffer bitmasks to gralloc1 bitmasks.
285struct UsageMaskMapping {
286 uint64_t hardwareBufferMask;
287 uint64_t grallocMask;
288};
289
290static constexpr UsageMaskMapping kUsage0ProducerMapping[] = {
291 { AHARDWAREBUFFER_USAGE0_CPU_WRITE, GRALLOC1_PRODUCER_USAGE_CPU_WRITE },
292 { AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN, GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN },
293 { AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT, GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET },
294 { AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT, GRALLOC1_PRODUCER_USAGE_PROTECTED },
295 { AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA, GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA },
296};
297
298static constexpr UsageMaskMapping kUsage1ProducerMapping[] = {
299 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_0, GRALLOC1_PRODUCER_USAGE_PRIVATE_0 },
300 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_1, GRALLOC1_PRODUCER_USAGE_PRIVATE_1 },
301 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_2, GRALLOC1_PRODUCER_USAGE_PRIVATE_2 },
302 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_3, GRALLOC1_PRODUCER_USAGE_PRIVATE_3 },
303 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_4, GRALLOC1_PRODUCER_USAGE_PRIVATE_4 },
304 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_5, GRALLOC1_PRODUCER_USAGE_PRIVATE_5 },
305 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_6, GRALLOC1_PRODUCER_USAGE_PRIVATE_6 },
306 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_7, GRALLOC1_PRODUCER_USAGE_PRIVATE_7 },
307 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_8, GRALLOC1_PRODUCER_USAGE_PRIVATE_8 },
308 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_9, GRALLOC1_PRODUCER_USAGE_PRIVATE_9 },
309 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_10, GRALLOC1_PRODUCER_USAGE_PRIVATE_10 },
310 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_11, GRALLOC1_PRODUCER_USAGE_PRIVATE_11 },
311 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_12, GRALLOC1_PRODUCER_USAGE_PRIVATE_12 },
312 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_13, GRALLOC1_PRODUCER_USAGE_PRIVATE_13 },
313 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_14, GRALLOC1_PRODUCER_USAGE_PRIVATE_14 },
314 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_15, GRALLOC1_PRODUCER_USAGE_PRIVATE_15 },
315 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_16, GRALLOC1_PRODUCER_USAGE_PRIVATE_16 },
316 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_17, GRALLOC1_PRODUCER_USAGE_PRIVATE_17 },
317 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_18, GRALLOC1_PRODUCER_USAGE_PRIVATE_18 },
318 { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_19, GRALLOC1_PRODUCER_USAGE_PRIVATE_19 },
319};
320
321static constexpr UsageMaskMapping kUsage0ConsumerMapping[] = {
322 { AHARDWAREBUFFER_USAGE0_CPU_READ, GRALLOC1_CONSUMER_USAGE_CPU_READ },
323 { AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN, GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN },
324 { AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE, GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE },
325 { AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER, GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER },
326 { AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE, GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER },
327};
328
329static constexpr UsageMaskMapping kUsage1ConsumerMapping[] = {
330 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_0, GRALLOC1_CONSUMER_USAGE_PRIVATE_0 },
331 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_1, GRALLOC1_CONSUMER_USAGE_PRIVATE_1 },
332 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_2, GRALLOC1_CONSUMER_USAGE_PRIVATE_2 },
333 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_3, GRALLOC1_CONSUMER_USAGE_PRIVATE_3 },
334 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_4, GRALLOC1_CONSUMER_USAGE_PRIVATE_4 },
335 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_5, GRALLOC1_CONSUMER_USAGE_PRIVATE_5 },
336 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_6, GRALLOC1_CONSUMER_USAGE_PRIVATE_6 },
337 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_7, GRALLOC1_CONSUMER_USAGE_PRIVATE_7 },
338 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_8, GRALLOC1_CONSUMER_USAGE_PRIVATE_8 },
339 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_9, GRALLOC1_CONSUMER_USAGE_PRIVATE_9 },
340 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_10, GRALLOC1_CONSUMER_USAGE_PRIVATE_10 },
341 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_11, GRALLOC1_CONSUMER_USAGE_PRIVATE_11 },
342 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_12, GRALLOC1_CONSUMER_USAGE_PRIVATE_12 },
343 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_13, GRALLOC1_CONSUMER_USAGE_PRIVATE_13 },
344 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_14, GRALLOC1_CONSUMER_USAGE_PRIVATE_14 },
345 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_15, GRALLOC1_CONSUMER_USAGE_PRIVATE_15 },
346 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_16, GRALLOC1_CONSUMER_USAGE_PRIVATE_16 },
347 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_17, GRALLOC1_CONSUMER_USAGE_PRIVATE_17 },
348 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_18, GRALLOC1_CONSUMER_USAGE_PRIVATE_18 },
349 { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_19, GRALLOC1_CONSUMER_USAGE_PRIVATE_19 },
350};
351
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800352static inline bool containsBits(uint64_t mask, uint64_t bitsToCheck) {
Craig Donnera5a719e2017-02-24 16:02:08 -0800353 return (mask & bitsToCheck) == bitsToCheck && bitsToCheck;
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800354}
355
356uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format) {
357 switch (format) {
358 case HAL_PIXEL_FORMAT_RGBA_8888: return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
359 case HAL_PIXEL_FORMAT_RGBX_8888: return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
360 case HAL_PIXEL_FORMAT_RGB_565: return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
361 case HAL_PIXEL_FORMAT_RGB_888: return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
Jesse Hall577aa752017-04-19 15:43:02 -0700362 case HAL_PIXEL_FORMAT_RGBA_FP16: return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
363 case HAL_PIXEL_FORMAT_RGBA_1010102: return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800364 case HAL_PIXEL_FORMAT_BLOB: return AHARDWAREBUFFER_FORMAT_BLOB;
365 default:ALOGE("Unknown pixel format %u", format);
366 return 0;
367 }
368}
369
370uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format) {
371 switch (format) {
372 case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM: return HAL_PIXEL_FORMAT_RGBA_8888;
373 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: return HAL_PIXEL_FORMAT_RGBX_8888;
374 case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: return HAL_PIXEL_FORMAT_RGB_565;
375 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: return HAL_PIXEL_FORMAT_RGB_888;
Jesse Hall577aa752017-04-19 15:43:02 -0700376 case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT: return HAL_PIXEL_FORMAT_RGBA_FP16;
377 case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM: return HAL_PIXEL_FORMAT_RGBA_1010102;
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800378 case AHARDWAREBUFFER_FORMAT_BLOB: return HAL_PIXEL_FORMAT_BLOB;
379 default:ALOGE("Unknown AHardwareBuffer format %u", format);
380 return 0;
381 }
382}
383
Craig Donnera5a719e2017-02-24 16:02:08 -0800384void AHardwareBuffer_convertToGrallocUsageBits(uint64_t* outProducerUsage,
385 uint64_t* outConsumerUsage, uint64_t usage0, uint64_t usage1) {
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800386 *outProducerUsage = 0;
387 *outConsumerUsage = 0;
Craig Donnera5a719e2017-02-24 16:02:08 -0800388 for (const UsageMaskMapping& mapping : kUsage0ProducerMapping) {
389 if (containsBits(usage0, mapping.hardwareBufferMask)) {
390 *outProducerUsage |= mapping.grallocMask;
391 }
392 }
393 for (const UsageMaskMapping& mapping : kUsage1ProducerMapping) {
394 if (containsBits(usage1, mapping.hardwareBufferMask)) {
395 *outProducerUsage |= mapping.grallocMask;
396 }
397 }
398 for (const UsageMaskMapping& mapping : kUsage0ConsumerMapping) {
399 if (containsBits(usage0, mapping.hardwareBufferMask)) {
400 *outConsumerUsage |= mapping.grallocMask;
401 }
402 }
403 for (const UsageMaskMapping& mapping : kUsage1ConsumerMapping) {
404 if (containsBits(usage1, mapping.hardwareBufferMask)) {
405 *outConsumerUsage |= mapping.grallocMask;
406 }
407 }
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800408}
409
Craig Donnera5a719e2017-02-24 16:02:08 -0800410void AHardwareBuffer_convertFromGrallocUsageBits(uint64_t* outUsage0, uint64_t* outUsage1,
411 uint64_t producerUsage, uint64_t consumerUsage) {
412 *outUsage0 = 0;
413 *outUsage1 = 0;
414 for (const UsageMaskMapping& mapping : kUsage0ProducerMapping) {
415 if (containsBits(producerUsage, mapping.grallocMask)) {
416 *outUsage0 |= mapping.hardwareBufferMask;
417 }
418 }
419 for (const UsageMaskMapping& mapping : kUsage1ProducerMapping) {
420 if (containsBits(producerUsage, mapping.grallocMask)) {
421 *outUsage1 |= mapping.hardwareBufferMask;
422 }
423 }
424 for (const UsageMaskMapping& mapping : kUsage0ConsumerMapping) {
425 if (containsBits(consumerUsage, mapping.grallocMask)) {
426 *outUsage0 |= mapping.hardwareBufferMask;
427 }
428 }
429 for (const UsageMaskMapping& mapping : kUsage1ConsumerMapping) {
430 if (containsBits(consumerUsage, mapping.grallocMask)) {
431 *outUsage1 |= mapping.hardwareBufferMask;
432 }
433 }
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800434}
435
436const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) {
437 return reinterpret_cast<const GraphicBuffer*>(buffer);
438}
439
440GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(AHardwareBuffer* buffer) {
441 return reinterpret_cast<GraphicBuffer*>(buffer);
442}
443
Mathias Agopian61963402017-02-24 16:38:15 -0800444const ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(const AHardwareBuffer* buffer) {
445 return AHardwareBuffer_to_GraphicBuffer(buffer)->getNativeBuffer();
446}
447
448ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(AHardwareBuffer* buffer) {
449 return AHardwareBuffer_to_GraphicBuffer(buffer)->getNativeBuffer();
450}
451
Mathias Agopian89ed4c82017-02-09 18:48:34 -0800452AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer) {
453 return reinterpret_cast<AHardwareBuffer*>(buffer);
454}
455
456} // namespace android