blob: c2d8598bbd128c4afdcab787cf47d1873ef3c6b2 [file] [log] [blame]
Prabhanjan Kandula96e92342016-03-24 21:03:35 +05301/*
Saurabh Shahc5b2b702016-10-24 17:16:01 -07002 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
Prabhanjan Kandula96e92342016-03-24 21:03:35 +05303 * Not a Contribution
4 *
5 * Copyright (C) 2010 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
Saurabh Shah7d476ed2016-06-27 16:40:58 -070020#include <drm/drm_fourcc.h>
21#include <drm_master.h>
22
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053023#include <utility>
24
25#include "qd_utils.h"
26#include "gr_priv_handle.h"
27#include "gr_buf_descriptor.h"
28#include "gr_utils.h"
29#include "gr_buf_mgr.h"
30#include "qdMetaData.h"
31
32namespace gralloc1 {
33
Saurabh Shah7d476ed2016-06-27 16:40:58 -070034using namespace drm_utils;
35
36static int getPlaneStrideOffset(private_handle_t *hnd, uint32_t *stride,
37 uint32_t *offset, uint32_t *num_planes) {
38 struct android_ycbcr yuvInfo = {};
39 *num_planes = 1;
40
41 switch (hnd->format) {
42 case HAL_PIXEL_FORMAT_RGB_565:
43 case HAL_PIXEL_FORMAT_BGR_565:
44 case HAL_PIXEL_FORMAT_RGBA_5551:
45 case HAL_PIXEL_FORMAT_RGBA_4444:
46 stride[0] = hnd->width * 2;
47 break;
48 case HAL_PIXEL_FORMAT_RGB_888:
49 stride[0] = hnd->width * 3;
50 break;
51 case HAL_PIXEL_FORMAT_RGBA_8888:
52 case HAL_PIXEL_FORMAT_BGRA_8888:
53 case HAL_PIXEL_FORMAT_RGBX_8888:
54 case HAL_PIXEL_FORMAT_BGRX_8888:
55 case HAL_PIXEL_FORMAT_RGBA_1010102:
56 case HAL_PIXEL_FORMAT_ARGB_2101010:
57 case HAL_PIXEL_FORMAT_RGBX_1010102:
58 case HAL_PIXEL_FORMAT_XRGB_2101010:
59 case HAL_PIXEL_FORMAT_BGRA_1010102:
60 case HAL_PIXEL_FORMAT_ABGR_2101010:
61 case HAL_PIXEL_FORMAT_BGRX_1010102:
62 case HAL_PIXEL_FORMAT_XBGR_2101010:
63 stride[0] = hnd->width * 4;
64 break;
65 }
66
67 // Format is RGB
68 if (stride[0]) {
69 return 0;
70 }
71
72 (*num_planes)++;
73 int ret = getYUVPlaneInfo(hnd, &yuvInfo);
74 if (ret < 0) {
75 ALOGE("%s failed", __FUNCTION__);
76 return ret;
77 }
78
79 stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
80 offset[0] = static_cast<uint32_t>(
81 reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
82 stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
83 switch (hnd->format) {
84 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
85 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
86 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
87 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
88 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
89 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
90 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
91 offset[1] = static_cast<uint32_t>(
92 reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
93 break;
94 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
95 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
96 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
97 offset[1] = static_cast<uint32_t>(
98 reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
99 break;
100 case HAL_PIXEL_FORMAT_YV12:
101 offset[1] = static_cast<uint32_t>(
102 reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
103 stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
104 offset[2] = static_cast<uint32_t>(
105 reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
106 (*num_planes)++;
107 break;
108 default:
109 ALOGW("%s: Unsupported format %s", __FUNCTION__,
110 qdutils::GetHALPixelFormatString(hnd->format));
111 }
112
113 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
114 std::fill(offset, offset + 4, 0);
115 }
116
117 return 0;
118}
119
120static void getDRMFormat(int hal_format, int flags, uint32_t *drm_format,
121 uint64_t *drm_format_modifier) {
122
123 if (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
124 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
125 }
126
127 switch (hal_format) {
128 case HAL_PIXEL_FORMAT_RGBA_8888:
129 *drm_format = DRM_FORMAT_RGBA8888;
130 break;
131 case HAL_PIXEL_FORMAT_RGBA_5551:
132 *drm_format = DRM_FORMAT_RGBA5551;
133 break;
134 case HAL_PIXEL_FORMAT_RGBA_4444:
135 *drm_format = DRM_FORMAT_RGBA4444;
136 break;
137 case HAL_PIXEL_FORMAT_BGRA_8888:
138 *drm_format = DRM_FORMAT_BGRA8888;
139 break;
140 case HAL_PIXEL_FORMAT_RGBX_8888:
141 *drm_format = DRM_FORMAT_RGBX8888;
142 break;
143 case HAL_PIXEL_FORMAT_BGRX_8888:
144 *drm_format = DRM_FORMAT_BGRX8888;
145 break;
146 case HAL_PIXEL_FORMAT_RGB_888:
147 *drm_format = DRM_FORMAT_RGB888;
148 break;
149 case HAL_PIXEL_FORMAT_RGB_565:
150 *drm_format = DRM_FORMAT_RGB565;
151 break;
152 case HAL_PIXEL_FORMAT_BGR_565:
153 *drm_format = DRM_FORMAT_BGR565;
154 break;
155 case HAL_PIXEL_FORMAT_RGBA_1010102:
156 *drm_format = DRM_FORMAT_RGBA1010102;
157 break;
158 case HAL_PIXEL_FORMAT_ARGB_2101010:
159 *drm_format = DRM_FORMAT_ARGB2101010;
160 break;
161 case HAL_PIXEL_FORMAT_RGBX_1010102:
162 *drm_format = DRM_FORMAT_RGBX1010102;
163 break;
164 case HAL_PIXEL_FORMAT_XRGB_2101010:
165 *drm_format = DRM_FORMAT_XRGB2101010;
166 break;
167 case HAL_PIXEL_FORMAT_BGRA_1010102:
168 *drm_format = DRM_FORMAT_BGRA1010102;
169 break;
170 case HAL_PIXEL_FORMAT_ABGR_2101010:
171 *drm_format = DRM_FORMAT_ABGR2101010;
172 break;
173 case HAL_PIXEL_FORMAT_BGRX_1010102:
174 *drm_format = DRM_FORMAT_BGRX1010102;
175 break;
176 case HAL_PIXEL_FORMAT_XBGR_2101010:
177 *drm_format = DRM_FORMAT_XBGR2101010;
178 break;
179 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
180 *drm_format = DRM_FORMAT_NV12;
181 break;
182 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
183 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
184 *drm_format = DRM_FORMAT_NV12;
185 break;
186 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
187 *drm_format = DRM_FORMAT_NV12;
188 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
189 break;
190 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
191 *drm_format = DRM_FORMAT_NV21;
192 break;
193 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
194 *drm_format = DRM_FORMAT_NV21;
195 break;
196 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
197 // TODO *drm_format = DRM_FORMAT_P010;
198 break;
199 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
200 // TODO *drm_format = DRM_FORMAT_P010;
201 // *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED |
202 // DRM_FORMAT_MOD_QCOM_TIGHT;
203 break;
204 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
205 *drm_format = DRM_FORMAT_NV16;
206 break;
207 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
208 *drm_format = DRM_FORMAT_NV61;
209 break;
210 case HAL_PIXEL_FORMAT_YV12:
211 *drm_format = DRM_FORMAT_YVU420;
212 break;
213 default:
214 ALOGW("%s: Unsupported format %s", __FUNCTION__,
215 qdutils::GetHALPixelFormatString(hal_format));
216
217 }
218}
219
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530220BufferManager::BufferManager() {
221 char property[PROPERTY_VALUE_MAX];
222
223 // Map framebuffer memory
224 if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
225 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
226 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
227 map_fb_mem_ = true;
228 }
229
230 // Enable UBWC for framebuffer
231 if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
232 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
233 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
234 ubwc_for_fb_ = true;
235 }
236
237 handles_map_.clear();
238}
239
240BufferManager::~BufferManager() {
241 if (allocator_) {
242 delete allocator_;
243 }
244}
245
246bool BufferManager::Init() {
247 allocator_ = new Allocator();
248
249 return allocator_->Init();
250}
251
252gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
253 const BufferDescriptor *descriptors,
254 buffer_handle_t *out_buffers) {
255 bool shared = true;
256 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
257
258 // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
259 // client can ask to test the allocation by passing NULL out_buffers
260 bool test_allocate = !out_buffers;
261
262 // Check if input descriptors can be supported AND
263 // Find out if a single buffer can be shared for all the given input descriptors
264 uint32_t i = 0;
265 int max_buf_index = -1;
266 shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
267
268 if (test_allocate) {
269 status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
270 return status;
271 }
272
273 if (shared && (max_buf_index >= 0)) {
274 // Allocate one and duplicate/copy the handles for each descriptor
275 if (AllocateBuffer(descriptors[max_buf_index], &out_buffers[max_buf_index])) {
276 return GRALLOC1_ERROR_NO_RESOURCES;
277 }
278
279 for (i = 0; i < num_descriptors; i++) {
280 // Create new handle for a given descriptor.
281 // Current assumption is even MetaData memory would be same
282 // Need to revisit if there is a need for own metadata memory
283 if (i != UINT(max_buf_index)) {
284 CreateSharedHandle(out_buffers[max_buf_index], descriptors[i], &out_buffers[i]);
285
286 // since we just created handle out of existing handle add it to map
287 locker_.lock();
288 handles_map_.insert(std::pair<private_handle_t const *, int>(
289 reinterpret_cast<private_handle_t const *>(out_buffers[i]), 1));
290 locker_.unlock();
291 }
292 }
293 } else {
294 // Buffer sharing is not feasible.
295 // Allocate seperate buffer for each descriptor
296 for (i = 0; i < num_descriptors; i++) {
297 if (AllocateBuffer(descriptors[i], &out_buffers[i])) {
298 return GRALLOC1_ERROR_NO_RESOURCES;
299 }
300 }
301 }
302
303 // Allocation is successful. If backstore is not shared inform the client.
304 if (!shared) {
305 return GRALLOC1_ERROR_NOT_SHARED;
306 }
307
308 return status;
309}
310
311void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
312 buffer_handle_t *outbuffer) {
313 private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
314
315 // Get Buffer attributes or dimension
316 unsigned int alignedw = 0, alignedh = 0;
317 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
318
319 // create new handle from input reference handle and given descriptor
320 int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
321 descriptor.GetConsumerUsage());
322 int buffer_type = GetBufferType(descriptor.GetFormat());
323
324 // Duplicate the fds
325 private_handle_t *out_hnd = new private_handle_t(
326 dup(input->fd), input->size, flags, buffer_type, descriptor.GetFormat(), INT(alignedw),
327 INT(alignedh), dup(input->fd_metadata), input->offset_metadata, input->base_metadata,
328 descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetProducerUsage(),
329 descriptor.GetConsumerUsage());
330
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700331 // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions?
332
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530333 *outbuffer = out_hnd;
334}
335
336gralloc1_error_t BufferManager::FreeBuffer(private_handle_t const *hnd) {
337 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
338 hnd->fd) != 0) {
339 return GRALLOC1_ERROR_BAD_HANDLE;
340 }
341
342 unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
343 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
344 hnd->offset_metadata, hnd->fd_metadata) != 0) {
345 return GRALLOC1_ERROR_BAD_HANDLE;
346 }
347
348 // delete handle also
349 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700350 if (handle->fb_id) {
351 int ret = DRMMaster::GetInstance(&master);
352 if (ret < 0) {
353 ALOGE("%s Failed to acquire DRMMaster instance", __FUNCTION__);
354 return ret;
355 }
356 ret = master->RemoveFbId(hnd->gem_handle, hnd->fb_id);
357 if (ret < 0) {
358 ALOGE("%s: Removing fb_id %d failed with error %d", __FUNCTION__,
359 hnd->fb_id, errno);
360 }
361 }
362
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530363 delete handle;
364
365 return GRALLOC1_ERROR_NONE;
366}
367
368gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
369 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
370
371 hnd->base = 0;
372 hnd->base_metadata = 0;
373 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
374 hnd->fd) != 0) {
375 return GRALLOC1_ERROR_BAD_HANDLE;
376 }
377
378 unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
379 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
380 hnd->offset_metadata, hnd->fd_metadata) != 0) {
381 return GRALLOC1_ERROR_BAD_HANDLE;
382 }
383
384 return GRALLOC1_ERROR_NONE;
385}
386
387gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
388 locker_.lock();
389
390 // find if this handle is already in map
391 auto it = handles_map_.find(hnd);
392 if (it != handles_map_.end()) {
393 // It's already in map, Just increment refcnt
394 // No need to mmap the memory.
395 it->second = it->second + 1;
396 } else {
397 // not present in the map. mmap and then add entry to map
398 if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) {
399 handles_map_.insert(std::pair<private_handle_t const *, int>(hnd, 1));
400 }
401 }
402
403 locker_.unlock();
404 return GRALLOC1_ERROR_NONE;
405}
406
407gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
408 locker_.lock();
409
410 // find if this handle is already in map
411 auto it = handles_map_.find(hnd);
412 if (it == handles_map_.end()) {
413 // Corrupt handle or map.
414 locker_.unlock();
415 return GRALLOC1_ERROR_BAD_HANDLE;
416 } else {
417 it->second = it->second - 1;
418 }
419
420 if (!it->second) {
421 handles_map_.erase(it);
422 FreeBuffer(hnd);
423 }
424
425 locker_.unlock();
426 return GRALLOC1_ERROR_NONE;
427}
428
429gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
430 gralloc1_producer_usage_t prod_usage,
431 gralloc1_consumer_usage_t cons_usage) {
432 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
433
434 // If buffer is not meant for CPU return err
435 if (!CpuCanAccess(prod_usage, cons_usage)) {
436 return GRALLOC1_ERROR_BAD_VALUE;
437 }
438
439 if (hnd->base == 0) {
440 // we need to map for real
441 locker_.lock();
442 err = MapBuffer(hnd);
443 locker_.unlock();
444 }
445
446 // Invalidate if CPU reads in software and there are non-CPU
447 // writers. No need to do this for the metadata buffer as it is
448 // only read/written in software.
449 if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
450 (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
451 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
452 hnd->fd, CACHE_INVALIDATE)) {
453 return GRALLOC1_ERROR_BAD_HANDLE;
454 }
455 }
456
457 // Mark the buffer to be flushed after CPU write.
458 if (!err && CpuCanWrite(prod_usage)) {
459 private_handle_t *handle = const_cast<private_handle_t *>(hnd);
460 handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
461 }
462
463 return err;
464}
465
466gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
467 gralloc1_error_t status = GRALLOC1_ERROR_NONE;
468
469 locker_.lock();
470 private_handle_t *hnd = const_cast<private_handle_t *>(handle);
471
472 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
473 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
474 hnd->fd, CACHE_CLEAN) != 0) {
475 status = GRALLOC1_ERROR_BAD_HANDLE;
476 }
477 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
478 }
479
480 locker_.unlock();
481 return status;
482}
483
484int BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
485 gralloc1_consumer_usage_t cons_usage) {
486 int align = getpagesize();
487 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
488 align = 8192;
489 }
490
491 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
Sushil Chauhandfe55a22016-09-12 15:48:29 -0700492 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
493 (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530494 // The alignment here reflects qsee mmu V7L/V8L requirement
495 align = SZ_2M;
496 } else {
497 align = SECURE_ALIGN;
498 }
499 }
500
501 return align;
502}
503
504int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
505 gralloc1_consumer_usage_t cons_usage) {
506 int flags = 0;
507 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
508 flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
509 }
510
511 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
512 flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
513 }
514
515 if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
516 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
517 }
518
519 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
520 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
521 }
522
523 if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
524 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
525 }
526
527 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
528 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
529 }
530
531 if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
532 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
533 }
534
535 if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
536 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
537 }
538
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530539 if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
540 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
541 }
542
543 if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
544 flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
545 }
546
547 // TODO(user): is this correct???
548 if ((cons_usage &
549 (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
550 (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
551 flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
552 }
553
554 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
555 flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
556 }
557
558 if (!allocator_->UseUncached(prod_usage)) {
559 flags |= private_handle_t::PRIV_FLAGS_CACHED;
560 }
561
562 return flags;
563}
564
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700565int BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int unaligned_w,
566 int unaligned_h, int format, int bufferType,
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530567 gralloc1_producer_usage_t prod_usage,
568 gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) {
569 int err = 0;
570 int flags = 0;
571 size = ALIGN(size, PAGE_SIZE);
572 AllocData data;
573 data.align = (unsigned int)GetDataAlignment(format, prod_usage, cons_usage);
574 size = ALIGN(size, data.align);
575 data.size = size;
576 data.handle = (uintptr_t)handle;
577
578 // Allocate memory
579 data.uncached = allocator_->UseUncached(prod_usage);
580 err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
581 if (err) {
582 ALOGE("gralloc failed to allocate err=%s", strerror(-err));
583 *handle = 0;
584 return err;
585 }
586
587 // allocate memory for MetaData
588 AllocData e_data;
589 e_data.size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
590 e_data.handle = data.handle;
591 e_data.align = (unsigned int)getpagesize();
592
593 ColorSpace_t colorSpace = ITU_R_601;
594 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
595 colorSpace = ITU_R_601_FR;
596 }
597
598 err =
599 allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
600 ALOGE_IF(err, "gralloc failed for e_daata error=%s", strerror(-err));
601
602 flags = GetHandleFlags(format, prod_usage, cons_usage);
603 flags |= data.alloc_type;
604
605 // Create handle
606 uint64_t eBaseAddr = (uint64_t)(e_data.base) + e_data.offset;
607 private_handle_t *hnd = new private_handle_t(data.fd, size, flags, bufferType, format, aligned_w,
608 aligned_h, e_data.fd, e_data.offset, eBaseAddr,
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700609 unaligned_w, unaligned_h, prod_usage, cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530610
611 hnd->offset = data.offset;
612 hnd->base = (uint64_t)(data.base) + data.offset;
613 hnd->gpuaddr = 0;
614
615 setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
Saurabh Shah7d476ed2016-06-27 16:40:58 -0700616 if (qdutils::getDriverType() == qdutils::DriverType::DRM &&
617 cons_usage & GRALLOC_USAGE_HW_COMPOSER) {
618 DRMBuffer buf = {};
619 int ret = getPlaneStrideOffset(hnd, buf.stride, buf.offset,
620 &buf.num_planes);
621 if (ret < 0) {
622 ALOGE("%s failed", __FUNCTION__);
623 return ret;
624 }
625
626 buf.fd = hnd->fd;
627 buf.width = hnd->width;
628 buf.height = hnd->height;
629 getDRMFormat(hnd->format, flags, &buf.drm_format,
630 &buf.drm_format_modifier);
631
632 DRMMaster *master = nullptr;
633 ret = DRMMaster::GetInstance(&master);
634 if (ret < 0) {
635 ALOGE("%s Failed to acquire DRMMaster instance", __FUNCTION__);
636 return ret;
637 }
638
639 ret = master->CreateFbId(buf, &hnd->gem_handle, &hnd->fb_id);
640 if (ret < 0) {
641 ALOGE("%s: CreateFbId failed. width %d, height %d, " \
642 "format: %s, stride %u, error %d", __FUNCTION__,
643 buf.width, buf.height,
644 qdutils::GetHALPixelFormatString(hnd->format),
645 buf.stride[0], errno);
646 return ret;
647 }
648 }
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530649
650 *handle = hnd;
651
652 // we have just allocated the buffer & mmapped. Add to map
653 locker_.lock();
654 handles_map_.insert(std::pair<private_handle_t const *, int>(hnd, 1));
655 locker_.unlock();
656
657 return err;
658}
659
660int BufferManager::GetBufferType(int inputFormat) {
661 int buffer_type = BUFFER_TYPE_VIDEO;
662 if (IsUncompressedRGBFormat(inputFormat)) {
663 // RGB formats
664 buffer_type = BUFFER_TYPE_UI;
665 }
666
667 return buffer_type;
668}
669
670int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
671 unsigned int bufferSize) {
672 if (!handle)
673 return -EINVAL;
674
675 int format = descriptor.GetFormat();
676 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
677 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
678
679 // Get implementation defined format
680 int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
681
682 bool use_fb_mem = false;
683 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && map_fb_mem_) {
684 use_fb_mem = true;
685 }
686
687 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && ubwc_for_fb_) {
688 prod_usage =
689 (gralloc1_producer_usage_t)(prod_usage | GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC);
690 }
691
692 unsigned int size;
693 unsigned int alignedw, alignedh;
694 int buffer_type = GetBufferType(gralloc_format);
695 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
696
697 size = (bufferSize >= size) ? bufferSize : size;
698
699 int err = 0;
700 if (use_fb_mem) {
701 // TODO(user): TBD Framebuffer specific implementation in a seperate file/class
702 } else {
703 err = AllocateBuffer(size, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
704 descriptor.GetHeight(), format, buffer_type, descriptor.GetProducerUsage(),
705 descriptor.GetConsumerUsage(), handle);
706 }
707
708 if (err < 0) {
709 return err;
710 }
711
712 return 0;
713}
714
715gralloc1_error_t BufferManager::Perform(int operation, va_list args) {
716 switch (operation) {
717 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
718 int fd = va_arg(args, int);
719 unsigned int size = va_arg(args, unsigned int);
720 unsigned int offset = va_arg(args, unsigned int);
721 void *base = va_arg(args, void *);
722 int width = va_arg(args, int);
723 int height = va_arg(args, int);
724 int format = va_arg(args, int);
725
726 native_handle_t **handle = va_arg(args, native_handle_t **);
727 private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
728 native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
729 if (hnd) {
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700730 unsigned int alignedw = 0, alignedh = 0;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530731 hnd->magic = private_handle_t::kMagic;
732 hnd->fd = fd;
733 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
734 hnd->size = size;
735 hnd->offset = offset;
736 hnd->base = uint64_t(base) + offset;
737 hnd->gpuaddr = 0;
Ramkumar Radhakrishnanba55eac2016-08-26 22:33:48 -0700738 BufferDescriptor descriptor(width, height, format);
739 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
740 hnd->unaligned_width = width;
741 hnd->unaligned_height = height;
742 hnd->width = alignedw;
743 hnd->height = alignedh;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530744 hnd->format = format;
745 *handle = reinterpret_cast<native_handle_t *>(hnd);
746 }
747 } break;
748
749 case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
750 int width = va_arg(args, int);
751 int format = va_arg(args, int);
752 int *stride = va_arg(args, int *);
753 unsigned int alignedw = 0, alignedh = 0;
754 BufferDescriptor descriptor(width, width, format);
755 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
756 *stride = INT(alignedw);
757 } break;
758
759 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
760 private_handle_t *hnd = va_arg(args, private_handle_t *);
761 int *stride = va_arg(args, int *);
762 if (private_handle_t::validate(hnd) != 0) {
763 return GRALLOC1_ERROR_BAD_HANDLE;
764 }
765
766 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
767 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
768 *stride = metadata->bufferDim.sliceWidth;
769 } else {
770 *stride = hnd->width;
771 }
772 } break;
773
774 // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
775 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
776 private_handle_t *hnd = va_arg(args, private_handle_t *);
777 int *stride = va_arg(args, int *);
778 int *height = va_arg(args, int *);
779 if (private_handle_t::validate(hnd) != 0) {
780 return GRALLOC1_ERROR_BAD_HANDLE;
781 }
782
783 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
784 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
785 *stride = metadata->bufferDim.sliceWidth;
786 *height = metadata->bufferDim.sliceHeight;
787 } else {
788 *stride = hnd->width;
789 *height = hnd->height;
790 }
791 } break;
792
793 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
794 // TODO(user): Usage is split now. take care of it from Gfx client.
795 // see if we can directly expect descriptor from gfx client.
796 int width = va_arg(args, int);
797 int height = va_arg(args, int);
798 int format = va_arg(args, int);
799 uint64_t producer_usage = va_arg(args, uint64_t);
800 uint64_t consumer_usage = va_arg(args, uint64_t);
801 gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
802 gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
803
804 int *aligned_width = va_arg(args, int *);
805 int *aligned_height = va_arg(args, int *);
806 int *tile_enabled = va_arg(args, int *);
807 unsigned int alignedw, alignedh;
808 BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
Saurabh Shahc5b2b702016-10-24 17:16:01 -0700809 *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530810
811 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
812 *aligned_width = INT(alignedw);
813 *aligned_height = INT(alignedh);
814 } break;
815
816 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
817 private_handle_t *hnd = va_arg(args, private_handle_t *);
818 int *color_space = va_arg(args, int *);
819 if (private_handle_t::validate(hnd) != 0) {
820 return GRALLOC1_ERROR_BAD_HANDLE;
821 }
822 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
Arun Kumar K.Rb2771bf2016-10-03 21:38:23 -0700823 if (!metadata) {
824 return GRALLOC1_ERROR_BAD_HANDLE;
825#ifdef USE_COLOR_METADATA
826 } else if (metadata->operation & COLOR_METADATA) {
827 ColorMetaData *colorMetadata = &metadata->color;
828 switch (colorMetadata->colorPrimaries) {
829 case ColorPrimaries_BT709_5:
830 *color_space = HAL_CSC_ITU_R_709;
831 break;
832 case ColorPrimaries_BT601_6_525:
833 *color_space = ((colorMetadata->range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
834 break;
835 case ColorPrimaries_BT2020:
836 *color_space = (colorMetadata->range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
837 break;
838 default:
839 ALOGE("Unknown Color Space = %d", colorMetadata->colorPrimaries);
840 break;
841 }
842#endif
843 } else if (metadata->operation & UPDATE_COLOR_SPACE) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530844 *color_space = metadata->colorSpace;
845 }
846 } break;
847 case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
848 private_handle_t *hnd = va_arg(args, private_handle_t *);
849 android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
850 if (private_handle_t::validate(hnd) != 0) {
851 return GRALLOC1_ERROR_BAD_HANDLE;
852 }
853 if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
854 return GRALLOC1_ERROR_UNDEFINED;
855 }
856 } break;
857
858 case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
859 private_handle_t *hnd = va_arg(args, private_handle_t *);
860 int *map_secure_buffer = va_arg(args, int *);
861 if (private_handle_t::validate(hnd) != 0) {
862 return GRALLOC1_ERROR_BAD_HANDLE;
863 }
864 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
865 if (metadata && metadata->operation & MAP_SECURE_BUFFER) {
866 *map_secure_buffer = metadata->mapSecureBuffer;
867 } else {
868 *map_secure_buffer = 0;
869 }
870 } break;
871
872 case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
873 private_handle_t *hnd = va_arg(args, private_handle_t *);
874 int *flag = va_arg(args, int *);
875 if (private_handle_t::validate(hnd) != 0) {
876 return GRALLOC1_ERROR_BAD_HANDLE;
877 }
878 *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
879 } break;
880
881 case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
882 private_handle_t *hnd = va_arg(args, private_handle_t *);
883 void **rgb_data = va_arg(args, void **);
884 if (private_handle_t::validate(hnd) != 0) {
885 return GRALLOC1_ERROR_BAD_HANDLE;
886 }
887 if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
888 return GRALLOC1_ERROR_UNDEFINED;
889 }
890 } break;
891
892 default:
893 break;
894 }
895
896 return GRALLOC1_ERROR_NONE;
897}
898
899} // namespace gralloc1