1 /*
2 * Copyright (C) 2011 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 #include <string.h>
17 #include <pthread.h>
18 #include <limits.h>
19 #include <cutils/ashmem.h>
20 #include <unistd.h>
21 #include <errno.h>
22 #include <dlfcn.h>
23 #include <sys/mman.h>
24 #include "gralloc_cb.h"
25 #include "goldfish_dma.h"
26 #include "FormatConversions.h"
27 #include "HostConnection.h"
28 #include "ProcessPipe.h"
29 #include "glUtils.h"
30 #include <utils/CallStack.h>
31 #include <cutils/log.h>
32 #include <cutils/properties.h>
33
34 #include <set>
35 #include <string>
36 #include <sstream>
37
38 /* Set to 1 or 2 to enable debug traces */
39 #define DEBUG 0
40
41 #if DEBUG >= 1
42 # define D(...) ALOGD(__VA_ARGS__)
43 #else
44 # define D(...) ((void)0)
45 #endif
46
47 #if DEBUG >= 2
48 # define DD(...) ALOGD(__VA_ARGS__)
49 #else
50 # define DD(...) ((void)0)
51 #endif
52
53 #define DBG_FUNC DBG("%s\n", __FUNCTION__)
54
55 #ifdef GOLDFISH_HIDL_GRALLOC
56 static bool isHidlGralloc = true;
57 #else
58 static bool isHidlGralloc = false;
59 #endif
60
getOpenCountPtr(cb_handle_t * cb)61 int32_t* getOpenCountPtr(cb_handle_t* cb) {
62 return ((int32_t*)cb->ashmemBase) + 1;
63 }
64
getAshmemColorOffset(cb_handle_t * cb)65 uint32_t getAshmemColorOffset(cb_handle_t* cb) {
66 uint32_t res = 0;
67 if (cb->canBePosted()) res = sizeof(intptr_t);
68 if (isHidlGralloc) res = sizeof(intptr_t) * 2;
69 return res;
70 }
71
72 //
73 // our private gralloc module structure
74 //
75 struct private_module_t {
76 gralloc_module_t base;
77 };
78
79 /* If not NULL, this is a pointer to the fallback module.
80 * This really is gralloc.default, which we'll use if we detect
81 * that the emulator we're running in does not support GPU emulation.
82 */
83 static gralloc_module_t* sFallback;
84 static pthread_once_t sFallbackOnce = PTHREAD_ONCE_INIT;
85
86 static void fallback_init(void); // forward
87
88 typedef struct _alloc_list_node {
89 buffer_handle_t handle;
90 _alloc_list_node *next;
91 _alloc_list_node *prev;
92 } AllocListNode;
93
94 struct MemRegionInfo {
95 void* ashmemBase;
96 mutable uint32_t refCount;
97 };
98
99 struct MemRegionInfoCmp {
operator ()MemRegionInfoCmp100 bool operator()(const MemRegionInfo& a, const MemRegionInfo& b) const {
101 return a.ashmemBase < b.ashmemBase;
102 }
103 };
104
105 typedef std::set<MemRegionInfo, MemRegionInfoCmp> MemRegionSet;
106 typedef MemRegionSet::iterator mem_region_handle_t;
107
108 //
109 // Our gralloc device structure (alloc interface)
110 //
111 struct gralloc_device_t {
112 alloc_device_t device;
113
114 AllocListNode *allocListHead; // double linked list of allocated buffers
115 MemRegionSet ashmemRegions; // to track allocations of each ashmem region
116 pthread_mutex_t lock;
117 };
118
119 struct gralloc_memregions_t {
120 MemRegionSet ashmemRegions;
121 };
122
123 #define INITIAL_DMA_REGION_SIZE 4096
124 struct gralloc_dmaregion_t {
125 goldfish_dma_context goldfish_dma;
126 uint32_t sz;
127 uint32_t refcount;
128 pthread_mutex_t lock;
129 };
130
131 // global device instance
132 static gralloc_memregions_t* s_grdev = NULL;
133 static gralloc_dmaregion_t* s_grdma = NULL;
134
init_gralloc_memregions()135 void init_gralloc_memregions() {
136 if (s_grdev) return;
137 s_grdev = new gralloc_memregions_t;
138 }
139
init_gralloc_dmaregion()140 void init_gralloc_dmaregion() {
141 D("%s: call\n", __FUNCTION__);
142 if (s_grdma) return;
143
144 s_grdma = new gralloc_dmaregion_t;
145 s_grdma->sz = INITIAL_DMA_REGION_SIZE;
146 s_grdma->refcount = 0;
147
148 pthread_mutex_init(&s_grdma->lock, NULL);
149 pthread_mutex_lock(&s_grdma->lock);
150 goldfish_dma_create_region(s_grdma->sz, &s_grdma->goldfish_dma);
151 pthread_mutex_unlock(&s_grdma->lock);
152 }
153
get_gralloc_dmaregion()154 void get_gralloc_dmaregion() {
155 if (!s_grdma) return;
156 pthread_mutex_lock(&s_grdma->lock);
157 s_grdma->refcount++;
158 D("%s: call. refcount: %u\n", __FUNCTION__, s_grdma->refcount);
159 pthread_mutex_unlock(&s_grdma->lock);
160 }
161
resize_gralloc_dmaregion_locked(uint32_t new_sz)162 static void resize_gralloc_dmaregion_locked(uint32_t new_sz) {
163 if (!s_grdma) return;
164 if (s_grdma->goldfish_dma.mapped) {
165 goldfish_dma_unmap(&s_grdma->goldfish_dma);
166 }
167 close(s_grdma->goldfish_dma.fd);
168 goldfish_dma_create_region(new_sz, &s_grdma->goldfish_dma);
169 s_grdma->sz = new_sz;
170 }
171
put_gralloc_dmaregion()172 bool put_gralloc_dmaregion() {
173 if (!s_grdma) return false;
174 pthread_mutex_lock(&s_grdma->lock);
175 D("%s: call. refcount before: %u\n", __FUNCTION__, s_grdma->refcount);
176 s_grdma->refcount--;
177 bool shouldDelete = !s_grdma->refcount;
178 if (shouldDelete) {
179 D("%s: should delete!\n", __FUNCTION__);
180 resize_gralloc_dmaregion_locked(INITIAL_DMA_REGION_SIZE);
181 D("%s: done\n", __FUNCTION__);
182 }
183 pthread_mutex_unlock(&s_grdma->lock);
184 D("%s: exit\n", __FUNCTION__);
185 return shouldDelete;
186 }
187
gralloc_dmaregion_register_ashmem(uint32_t sz)188 void gralloc_dmaregion_register_ashmem(uint32_t sz) {
189 if (!s_grdma) return;
190 pthread_mutex_lock(&s_grdma->lock);
191 D("%s: for sz %u, refcount %u", __FUNCTION__, sz, s_grdma->refcount);
192 uint32_t new_sz = std::max(s_grdma->sz, sz);
193 if (new_sz != s_grdma->sz) {
194 D("%s: change sz from %u to %u", __FUNCTION__, s_grdma->sz, sz);
195 resize_gralloc_dmaregion_locked(new_sz);
196 }
197 if (!s_grdma->goldfish_dma.mapped) {
198 goldfish_dma_map(&s_grdma->goldfish_dma);
199 }
200 pthread_mutex_unlock(&s_grdma->lock);
201 }
202
get_mem_region(void * ashmemBase)203 void get_mem_region(void* ashmemBase) {
204 init_gralloc_memregions();
205 D("%s: call for %p", __FUNCTION__, ashmemBase);
206 MemRegionInfo lookup;
207 lookup.ashmemBase = ashmemBase;
208 mem_region_handle_t handle = s_grdev->ashmemRegions.find(lookup);
209 if (handle == s_grdev->ashmemRegions.end()) {
210 MemRegionInfo newRegion;
211 newRegion.ashmemBase = ashmemBase;
212 newRegion.refCount = 1;
213 s_grdev->ashmemRegions.insert(newRegion);
214 } else {
215 handle->refCount++;
216 }
217 }
218
put_mem_region(void * ashmemBase)219 bool put_mem_region(void* ashmemBase) {
220 init_gralloc_memregions();
221 D("%s: call for %p", __FUNCTION__, ashmemBase);
222 MemRegionInfo lookup;
223 lookup.ashmemBase = ashmemBase;
224 mem_region_handle_t handle = s_grdev->ashmemRegions.find(lookup);
225 if (handle == s_grdev->ashmemRegions.end()) {
226 ALOGE("%s: error: tried to put nonexistent mem region!", __FUNCTION__);
227 return true;
228 } else {
229 handle->refCount--;
230 bool shouldRemove = !handle->refCount;
231 if (shouldRemove) {
232 s_grdev->ashmemRegions.erase(lookup);
233 }
234 return shouldRemove;
235 }
236 }
237
dump_regions()238 void dump_regions() {
239 init_gralloc_memregions();
240 mem_region_handle_t curr = s_grdev->ashmemRegions.begin();
241 std::stringstream res;
242 for (; curr != s_grdev->ashmemRegions.end(); curr++) {
243 res << "\tashmem base " << curr->ashmemBase << " refcount " << curr->refCount << "\n";
244 }
245 ALOGD("ashmem region dump [\n%s]", res.str().c_str());
246 }
247
248 #if DEBUG
249
250 #define GET_ASHMEM_REGION(cb) \
251 dump_regions(); \
252 get_mem_region((void*)cb->ashmemBase); \
253 dump_regions(); \
254
255 #define PUT_ASHMEM_REGION(cb) \
256 dump_regions(); \
257 bool SHOULD_UNMAP = put_mem_region((void*)cb->ashmemBase); \
258 dump_regions(); \
259
260 #else
261
262 #define GET_ASHMEM_REGION(cb) \
263 get_mem_region((void*)cb->ashmemBase); \
264
265 #define PUT_ASHMEM_REGION(cb) \
266 bool SHOULD_UNMAP = put_mem_region((void*)cb->ashmemBase); \
267
268 #endif
269
270 //
271 // Our framebuffer device structure
272 //
273 struct fb_device_t {
274 framebuffer_device_t device;
275 };
276
map_buffer(cb_handle_t * cb,void ** vaddr)277 static int map_buffer(cb_handle_t *cb, void **vaddr)
278 {
279 if (cb->fd < 0 || cb->ashmemSize <= 0) {
280 return -EINVAL;
281 }
282
283 int map_flags = MAP_SHARED;
284 if (isHidlGralloc) map_flags |= MAP_ANONYMOUS;
285
286 void *addr = mmap(0, cb->ashmemSize, PROT_READ | PROT_WRITE,
287 MAP_SHARED, cb->fd, 0);
288 if (addr == MAP_FAILED) {
289 ALOGE("%s: failed to map ashmem region!", __FUNCTION__);
290 return -errno;
291 }
292
293 cb->ashmemBase = intptr_t(addr);
294 cb->ashmemBasePid = getpid();
295 D("%s: %p mapped ashmem base %p size %d\n", __FUNCTION__,
296 cb, cb->ashmemBase, cb->ashmemSize);
297
298 *vaddr = addr;
299 return 0;
300 }
301
302 #define DEFINE_HOST_CONNECTION \
303 HostConnection *hostCon = HostConnection::get(); \
304 ExtendedRCEncoderContext *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
305
306 #define DEFINE_AND_VALIDATE_HOST_CONNECTION \
307 HostConnection *hostCon = HostConnection::get(); \
308 if (!hostCon) { \
309 ALOGE("gralloc: Failed to get host connection\n"); \
310 return -EIO; \
311 } \
312 ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \
313 if (!rcEnc) { \
314 ALOGE("gralloc: Failed to get renderControl encoder context\n"); \
315 return -EIO; \
316 }
317
318 #if PLATFORM_SDK_VERSION < 18
319 // On older APIs, just define it as a value no one is going to use.
320 #define HAL_PIXEL_FORMAT_YCbCr_420_888 0xFFFFFFFF
321 #endif
322
updateHostColorBuffer(cb_handle_t * cb,bool doLocked,char * pixels)323 static void updateHostColorBuffer(cb_handle_t* cb,
324 bool doLocked,
325 char* pixels) {
326 D("%s: call. doLocked=%d", __FUNCTION__, doLocked);
327 DEFINE_HOST_CONNECTION;
328 int bpp = glUtilsPixelBitSize(cb->glFormat, cb->glType) >> 3;
329 int left = doLocked ? cb->lockedLeft : 0;
330 int top = doLocked ? cb->lockedTop : 0;
331 int width = doLocked ? cb->lockedWidth : cb->width;
332 int height = doLocked ? cb->lockedHeight : cb->height;
333
334 char* to_send = pixels;
335 uint32_t rgbSz = width * height * bpp;
336 uint32_t send_buffer_size = rgbSz;
337 bool is_rgb_format =
338 cb->frameworkFormat != HAL_PIXEL_FORMAT_YV12 &&
339 cb->frameworkFormat != HAL_PIXEL_FORMAT_YCbCr_420_888;
340
341 char* convertedBuf = NULL;
342 if ((doLocked && is_rgb_format) ||
343 (!s_grdma &&
344 (doLocked || !is_rgb_format))) {
345 convertedBuf = new char[rgbSz];
346 to_send = convertedBuf;
347 send_buffer_size = rgbSz;
348 }
349
350 if (doLocked && is_rgb_format) {
351 copy_rgb_buffer_from_unlocked(
352 to_send, pixels,
353 cb->width,
354 width, height, top, left, bpp);
355 }
356
357 if (s_grdma) {
358 if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
359 get_yv12_offsets(width, height, NULL, NULL,
360 &send_buffer_size);
361 }
362 if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
363 get_yuv420p_offsets(width, height, NULL, NULL,
364 &send_buffer_size);
365 }
366
367 rcEnc->bindDmaContext(&s_grdma->goldfish_dma);
368 D("%s: call. dma update with sz=%u", __FUNCTION__, send_buffer_size);
369 pthread_mutex_lock(&s_grdma->lock);
370 rcEnc->rcUpdateColorBufferDMA(rcEnc, cb->hostHandle,
371 left, top, width, height,
372 cb->glFormat, cb->glType,
373 to_send, send_buffer_size);
374 pthread_mutex_unlock(&s_grdma->lock);
375 } else {
376 if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
377 yv12_to_rgb888(to_send, pixels,
378 width, height, left, top,
379 left + width - 1, top + height - 1);
380 }
381 if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
382 yuv420p_to_rgb888(to_send, pixels,
383 width, height, left, top,
384 left + width - 1, top + height - 1);
385 }
386 rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle,
387 left, top, width, height,
388 cb->glFormat, cb->glType, to_send);
389 }
390
391 if (convertedBuf) delete [] convertedBuf;
392 }
393
394 #ifndef GL_RGBA16F
395 #define GL_RGBA16F 0x881A
396 #endif // GL_RGBA16F
397 #ifndef GL_UNSIGNED_INT_10_10_10_2
398 #define GL_UNSIGNED_INT_10_10_10_2 0x8DF6
399 #endif // GL_UNSIGNED_INT_10_10_10_2
400 #ifndef GL_HALF_FLOAT
401 #define GL_HALF_FLOAT 0x140B
402 #endif // GL_HALF_FLOAT
403 //
404 // gralloc device functions (alloc interface)
405 //
gralloc_alloc(alloc_device_t * dev,int w,int h,int format,int usage,buffer_handle_t * pHandle,int * pStride)406 static int gralloc_alloc(alloc_device_t* dev,
407 int w, int h, int format, int usage,
408 buffer_handle_t* pHandle, int* pStride)
409 {
410 D("gralloc_alloc w=%d h=%d usage=0x%x format=0x%x\n", w, h, usage, format);
411
412 gralloc_device_t *grdev = (gralloc_device_t *)dev;
413 if (!grdev || !pHandle || !pStride) {
414 ALOGE("gralloc_alloc: Bad inputs (grdev: %p, pHandle: %p, pStride: %p",
415 grdev, pHandle, pStride);
416 return -EINVAL;
417 }
418
419 //
420 // Note: in screen capture mode, both sw_write and hw_write will be on
421 // and this is a valid usage
422 //
423 bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
424 bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
425 bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
426 #if PLATFORM_SDK_VERSION >= 17
427 bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
428 bool hw_cam_read = (usage & GRALLOC_USAGE_HW_CAMERA_READ);
429 #else // PLATFORM_SDK_VERSION
430 bool hw_cam_write = false;
431 bool hw_cam_read = false;
432 #endif // PLATFORM_SDK_VERSION
433 #if PLATFORM_SDK_VERSION >= 15
434 bool hw_vid_enc_read = usage & GRALLOC_USAGE_HW_VIDEO_ENCODER;
435 #else // PLATFORM_SDK_VERSION
436 bool hw_vid_enc_read = false;
437 #endif // PLATFORM_SDK_VERSION
438
439 // Keep around original requested format for later validation
440 int frameworkFormat = format;
441 // Pick the right concrete pixel format given the endpoints as encoded in
442 // the usage bits. Every end-point pair needs explicit listing here.
443 #if PLATFORM_SDK_VERSION >= 17
444 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
445 // Camera as producer
446 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
447 if (usage & GRALLOC_USAGE_HW_TEXTURE) {
448 // Camera-to-display is RGBA
449 format = HAL_PIXEL_FORMAT_RGBA_8888;
450 } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
451 // Camera-to-encoder is NV21
452 format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
453 } else if ((usage & GRALLOC_USAGE_HW_CAMERA_MASK) ==
454 GRALLOC_USAGE_HW_CAMERA_ZSL) {
455 // Camera-to-ZSL-queue is RGB_888
456 format = HAL_PIXEL_FORMAT_RGB_888;
457 }
458 }
459
460 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
461 ALOGE("gralloc_alloc: Requested auto format selection, "
462 "but no known format for this usage: %d x %d, usage %x",
463 w, h, usage);
464 return -EINVAL;
465 }
466 }
467 else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
468 ALOGW("gralloc_alloc: Requested YCbCr_420_888, taking experimental path. "
469 "usage: %d x %d, usage %x",
470 w, h, usage);
471 }
472 #endif // PLATFORM_SDK_VERSION >= 17
473 bool yuv_format = false;
474
475 int ashmem_size = 0;
476 int stride = w;
477
478 GLenum glFormat = 0;
479 GLenum glType = 0;
480 EmulatorFrameworkFormat selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_GL_COMPATIBLE;
481
482 int bpp = 0;
483 int align = 1;
484 switch (format) {
485 case HAL_PIXEL_FORMAT_RGBA_8888:
486 case HAL_PIXEL_FORMAT_RGBX_8888:
487 case HAL_PIXEL_FORMAT_BGRA_8888:
488 bpp = 4;
489 glFormat = GL_RGBA;
490 glType = GL_UNSIGNED_BYTE;
491 break;
492 case HAL_PIXEL_FORMAT_RGB_888:
493 bpp = 3;
494 glFormat = GL_RGB;
495 glType = GL_UNSIGNED_BYTE;
496 break;
497 case HAL_PIXEL_FORMAT_RGB_565:
498 bpp = 2;
499 glFormat = GL_RGB;
500 glType = GL_UNSIGNED_SHORT_5_6_5;
501 break;
502 #if PLATFORM_SDK_VERSION >= 26
503 case HAL_PIXEL_FORMAT_RGBA_FP16:
504 bpp = 8;
505 glFormat = GL_RGBA16F;
506 glType = GL_HALF_FLOAT;
507 break;
508 case HAL_PIXEL_FORMAT_RGBA_1010102:
509 bpp = 4;
510 glFormat = GL_RGBA;
511 glType = GL_UNSIGNED_INT_10_10_10_2;
512 break;
513 #endif // PLATFORM_SDK_VERSION >= 26
514 #if PLATFORM_SDK_VERSION >= 21
515 case HAL_PIXEL_FORMAT_RAW16:
516 case HAL_PIXEL_FORMAT_Y16:
517 #elif PLATFORM_SDK_VERSION >= 16
518 case HAL_PIXEL_FORMAT_RAW_SENSOR:
519 #endif
520 bpp = 2;
521 align = 16*bpp;
522 if (! ((sw_read || hw_cam_read) && (sw_write || hw_cam_write) ) ) {
523 // Raw sensor data or Y16 only goes between camera and CPU
524 return -EINVAL;
525 }
526 // Not expecting to actually create any GL surfaces for this
527 glFormat = GL_LUMINANCE;
528 glType = GL_UNSIGNED_SHORT;
529 break;
530 #if PLATFORM_SDK_VERSION >= 17
531 case HAL_PIXEL_FORMAT_BLOB:
532 bpp = 1;
533 if (! (sw_read) ) {
534 // Blob data cannot be used by HW other than camera emulator
535 // But there is a CTS test trying to have access to it
536 // BUG: https://buganizer.corp.google.com/issues/37719518
537 return -EINVAL;
538 }
539 // Not expecting to actually create any GL surfaces for this
540 glFormat = GL_LUMINANCE;
541 glType = GL_UNSIGNED_BYTE;
542 break;
543 #endif // PLATFORM_SDK_VERSION >= 17
544 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
545 align = 1;
546 bpp = 1; // per-channel bpp
547 yuv_format = true;
548 // Not expecting to actually create any GL surfaces for this
549 break;
550 case HAL_PIXEL_FORMAT_YV12:
551 align = 16;
552 bpp = 1; // per-channel bpp
553 yuv_format = true;
554 // We are going to use RGB888 on the host
555 glFormat = GL_RGB;
556 glType = GL_UNSIGNED_BYTE;
557 selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YV12;
558 break;
559 case HAL_PIXEL_FORMAT_YCbCr_420_888:
560 align = 1;
561 bpp = 1; // per-channel bpp
562 yuv_format = true;
563 // We are going to use RGB888 on the host
564 glFormat = GL_RGB;
565 glType = GL_UNSIGNED_BYTE;
566 selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YUV_420_888;
567 break;
568 default:
569 ALOGE("gralloc_alloc: Unknown format %d", format);
570 return -EINVAL;
571 }
572
573 //
574 // Allocate ColorBuffer handle on the host (only if h/w access is allowed)
575 // Only do this for some h/w usages, not all.
576 // Also do this if we need to read from the surface, in this case the
577 // rendering will still happen on the host but we also need to be able to
578 // read back from the color buffer, which requires that there is a buffer
579 //
580 bool needHostCb = (!yuv_format ||
581 frameworkFormat == HAL_PIXEL_FORMAT_YV12 ||
582 frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) &&
583 #if PLATFORM_SDK_VERSION >= 15
584 (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
585 GRALLOC_USAGE_HW_2D | GRALLOC_USAGE_HW_COMPOSER |
586 GRALLOC_USAGE_HW_VIDEO_ENCODER |
587 GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_SW_READ_MASK))
588 #else // PLATFORM_SDK_VERSION
589 (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
590 GRALLOC_USAGE_HW_2D |
591 GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_SW_READ_MASK))
592 #endif // PLATFORM_SDK_VERSION
593 ;
594
595 if (isHidlGralloc) {
596 if (needHostCb || (usage & GRALLOC_USAGE_HW_FB)) {
597 // keep space for postCounter
598 // AND openCounter for all host cb
599 ashmem_size += sizeof(uint32_t) * 2;
600 }
601 } else {
602 if (usage & GRALLOC_USAGE_HW_FB) {
603 // keep space for postCounter
604 ashmem_size += sizeof(uint32_t) * 1;
605 }
606 }
607
608 // API26 always expect at least one file descriptor is associated with
609 // one color buffer
610 // BUG: 37719038
611 if (PLATFORM_SDK_VERSION >= 26 ||
612 sw_read || sw_write || hw_cam_write || hw_vid_enc_read) {
613 // keep space for image on guest memory if SW access is needed
614 // or if the camera is doing writing
615 if (yuv_format) {
616 size_t yStride = (w*bpp + (align - 1)) & ~(align-1);
617 size_t uvStride = (yStride / 2 + (align - 1)) & ~(align-1);
618 size_t uvHeight = h / 2;
619 ashmem_size += yStride * h + 2 * (uvHeight * uvStride);
620 stride = yStride / bpp;
621 } else {
622 size_t bpr = (w*bpp + (align-1)) & ~(align-1);
623 ashmem_size += (bpr * h);
624 stride = bpr / bpp;
625 }
626 }
627
628 D("gralloc_alloc format=%d, ashmem_size=%d, stride=%d, tid %d\n", format,
629 ashmem_size, stride, gettid());
630
631 //
632 // Allocate space in ashmem if needed
633 //
634 int fd = -1;
635 if (ashmem_size > 0) {
636 // round to page size;
637 ashmem_size = (ashmem_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
638
639 ALOGD("%s: Creating ashmem region of size %lu\n", __FUNCTION__, ashmem_size);
640 fd = ashmem_create_region("gralloc-buffer", ashmem_size);
641 if (fd < 0) {
642 ALOGE("gralloc_alloc failed to create ashmem region: %s\n",
643 strerror(errno));
644 return -errno;
645 }
646 }
647
648 cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage,
649 w, h, frameworkFormat, format,
650 glFormat, glType, selectedEmuFrameworkFormat);
651
652 DEFINE_HOST_CONNECTION;
653 if (ashmem_size > 0) {
654
655 //
656 // map ashmem region if exist
657 //
658 void *vaddr;
659 int err = map_buffer(cb, &vaddr);
660 if (err) {
661 close(fd);
662 delete cb;
663 return err;
664 }
665
666 cb->setFd(fd);
667
668 if (rcEnc->getDmaVersion() > 0) {
669 D("%s: creating goldfish dma region of size %lu (cb fd %d)\n", __FUNCTION__, ashmem_size, cb->fd);
670 init_gralloc_dmaregion();
671 get_gralloc_dmaregion();
672 } else {
673 cb->goldfish_dma.fd = -1;
674 }
675 } else {
676 cb->goldfish_dma.fd = -1;
677 }
678
679 if (needHostCb) {
680 if (hostCon && rcEnc) {
681 if (s_grdma) {
682 cb->hostHandle = rcEnc->rcCreateColorBufferDMA(rcEnc, w, h, glFormat, cb->emuFrameworkFormat);
683 } else {
684 cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
685 }
686 D("Created host ColorBuffer 0x%x\n", cb->hostHandle);
687 }
688
689 if (!cb->hostHandle) {
690 // Could not create colorbuffer on host !!!
691 close(fd);
692 delete cb;
693 ALOGD("%s: failed to create host cb! -EIO", __FUNCTION__);
694 return -EIO;
695 }
696
697 if (isHidlGralloc) { *getOpenCountPtr(cb) = 0; }
698 }
699
700 //
701 // alloc succeeded - insert the allocated handle to the allocated list
702 //
703 AllocListNode *node = new AllocListNode();
704 pthread_mutex_lock(&grdev->lock);
705 node->handle = cb;
706 node->next = grdev->allocListHead;
707 node->prev = NULL;
708 if (grdev->allocListHead) {
709 grdev->allocListHead->prev = node;
710 }
711 grdev->allocListHead = node;
712 pthread_mutex_unlock(&grdev->lock);
713
714 *pHandle = cb;
715 D("%s: alloc succeded, new ashmem base and size: %p %d handle: %p",
716 __FUNCTION__, cb->ashmemBase, cb->ashmemSize, cb);
717 switch (frameworkFormat) {
718 case HAL_PIXEL_FORMAT_YCbCr_420_888:
719 *pStride = 0;
720 break;
721 default:
722 *pStride = stride;
723 break;
724 }
725 return 0;
726 }
727
gralloc_free(alloc_device_t * dev,buffer_handle_t handle)728 static int gralloc_free(alloc_device_t* dev,
729 buffer_handle_t handle)
730 {
731 cb_handle_t *cb = (cb_handle_t *)handle;
732 if (!cb_handle_t::validate((cb_handle_t*)cb)) {
733 ERR("gralloc_free: invalid handle");
734 return -EINVAL;
735 }
736
737 D("%s: for buf %p ptr %p size %d\n",
738 __FUNCTION__, handle, cb->ashmemBase, cb->ashmemSize);
739
740 if (cb->hostHandle) {
741 int32_t openCount = 1;
742 int32_t* openCountPtr = &openCount;
743
744 if (isHidlGralloc) { openCountPtr = getOpenCountPtr(cb); }
745
746 if (*openCountPtr > 0) {
747 DEFINE_AND_VALIDATE_HOST_CONNECTION;
748 D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
749 rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
750 } else {
751 D("A rcCloseColorBuffer is owed!!! sdk ver: %d", PLATFORM_SDK_VERSION);
752 *openCountPtr = -1;
753 }
754 }
755
756 //
757 // detach and unmap ashmem area if present
758 //
759 if (cb->fd > 0) {
760 if (cb->ashmemSize > 0 && cb->ashmemBase) {
761 D("%s: unmapped %p", __FUNCTION__, cb->ashmemBase);
762 munmap((void *)cb->ashmemBase, cb->ashmemSize);
763 put_gralloc_dmaregion();
764 }
765 close(cb->fd);
766 }
767
768 D("%s: done", __FUNCTION__);
769 // remove it from the allocated list
770 gralloc_device_t *grdev = (gralloc_device_t *)dev;
771 pthread_mutex_lock(&grdev->lock);
772 AllocListNode *n = grdev->allocListHead;
773 while( n && n->handle != cb ) {
774 n = n->next;
775 }
776 if (n) {
777 // buffer found on list - remove it from list
778 if (n->next) {
779 n->next->prev = n->prev;
780 }
781 if (n->prev) {
782 n->prev->next = n->next;
783 }
784 else {
785 grdev->allocListHead = n->next;
786 }
787
788 delete n;
789 }
790 pthread_mutex_unlock(&grdev->lock);
791
792 delete cb;
793
794 D("%s: exit", __FUNCTION__);
795 return 0;
796 }
797
gralloc_device_close(struct hw_device_t * dev)798 static int gralloc_device_close(struct hw_device_t *dev)
799 {
800 gralloc_device_t* d = reinterpret_cast<gralloc_device_t*>(dev);
801 if (d) {
802
803 // free still allocated buffers
804 while( d->allocListHead != NULL ) {
805 gralloc_free(&d->device, d->allocListHead->handle);
806 }
807
808 // free device
809 free(d);
810 }
811 return 0;
812 }
813
fb_compositionComplete(struct framebuffer_device_t * dev)814 static int fb_compositionComplete(struct framebuffer_device_t* dev)
815 {
816 (void)dev;
817
818 return 0;
819 }
820
821 //
822 // Framebuffer device functions
823 //
fb_post(struct framebuffer_device_t * dev,buffer_handle_t buffer)824 static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
825 {
826 fb_device_t *fbdev = (fb_device_t *)dev;
827 cb_handle_t *cb = (cb_handle_t *)buffer;
828
829 if (!fbdev || !cb_handle_t::validate(cb) || !cb->canBePosted()) {
830 return -EINVAL;
831 }
832
833 // Make sure we have host connection
834 DEFINE_AND_VALIDATE_HOST_CONNECTION;
835
836 // increment the post count of the buffer
837 intptr_t *postCountPtr = (intptr_t *)cb->ashmemBase;
838 if (!postCountPtr) {
839 // This should not happen
840 return -EINVAL;
841 }
842 (*postCountPtr)++;
843
844 // send post request to host
845 rcEnc->rcFBPost(rcEnc, cb->hostHandle);
846 hostCon->flush();
847
848 return 0;
849 }
850
fb_setUpdateRect(struct framebuffer_device_t * dev,int l,int t,int w,int h)851 static int fb_setUpdateRect(struct framebuffer_device_t* dev,
852 int l, int t, int w, int h)
853 {
854 fb_device_t *fbdev = (fb_device_t *)dev;
855
856 (void)l;
857 (void)t;
858 (void)w;
859 (void)h;
860
861 if (!fbdev) {
862 return -EINVAL;
863 }
864
865 // Make sure we have host connection
866 DEFINE_AND_VALIDATE_HOST_CONNECTION;
867
868 // send request to host
869 // TODO: XXX - should be implemented
870 //rcEnc->rc_XXX
871
872 return 0;
873 }
874
fb_setSwapInterval(struct framebuffer_device_t * dev,int interval)875 static int fb_setSwapInterval(struct framebuffer_device_t* dev,
876 int interval)
877 {
878 fb_device_t *fbdev = (fb_device_t *)dev;
879
880 if (!fbdev) {
881 return -EINVAL;
882 }
883
884 // Make sure we have host connection
885 DEFINE_AND_VALIDATE_HOST_CONNECTION;
886
887 // send request to host
888 rcEnc->rcFBSetSwapInterval(rcEnc, interval);
889 hostCon->flush();
890
891 return 0;
892 }
893
fb_close(struct hw_device_t * dev)894 static int fb_close(struct hw_device_t *dev)
895 {
896 fb_device_t *fbdev = (fb_device_t *)dev;
897
898 delete fbdev;
899
900 return 0;
901 }
902
903
904 //
905 // gralloc module functions - refcount + locking interface
906 //
gralloc_register_buffer(gralloc_module_t const * module,buffer_handle_t handle)907 static int gralloc_register_buffer(gralloc_module_t const* module,
908 buffer_handle_t handle)
909 {
910
911 D("%s: start", __FUNCTION__);
912 pthread_once(&sFallbackOnce, fallback_init);
913 if (sFallback != NULL) {
914 return sFallback->registerBuffer(sFallback, handle);
915 }
916
917 D("gralloc_register_buffer(%p) called", handle);
918
919 private_module_t *gr = (private_module_t *)module;
920 cb_handle_t *cb = (cb_handle_t *)handle;
921
922 if (!gr || !cb_handle_t::validate(cb)) {
923 ERR("gralloc_register_buffer(%p): invalid buffer", cb);
924 return -EINVAL;
925 }
926
927 if (cb->hostHandle != 0) {
928 DEFINE_AND_VALIDATE_HOST_CONNECTION;
929 D("Opening host ColorBuffer 0x%x\n", cb->hostHandle);
930 rcEnc->rcOpenColorBuffer2(rcEnc, cb->hostHandle);
931 }
932
933 //
934 // if the color buffer has ashmem region and it is not mapped in this
935 // process map it now.
936 //
937 if (cb->ashmemSize > 0 && cb->mappedPid != getpid()) {
938 void *vaddr;
939 int err = map_buffer(cb, &vaddr);
940 if (err) {
941 ERR("gralloc_register_buffer(%p): map failed: %s", cb, strerror(-err));
942 return -err;
943 }
944 cb->mappedPid = getpid();
945
946 if (isHidlGralloc) {
947 int32_t* openCountPtr = getOpenCountPtr(cb);
948 if (!*openCountPtr) *openCountPtr = 1;
949 }
950
951 DEFINE_AND_VALIDATE_HOST_CONNECTION;
952 if (rcEnc->getDmaVersion() > 0) {
953 init_gralloc_dmaregion();
954 gralloc_dmaregion_register_ashmem(cb->ashmemSize);
955 }
956
957 }
958
959 if (cb->ashmemSize > 0) {
960 GET_ASHMEM_REGION(cb);
961 get_gralloc_dmaregion();
962 }
963
964 return 0;
965 }
966
gralloc_unregister_buffer(gralloc_module_t const * module,buffer_handle_t handle)967 static int gralloc_unregister_buffer(gralloc_module_t const* module,
968 buffer_handle_t handle)
969 {
970 if (sFallback != NULL) {
971 return sFallback->unregisterBuffer(sFallback, handle);
972 }
973
974 private_module_t *gr = (private_module_t *)module;
975 cb_handle_t *cb = (cb_handle_t *)handle;
976
977 if (!gr || !cb_handle_t::validate(cb)) {
978 ERR("gralloc_unregister_buffer(%p): invalid buffer", cb);
979 return -EINVAL;
980 }
981
982
983 if (cb->hostHandle) {
984 D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
985 DEFINE_AND_VALIDATE_HOST_CONNECTION;
986 rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
987
988 if (isHidlGralloc) {
989 // Queue up another rcCloseColorBuffer if applicable.
990 // invariant: have ashmem.
991 if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
992 int32_t* openCountPtr = getOpenCountPtr(cb);
993 if (*openCountPtr == -1) {
994 D("%s: revenge of the rcCloseColorBuffer!", __func__);
995 rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
996 *openCountPtr = -2;
997 }
998 }
999 }
1000 }
1001
1002 //
1003 // unmap ashmem region if it was previously mapped in this process
1004 // (through register_buffer)
1005 //
1006 if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
1007
1008 PUT_ASHMEM_REGION(cb);
1009 put_gralloc_dmaregion();
1010
1011 if (!SHOULD_UNMAP) goto done;
1012
1013 DEFINE_AND_VALIDATE_HOST_CONNECTION;
1014
1015 void *vaddr;
1016 int err = munmap((void *)cb->ashmemBase, cb->ashmemSize);
1017 if (err) {
1018 ERR("gralloc_unregister_buffer(%p): unmap failed", cb);
1019 return -EINVAL;
1020 }
1021 cb->ashmemBase = 0;
1022 cb->mappedPid = 0;
1023 D("%s: Unregister buffer previous mapped to pid %d", __FUNCTION__, getpid());
1024 }
1025
1026 done:
1027 D("gralloc_unregister_buffer(%p) done\n", cb);
1028 return 0;
1029 }
1030
1031
1032
gralloc_lock(gralloc_module_t const * module,buffer_handle_t handle,int usage,int l,int t,int w,int h,void ** vaddr)1033 static int gralloc_lock(gralloc_module_t const* module,
1034 buffer_handle_t handle, int usage,
1035 int l, int t, int w, int h,
1036 void** vaddr)
1037 {
1038 if (sFallback != NULL) {
1039 return sFallback->lock(sFallback, handle, usage, l, t, w, h, vaddr);
1040 }
1041
1042 private_module_t *gr = (private_module_t *)module;
1043 cb_handle_t *cb = (cb_handle_t *)handle;
1044
1045 if (!gr || !cb_handle_t::validate(cb)) {
1046 ALOGE("gralloc_lock bad handle\n");
1047 return -EINVAL;
1048 }
1049
1050 // Validate usage,
1051 // 1. cannot be locked for hw access
1052 // 2. lock for either sw read or write.
1053 // 3. locked sw access must match usage during alloc time.
1054 bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
1055 bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
1056 bool hw_read = (usage & GRALLOC_USAGE_HW_TEXTURE);
1057 bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
1058 #if PLATFORM_SDK_VERSION >= 17
1059 bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
1060 bool hw_cam_read = (usage & GRALLOC_USAGE_HW_CAMERA_READ);
1061 #else // PLATFORM_SDK_VERSION
1062 bool hw_cam_write = false;
1063 bool hw_cam_read = false;
1064 #endif // PLATFORM_SDK_VERSION
1065
1066 #if PLATFORM_SDK_VERSION >= 15
1067 bool hw_vid_enc_read = (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER);
1068 #else // PLATFORM_SDK_VERSION
1069 bool hw_vid_enc_read = false;
1070 #endif // PLATFORM_SDK_VERSION
1071
1072 bool sw_read_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_READ_MASK));
1073
1074 #if PLATFORM_SDK_VERSION >= 15
1075 // bug: 30088791
1076 // a buffer was created for GRALLOC_USAGE_HW_VIDEO_ENCODER usage but
1077 // later a software encoder is reading this buffer: this is actually
1078 // legit usage.
1079 sw_read_allowed = sw_read_allowed || (cb->usage & GRALLOC_USAGE_HW_VIDEO_ENCODER);
1080 #endif // PLATFORM_SDK_VERSION >= 15
1081
1082 bool sw_write_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_WRITE_MASK));
1083
1084 if ( (hw_read || hw_write) ||
1085 (!sw_read && !sw_write &&
1086 !hw_cam_write && !hw_cam_read &&
1087 !hw_vid_enc_read) ||
1088 (sw_read && !sw_read_allowed) ||
1089 (sw_write && !sw_write_allowed) ) {
1090 ALOGE("gralloc_lock usage mismatch usage=0x%x cb->usage=0x%x\n", usage,
1091 cb->usage);
1092 //This is not exactly an error and loose it up.
1093 //bug: 30784436
1094 //return -EINVAL;
1095 }
1096
1097 intptr_t postCount = 0;
1098 void *cpu_addr = NULL;
1099
1100 //
1101 // make sure ashmem area is mapped if needed
1102 //
1103 if (cb->canBePosted() || sw_read || sw_write ||
1104 hw_cam_write || hw_cam_read ||
1105 hw_vid_enc_read) {
1106 if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
1107 return -EACCES;
1108 }
1109
1110 cpu_addr = (void *)(cb->ashmemBase + getAshmemColorOffset(cb));
1111 }
1112
1113 if (cb->hostHandle) {
1114 // Make sure we have host connection
1115 DEFINE_AND_VALIDATE_HOST_CONNECTION;
1116
1117 //
1118 // flush color buffer write cache on host and get its sync status.
1119 //
1120 int hostSyncStatus = rcEnc->rcColorBufferCacheFlush(rcEnc, cb->hostHandle,
1121 postCount,
1122 sw_read);
1123 if (hostSyncStatus < 0) {
1124 // host failed the color buffer sync - probably since it was already
1125 // locked for write access. fail the lock.
1126 ALOGE("gralloc_lock cacheFlush failed postCount=%d sw_read=%d\n",
1127 postCount, sw_read);
1128 return -EBUSY;
1129 }
1130
1131 if (sw_read) {
1132 void* rgb_addr = cpu_addr;
1133 char* tmpBuf = 0;
1134 if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12 ||
1135 cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1136 // We are using RGB888
1137 tmpBuf = new char[cb->width * cb->height * 3];
1138 rgb_addr = tmpBuf;
1139 }
1140 D("gralloc_lock read back color buffer %d %d ashmem base %p sz %d\n",
1141 cb->width, cb->height, cb->ashmemBase, cb->ashmemSize);
1142 rcEnc->rcReadColorBuffer(rcEnc, cb->hostHandle,
1143 0, 0, cb->width, cb->height, cb->glFormat, cb->glType, rgb_addr);
1144 if (tmpBuf) {
1145 if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) {
1146 rgb888_to_yv12((char*)cpu_addr, tmpBuf, cb->width, cb->height, l, t, l+w-1, t+h-1);
1147 } else if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1148 rgb888_to_yuv420p((char*)cpu_addr, tmpBuf, cb->width, cb->height, l, t, l+w-1, t+h-1);
1149 }
1150 delete [] tmpBuf;
1151 }
1152 }
1153 }
1154
1155 //
1156 // is virtual address required ?
1157 //
1158 if (sw_read || sw_write || hw_cam_write || hw_cam_read || hw_vid_enc_read) {
1159 *vaddr = cpu_addr;
1160 }
1161
1162 if (sw_write || hw_cam_write) {
1163 //
1164 // Keep locked region if locked for s/w write access.
1165 //
1166 cb->lockedLeft = l;
1167 cb->lockedTop = t;
1168 cb->lockedWidth = w;
1169 cb->lockedHeight = h;
1170 }
1171
1172 DD("gralloc_lock success. vaddr: %p, *vaddr: %p, usage: %x, cpu_addr: %p",
1173 vaddr, vaddr ? *vaddr : 0, usage, cpu_addr);
1174
1175 return 0;
1176 }
1177
gralloc_unlock(gralloc_module_t const * module,buffer_handle_t handle)1178 static int gralloc_unlock(gralloc_module_t const* module,
1179 buffer_handle_t handle)
1180 {
1181 if (sFallback != NULL) {
1182 return sFallback->unlock(sFallback, handle);
1183 }
1184
1185 private_module_t *gr = (private_module_t *)module;
1186 cb_handle_t *cb = (cb_handle_t *)handle;
1187
1188 if (!gr || !cb_handle_t::validate(cb)) {
1189 ALOGD("%s: invalid gr or cb handle. -EINVAL", __FUNCTION__);
1190 return -EINVAL;
1191 }
1192
1193 //
1194 // if buffer was locked for s/w write, we need to update the host with
1195 // the updated data
1196 //
1197 if (cb->hostHandle) {
1198
1199 // Make sure we have host connection
1200 DEFINE_AND_VALIDATE_HOST_CONNECTION;
1201
1202 void *cpu_addr = (void *)(cb->ashmemBase + getAshmemColorOffset(cb));
1203
1204 char* rgb_addr = (char *)cpu_addr;
1205 if (cb->lockedWidth < cb->width || cb->lockedHeight < cb->height) {
1206 updateHostColorBuffer(cb, true, rgb_addr);
1207 }
1208 else {
1209 updateHostColorBuffer(cb, false, rgb_addr);
1210 }
1211
1212 DD("gralloc_unlock success. cpu_addr: %p", cpu_addr);
1213 }
1214
1215 cb->lockedWidth = cb->lockedHeight = 0;
1216 return 0;
1217 }
1218
1219 #if PLATFORM_SDK_VERSION >= 18
gralloc_lock_ycbcr(gralloc_module_t const * module,buffer_handle_t handle,int usage,int l,int t,int w,int h,android_ycbcr * ycbcr)1220 static int gralloc_lock_ycbcr(gralloc_module_t const* module,
1221 buffer_handle_t handle, int usage,
1222 int l, int t, int w, int h,
1223 android_ycbcr *ycbcr)
1224 {
1225 // Not supporting fallback module for YCbCr
1226 if (sFallback != NULL) {
1227 ALOGD("%s: has fallback, return -EINVAL", __FUNCTION__);
1228 return -EINVAL;
1229 }
1230
1231 if (!ycbcr) {
1232 ALOGE("%s: got NULL ycbcr struct! -EINVAL", __FUNCTION__);
1233 return -EINVAL;
1234 }
1235
1236 private_module_t *gr = (private_module_t *)module;
1237 cb_handle_t *cb = (cb_handle_t *)handle;
1238 if (!gr || !cb_handle_t::validate(cb)) {
1239 ALOGE("%s: bad colorbuffer handle. -EINVAL", __FUNCTION__);
1240 return -EINVAL;
1241 }
1242
1243 if (cb->frameworkFormat != HAL_PIXEL_FORMAT_YV12 &&
1244 cb->frameworkFormat != HAL_PIXEL_FORMAT_YCbCr_420_888) {
1245 ALOGE("gralloc_lock_ycbcr can only be used with "
1246 "HAL_PIXEL_FORMAT_YCbCr_420_888 or HAL_PIXEL_FORMAT_YV12, got %x instead. "
1247 "-EINVAL",
1248 cb->frameworkFormat);
1249 return -EINVAL;
1250 }
1251
1252 // Make sure memory is mapped, get address
1253 if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
1254 ALOGD("%s: ashmembase not mapped. -EACCESS", __FUNCTION__);
1255 return -EACCES;
1256 }
1257
1258 uint8_t *cpu_addr = NULL;
1259 cpu_addr = (uint8_t *)(cb->ashmemBase) + getAshmemColorOffset(cb);
1260
1261 // Calculate offsets to underlying YUV data
1262 size_t yStride;
1263 size_t cStride;
1264 size_t cSize;
1265 size_t yOffset;
1266 size_t uOffset;
1267 size_t vOffset;
1268 size_t cStep;
1269 size_t align;
1270 switch (cb->format) {
1271 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1272 yStride = cb->width;
1273 cStride = cb->width;
1274 yOffset = 0;
1275 vOffset = yStride * cb->height;
1276 uOffset = vOffset + 1;
1277 cStep = 2;
1278 break;
1279 case HAL_PIXEL_FORMAT_YV12:
1280 // https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12
1281 align = 16;
1282 yStride = (cb->width + (align -1)) & ~(align-1);
1283 cStride = (yStride / 2 + (align - 1)) & ~(align-1);
1284 yOffset = 0;
1285 cSize = cStride * cb->height/2;
1286 vOffset = yStride * cb->height;
1287 uOffset = vOffset + cSize;
1288 cStep = 1;
1289 break;
1290 case HAL_PIXEL_FORMAT_YCbCr_420_888:
1291 align = 1;
1292 yStride = cb->width;
1293 cStride = yStride / 2;
1294 yOffset = 0;
1295 cSize = cStride * cb->height/2;
1296 uOffset = yStride * cb->height;
1297 vOffset = uOffset + cSize;
1298 cStep = 1;
1299 break;
1300 default:
1301 ALOGE("gralloc_lock_ycbcr unexpected internal format %x",
1302 cb->format);
1303 return -EINVAL;
1304 }
1305
1306 ycbcr->y = cpu_addr + yOffset;
1307 ycbcr->cb = cpu_addr + uOffset;
1308 ycbcr->cr = cpu_addr + vOffset;
1309 ycbcr->ystride = yStride;
1310 ycbcr->cstride = cStride;
1311 ycbcr->chroma_step = cStep;
1312
1313 // Zero out reserved fields
1314 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
1315
1316 //
1317 // Keep locked region if locked for s/w write access.
1318 //
1319 cb->lockedLeft = l;
1320 cb->lockedTop = t;
1321 cb->lockedWidth = w;
1322 cb->lockedHeight = h;
1323
1324 DD("gralloc_lock_ycbcr success. usage: %x, ycbcr.y: %p, .cb: %p, .cr: %p, "
1325 ".ystride: %d , .cstride: %d, .chroma_step: %d", usage,
1326 ycbcr->y, ycbcr->cb, ycbcr->cr, ycbcr->ystride, ycbcr->cstride,
1327 ycbcr->chroma_step);
1328
1329 return 0;
1330 }
1331 #endif // PLATFORM_SDK_VERSION >= 18
1332
gralloc_device_open(const hw_module_t * module,const char * name,hw_device_t ** device)1333 static int gralloc_device_open(const hw_module_t* module,
1334 const char* name,
1335 hw_device_t** device)
1336 {
1337 int status = -EINVAL;
1338
1339 D("gralloc_device_open %s\n", name);
1340
1341 pthread_once( &sFallbackOnce, fallback_init );
1342 if (sFallback != NULL) {
1343 return sFallback->common.methods->open(&sFallback->common, name, device);
1344 }
1345
1346 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
1347
1348 // Create host connection and keep it in the TLS.
1349 // return error if connection with host can not be established
1350 HostConnection *hostCon = HostConnection::get();
1351 if (!hostCon) {
1352 ALOGE("gralloc: failed to get host connection while opening %s\n", name);
1353 return -EIO;
1354 }
1355
1356 //
1357 // Allocate memory for the gralloc device (alloc interface)
1358 //
1359 gralloc_device_t *dev;
1360 dev = (gralloc_device_t*)malloc(sizeof(gralloc_device_t));
1361 if (NULL == dev) {
1362 return -ENOMEM;
1363 }
1364 memset(dev, 0, sizeof(gralloc_device_t));
1365
1366 // Initialize our device structure
1367 //
1368 dev->device.common.tag = HARDWARE_DEVICE_TAG;
1369 dev->device.common.version = 0;
1370 dev->device.common.module = const_cast<hw_module_t*>(module);
1371 dev->device.common.close = gralloc_device_close;
1372
1373 dev->device.alloc = gralloc_alloc;
1374 dev->device.free = gralloc_free;
1375 dev->allocListHead = NULL;
1376 pthread_mutex_init(&dev->lock, NULL);
1377
1378 *device = &dev->device.common;
1379 status = 0;
1380 }
1381 else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
1382
1383 // return error if connection with host can not be established
1384 DEFINE_AND_VALIDATE_HOST_CONNECTION;
1385
1386 //
1387 // Query the host for Framebuffer attributes
1388 //
1389 D("gralloc: query Frabuffer attribs\n");
1390 EGLint width = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
1391 D("gralloc: width=%d\n", width);
1392 EGLint height = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
1393 D("gralloc: height=%d\n", height);
1394 EGLint xdpi = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
1395 D("gralloc: xdpi=%d\n", xdpi);
1396 EGLint ydpi = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
1397 D("gralloc: ydpi=%d\n", ydpi);
1398 EGLint fps = rcEnc->rcGetFBParam(rcEnc, FB_FPS);
1399 D("gralloc: fps=%d\n", fps);
1400 EGLint min_si = rcEnc->rcGetFBParam(rcEnc, FB_MIN_SWAP_INTERVAL);
1401 D("gralloc: min_swap=%d\n", min_si);
1402 EGLint max_si = rcEnc->rcGetFBParam(rcEnc, FB_MAX_SWAP_INTERVAL);
1403 D("gralloc: max_swap=%d\n", max_si);
1404
1405 //
1406 // Allocate memory for the framebuffer device
1407 //
1408 fb_device_t *dev;
1409 dev = (fb_device_t*)malloc(sizeof(fb_device_t));
1410 if (NULL == dev) {
1411 return -ENOMEM;
1412 }
1413 memset(dev, 0, sizeof(fb_device_t));
1414
1415 // Initialize our device structure
1416 //
1417 dev->device.common.tag = HARDWARE_DEVICE_TAG;
1418 dev->device.common.version = 0;
1419 dev->device.common.module = const_cast<hw_module_t*>(module);
1420 dev->device.common.close = fb_close;
1421 dev->device.setSwapInterval = fb_setSwapInterval;
1422 dev->device.post = fb_post;
1423 dev->device.setUpdateRect = 0; //fb_setUpdateRect;
1424 dev->device.compositionComplete = fb_compositionComplete; //XXX: this is a dummy
1425
1426 const_cast<uint32_t&>(dev->device.flags) = 0;
1427 const_cast<uint32_t&>(dev->device.width) = width;
1428 const_cast<uint32_t&>(dev->device.height) = height;
1429 const_cast<int&>(dev->device.stride) = width;
1430 const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGBA_8888;
1431 const_cast<float&>(dev->device.xdpi) = xdpi;
1432 const_cast<float&>(dev->device.ydpi) = ydpi;
1433 const_cast<float&>(dev->device.fps) = fps;
1434 const_cast<int&>(dev->device.minSwapInterval) = min_si;
1435 const_cast<int&>(dev->device.maxSwapInterval) = max_si;
1436 *device = &dev->device.common;
1437
1438 status = 0;
1439 }
1440
1441 return status;
1442 }
1443
1444 //
1445 // define the HMI symbol - our module interface
1446 //
1447 static struct hw_module_methods_t gralloc_module_methods = {
1448 open: gralloc_device_open
1449 };
1450
1451 struct private_module_t HAL_MODULE_INFO_SYM = {
1452 base: {
1453 common: {
1454 tag: HARDWARE_MODULE_TAG,
1455 #if PLATFORM_SDK_VERSION >= 18
1456 module_api_version: GRALLOC_MODULE_API_VERSION_0_2,
1457 hal_api_version: 0,
1458 #elif PLATFORM_SDK_VERSION >= 16
1459 module_api_version: 1,
1460 hal_api_version: 0,
1461 #else // PLATFORM_SDK_VERSION
1462 version_major: 1,
1463 version_minor: 0,
1464 #endif // PLATFORM_SDK_VERSION
1465 id: GRALLOC_HARDWARE_MODULE_ID,
1466 name: "Graphics Memory Allocator Module",
1467 author: "The Android Open Source Project",
1468 methods: &gralloc_module_methods,
1469 dso: NULL,
1470 reserved: {0, }
1471 },
1472 registerBuffer: gralloc_register_buffer,
1473 unregisterBuffer: gralloc_unregister_buffer,
1474 lock: gralloc_lock,
1475 unlock: gralloc_unlock,
1476 perform: NULL,
1477 #if PLATFORM_SDK_VERSION >= 18
1478 lock_ycbcr: gralloc_lock_ycbcr,
1479 #endif // PLATFORM_SDK_VERSION >= 18
1480 }
1481 };
1482
1483 /* This function is called once to detect whether the emulator supports
1484 * GPU emulation (this is done by looking at the qemu.gles kernel
1485 * parameter, which must be == 1 if this is the case).
1486 *
1487 * If not, then load gralloc.default instead as a fallback.
1488 */
1489
1490 #if __LP64__
1491 static const char kGrallocDefaultSystemPath[] = "/system/lib64/hw/gralloc.default.so";
1492 static const char kGrallocDefaultVendorPath[] = "/vendor/lib64/hw/gralloc.default.so";
1493 #else
1494 static const char kGrallocDefaultSystemPath[] = "/system/lib/hw/gralloc.default.so";
1495 static const char kGrallocDefaultVendorPath[] = "/vendor/lib/hw/gralloc.default.so";
1496 #endif
1497
1498 static void
fallback_init(void)1499 fallback_init(void)
1500 {
1501 char prop[PROPERTY_VALUE_MAX];
1502 void* module;
1503
1504 // qemu.gles=0 -> no GLES 2.x support (only 1.x through software).
1505 // qemu.gles=1 -> host-side GPU emulation through EmuGL
1506 // qemu.gles=2 -> guest-side GPU emulation.
1507 property_get("ro.kernel.qemu.gles", prop, "0");
1508 if (atoi(prop) == 1) {
1509 return;
1510 }
1511 ALOGD("Emulator without host-side GPU emulation detected. "
1512 "Loading gralloc.default.so from %s...",
1513 kGrallocDefaultVendorPath);
1514 module = dlopen(kGrallocDefaultVendorPath, RTLD_LAZY | RTLD_LOCAL);
1515 if (!module) {
1516 // vendor folder didn't work. try system
1517 ALOGD("gralloc.default.so not found in /vendor. Trying %s...",
1518 kGrallocDefaultSystemPath);
1519 module = dlopen(kGrallocDefaultSystemPath, RTLD_LAZY | RTLD_LOCAL);
1520 }
1521
1522 if (module != NULL) {
1523 sFallback = reinterpret_cast<gralloc_module_t*>(dlsym(module, HAL_MODULE_INFO_SYM_AS_STR));
1524 if (sFallback == NULL) {
1525 dlclose(module);
1526 }
1527 }
1528 if (sFallback == NULL) {
1529 ALOGE("FATAL: Could not find gralloc.default.so!");
1530 }
1531 }
1532