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 "HostConnection.h"
26 #include "glUtils.h"
27 #include <cutils/log.h>
28 #include <cutils/properties.h>
29
30 /* Set to 1 or 2 to enable debug traces */
31 #define DEBUG 0
32
33 #if DEBUG >= 1
34 # define D(...) ALOGD(__VA_ARGS__)
35 #else
36 # define D(...) ((void)0)
37 #endif
38
39 #if DEBUG >= 2
40 # define DD(...) ALOGD(__VA_ARGS__)
41 #else
42 # define DD(...) ((void)0)
43 #endif
44
45 #define DBG_FUNC DBG("%s\n", __FUNCTION__)
46 //
47 // our private gralloc module structure
48 //
49 struct private_module_t {
50 gralloc_module_t base;
51 };
52
53 /* If not NULL, this is a pointer to the fallback module.
54 * This really is gralloc.default, which we'll use if we detect
55 * that the emulator we're running in does not support GPU emulation.
56 */
57 static gralloc_module_t* sFallback;
58 static pthread_once_t sFallbackOnce = PTHREAD_ONCE_INIT;
59
60 static void fallback_init(void); // forward
61
62
63 typedef struct _alloc_list_node {
64 buffer_handle_t handle;
65 _alloc_list_node *next;
66 _alloc_list_node *prev;
67 } AllocListNode;
68
69 //
70 // Our gralloc device structure (alloc interface)
71 //
72 struct gralloc_device_t {
73 alloc_device_t device;
74
75 AllocListNode *allocListHead; // double linked list of allocated buffers
76 pthread_mutex_t lock;
77 };
78
79 //
80 // Our framebuffer device structure
81 //
82 struct fb_device_t {
83 framebuffer_device_t device;
84 };
85
map_buffer(cb_handle_t * cb,void ** vaddr)86 static int map_buffer(cb_handle_t *cb, void **vaddr)
87 {
88 if (cb->fd < 0 || cb->ashmemSize <= 0) {
89 return -EINVAL;
90 }
91
92 void *addr = mmap(0, cb->ashmemSize, PROT_READ | PROT_WRITE,
93 MAP_SHARED, cb->fd, 0);
94 if (addr == MAP_FAILED) {
95 return -errno;
96 }
97
98 cb->ashmemBase = intptr_t(addr);
99 cb->ashmemBasePid = getpid();
100
101 *vaddr = addr;
102 return 0;
103 }
104
105 #define DEFINE_HOST_CONNECTION \
106 HostConnection *hostCon = HostConnection::get(); \
107 renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
108
109 #define DEFINE_AND_VALIDATE_HOST_CONNECTION \
110 HostConnection *hostCon = HostConnection::get(); \
111 if (!hostCon) { \
112 ALOGE("gralloc: Failed to get host connection\n"); \
113 return -EIO; \
114 } \
115 renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
116 if (!rcEnc) { \
117 ALOGE("gralloc: Failed to get renderControl encoder context\n"); \
118 return -EIO; \
119 }
120
121
122 //
123 // gralloc device functions (alloc interface)
124 //
gralloc_alloc(alloc_device_t * dev,int w,int h,int format,int usage,buffer_handle_t * pHandle,int * pStride)125 static int gralloc_alloc(alloc_device_t* dev,
126 int w, int h, int format, int usage,
127 buffer_handle_t* pHandle, int* pStride)
128 {
129 D("gralloc_alloc w=%d h=%d usage=0x%x\n", w, h, usage);
130
131 gralloc_device_t *grdev = (gralloc_device_t *)dev;
132 if (!grdev || !pHandle || !pStride) {
133 ALOGE("gralloc_alloc: Bad inputs (grdev: %p, pHandle: %p, pStride: %p",
134 grdev, pHandle, pStride);
135 return -EINVAL;
136 }
137
138 //
139 // Validate usage: buffer cannot be written both by s/w and h/w access.
140 //
141 bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
142 bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
143 if (hw_write && sw_write) {
144 ALOGE("gralloc_alloc: Mismatched usage flags: %d x %d, usage %x",
145 w, h, usage);
146 return -EINVAL;
147 }
148 bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
149 bool hw_cam_write = usage & GRALLOC_USAGE_HW_CAMERA_WRITE;
150 bool hw_cam_read = usage & GRALLOC_USAGE_HW_CAMERA_READ;
151 bool hw_vid_enc_read = usage & GRALLOC_USAGE_HW_VIDEO_ENCODER;
152
153 // Keep around original requested format for later validation
154 int frameworkFormat = format;
155 // Pick the right concrete pixel format given the endpoints as encoded in
156 // the usage bits. Every end-point pair needs explicit listing here.
157 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
158 // Camera as producer
159 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
160 if (usage & GRALLOC_USAGE_HW_TEXTURE) {
161 // Camera-to-display is RGBA
162 format = HAL_PIXEL_FORMAT_RGBA_8888;
163 } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
164 // Camera-to-encoder is NV21
165 format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
166 } else if ((usage & GRALLOC_USAGE_HW_CAMERA_MASK) ==
167 GRALLOC_USAGE_HW_CAMERA_ZSL) {
168 // Camera-to-ZSL-queue is RGB_888
169 format = HAL_PIXEL_FORMAT_RGB_888;
170 }
171 }
172
173 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
174 ALOGE("gralloc_alloc: Requested auto format selection, "
175 "but no known format for this usage: %d x %d, usage %x",
176 w, h, usage);
177 return -EINVAL;
178 }
179 } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
180 // Flexible framework-accessible YUV format; map to NV21 for now
181 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
182 format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
183 }
184 if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
185 ALOGE("gralloc_alloc: Requested YCbCr_420_888, but no known "
186 "specific format for this usage: %d x %d, usage %x",
187 w, h, usage);
188 }
189 }
190 bool yuv_format = false;
191
192 int ashmem_size = 0;
193 int stride = w;
194
195 GLenum glFormat = 0;
196 GLenum glType = 0;
197
198 int bpp = 0;
199 int align = 1;
200 switch (format) {
201 case HAL_PIXEL_FORMAT_RGBA_8888:
202 case HAL_PIXEL_FORMAT_RGBX_8888:
203 case HAL_PIXEL_FORMAT_BGRA_8888:
204 bpp = 4;
205 glFormat = GL_RGBA;
206 glType = GL_UNSIGNED_BYTE;
207 break;
208 case HAL_PIXEL_FORMAT_RGB_888:
209 bpp = 3;
210 glFormat = GL_RGB;
211 glType = GL_UNSIGNED_BYTE;
212 break;
213 case HAL_PIXEL_FORMAT_RGB_565:
214 bpp = 2;
215 glFormat = GL_RGB;
216 glType = GL_UNSIGNED_SHORT_5_6_5;
217 break;
218 case HAL_PIXEL_FORMAT_RAW_SENSOR:
219 bpp = 2;
220 align = 16*bpp;
221 if (! ((sw_read || hw_cam_read) && (sw_write || hw_cam_write) ) ) {
222 // Raw sensor data only goes between camera and CPU
223 return -EINVAL;
224 }
225 // Not expecting to actually create any GL surfaces for this
226 glFormat = GL_LUMINANCE;
227 glType = GL_UNSIGNED_SHORT;
228 break;
229 case HAL_PIXEL_FORMAT_BLOB:
230 bpp = 1;
231 if (! (sw_read && hw_cam_write) ) {
232 // Blob data cannot be used by HW other than camera emulator
233 return -EINVAL;
234 }
235 // Not expecting to actually create any GL surfaces for this
236 glFormat = GL_LUMINANCE;
237 glType = GL_UNSIGNED_BYTE;
238 break;
239 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
240 align = 1;
241 bpp = 1; // per-channel bpp
242 yuv_format = true;
243 // Not expecting to actually create any GL surfaces for this
244 break;
245 case HAL_PIXEL_FORMAT_YV12:
246 align = 16;
247 bpp = 1; // per-channel bpp
248 yuv_format = true;
249 // Not expecting to actually create any GL surfaces for this
250 break;
251 default:
252 ALOGE("gralloc_alloc: Unknown format %d", format);
253 return -EINVAL;
254 }
255
256 if (usage & GRALLOC_USAGE_HW_FB) {
257 // keep space for postCounter
258 ashmem_size += sizeof(uint32_t);
259 }
260
261 if (sw_read || sw_write || hw_cam_write || hw_vid_enc_read) {
262 // keep space for image on guest memory if SW access is needed
263 // or if the camera is doing writing
264 if (yuv_format) {
265 size_t yStride = (w*bpp + (align - 1)) & ~(align-1);
266 size_t uvStride = (yStride / 2 + (align - 1)) & ~(align-1);
267 size_t uvHeight = h / 2;
268 ashmem_size += yStride * h + 2 * (uvHeight * uvStride);
269 stride = yStride / bpp;
270 } else {
271 size_t bpr = (w*bpp + (align-1)) & ~(align-1);
272 ashmem_size += (bpr * h);
273 stride = bpr / bpp;
274 }
275 }
276
277 D("gralloc_alloc format=%d, ashmem_size=%d, stride=%d, tid %d\n", format,
278 ashmem_size, stride, gettid());
279
280 //
281 // Allocate space in ashmem if needed
282 //
283 int fd = -1;
284 if (ashmem_size > 0) {
285 // round to page size;
286 ashmem_size = (ashmem_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
287
288 fd = ashmem_create_region("gralloc-buffer", ashmem_size);
289 if (fd < 0) {
290 ALOGE("gralloc_alloc failed to create ashmem region: %s\n",
291 strerror(errno));
292 return -errno;
293 }
294 }
295
296 cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage,
297 w, h, frameworkFormat, format,
298 glFormat, glType);
299
300 if (ashmem_size > 0) {
301 //
302 // map ashmem region if exist
303 //
304 void *vaddr;
305 int err = map_buffer(cb, &vaddr);
306 if (err) {
307 close(fd);
308 delete cb;
309 return err;
310 }
311
312 cb->setFd(fd);
313 }
314
315 //
316 // Allocate ColorBuffer handle on the host (only if h/w access is allowed)
317 // Only do this for some h/w usages, not all.
318 //
319 if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
320 GRALLOC_USAGE_HW_2D | GRALLOC_USAGE_HW_COMPOSER |
321 GRALLOC_USAGE_HW_FB) ) {
322 DEFINE_HOST_CONNECTION;
323 if (hostCon && rcEnc) {
324 cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
325 D("Created host ColorBuffer 0x%x\n", cb->hostHandle);
326 }
327
328 if (!cb->hostHandle) {
329 // Could not create colorbuffer on host !!!
330 close(fd);
331 delete cb;
332 return -EIO;
333 }
334 }
335
336 //
337 // alloc succeeded - insert the allocated handle to the allocated list
338 //
339 AllocListNode *node = new AllocListNode();
340 pthread_mutex_lock(&grdev->lock);
341 node->handle = cb;
342 node->next = grdev->allocListHead;
343 node->prev = NULL;
344 if (grdev->allocListHead) {
345 grdev->allocListHead->prev = node;
346 }
347 grdev->allocListHead = node;
348 pthread_mutex_unlock(&grdev->lock);
349
350 *pHandle = cb;
351 if (frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
352 *pStride = 0;
353 } else {
354 *pStride = stride;
355 }
356 return 0;
357 }
358
gralloc_free(alloc_device_t * dev,buffer_handle_t handle)359 static int gralloc_free(alloc_device_t* dev,
360 buffer_handle_t handle)
361 {
362 const cb_handle_t *cb = (const cb_handle_t *)handle;
363 if (!cb_handle_t::validate((cb_handle_t*)cb)) {
364 ERR("gralloc_free: invalid handle");
365 return -EINVAL;
366 }
367
368 if (cb->hostHandle != 0) {
369 DEFINE_AND_VALIDATE_HOST_CONNECTION;
370 D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
371 rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
372 }
373
374 //
375 // detach and unmap ashmem area if present
376 //
377 if (cb->fd > 0) {
378 if (cb->ashmemSize > 0 && cb->ashmemBase) {
379 munmap((void *)cb->ashmemBase, cb->ashmemSize);
380 }
381 close(cb->fd);
382 }
383
384 // remove it from the allocated list
385 gralloc_device_t *grdev = (gralloc_device_t *)dev;
386 pthread_mutex_lock(&grdev->lock);
387 AllocListNode *n = grdev->allocListHead;
388 while( n && n->handle != cb ) {
389 n = n->next;
390 }
391 if (n) {
392 // buffer found on list - remove it from list
393 if (n->next) {
394 n->next->prev = n->prev;
395 }
396 if (n->prev) {
397 n->prev->next = n->next;
398 }
399 else {
400 grdev->allocListHead = n->next;
401 }
402
403 delete n;
404 }
405 pthread_mutex_unlock(&grdev->lock);
406
407 delete cb;
408
409 return 0;
410 }
411
gralloc_device_close(struct hw_device_t * dev)412 static int gralloc_device_close(struct hw_device_t *dev)
413 {
414 gralloc_device_t* d = reinterpret_cast<gralloc_device_t*>(dev);
415 if (d) {
416
417 // free still allocated buffers
418 while( d->allocListHead != NULL ) {
419 gralloc_free(&d->device, d->allocListHead->handle);
420 }
421
422 // free device
423 free(d);
424 }
425 return 0;
426 }
427
fb_compositionComplete(struct framebuffer_device_t * dev)428 static int fb_compositionComplete(struct framebuffer_device_t* dev)
429 {
430 return 0;
431 }
432
433 //
434 // Framebuffer device functions
435 //
fb_post(struct framebuffer_device_t * dev,buffer_handle_t buffer)436 static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
437 {
438 fb_device_t *fbdev = (fb_device_t *)dev;
439 cb_handle_t *cb = (cb_handle_t *)buffer;
440
441 if (!fbdev || !cb_handle_t::validate(cb) || !cb->canBePosted()) {
442 return -EINVAL;
443 }
444
445 // Make sure we have host connection
446 DEFINE_AND_VALIDATE_HOST_CONNECTION;
447
448 // increment the post count of the buffer
449 intptr_t *postCountPtr = (intptr_t *)cb->ashmemBase;
450 if (!postCountPtr) {
451 // This should not happen
452 return -EINVAL;
453 }
454 (*postCountPtr)++;
455
456 // send post request to host
457 rcEnc->rcFBPost(rcEnc, cb->hostHandle);
458 hostCon->flush();
459
460 return 0;
461 }
462
fb_setUpdateRect(struct framebuffer_device_t * dev,int l,int t,int w,int h)463 static int fb_setUpdateRect(struct framebuffer_device_t* dev,
464 int l, int t, int w, int h)
465 {
466 fb_device_t *fbdev = (fb_device_t *)dev;
467
468 if (!fbdev) {
469 return -EINVAL;
470 }
471
472 // Make sure we have host connection
473 DEFINE_AND_VALIDATE_HOST_CONNECTION;
474
475 // send request to host
476 // TODO: XXX - should be implemented
477 //rcEnc->rc_XXX
478
479 return 0;
480 }
481
fb_setSwapInterval(struct framebuffer_device_t * dev,int interval)482 static int fb_setSwapInterval(struct framebuffer_device_t* dev,
483 int interval)
484 {
485 fb_device_t *fbdev = (fb_device_t *)dev;
486
487 if (!fbdev) {
488 return -EINVAL;
489 }
490
491 // Make sure we have host connection
492 DEFINE_AND_VALIDATE_HOST_CONNECTION;
493
494 // send request to host
495 rcEnc->rcFBSetSwapInterval(rcEnc, interval);
496 hostCon->flush();
497
498 return 0;
499 }
500
fb_close(struct hw_device_t * dev)501 static int fb_close(struct hw_device_t *dev)
502 {
503 fb_device_t *fbdev = (fb_device_t *)dev;
504
505 delete fbdev;
506
507 return 0;
508 }
509
510
511 //
512 // gralloc module functions - refcount + locking interface
513 //
gralloc_register_buffer(gralloc_module_t const * module,buffer_handle_t handle)514 static int gralloc_register_buffer(gralloc_module_t const* module,
515 buffer_handle_t handle)
516 {
517 pthread_once(&sFallbackOnce, fallback_init);
518 if (sFallback != NULL) {
519 return sFallback->registerBuffer(sFallback, handle);
520 }
521
522 D("gralloc_register_buffer(%p) called", handle);
523
524 private_module_t *gr = (private_module_t *)module;
525 cb_handle_t *cb = (cb_handle_t *)handle;
526 if (!gr || !cb_handle_t::validate(cb)) {
527 ERR("gralloc_register_buffer(%p): invalid buffer", cb);
528 return -EINVAL;
529 }
530
531 if (cb->hostHandle != 0) {
532 DEFINE_AND_VALIDATE_HOST_CONNECTION;
533 D("Opening host ColorBuffer 0x%x\n", cb->hostHandle);
534 rcEnc->rcOpenColorBuffer2(rcEnc, cb->hostHandle);
535 }
536
537 //
538 // if the color buffer has ashmem region and it is not mapped in this
539 // process map it now.
540 //
541 if (cb->ashmemSize > 0 && cb->mappedPid != getpid()) {
542 void *vaddr;
543 int err = map_buffer(cb, &vaddr);
544 if (err) {
545 ERR("gralloc_register_buffer(%p): map failed: %s", cb, strerror(-err));
546 return -err;
547 }
548 cb->mappedPid = getpid();
549 }
550
551 return 0;
552 }
553
gralloc_unregister_buffer(gralloc_module_t const * module,buffer_handle_t handle)554 static int gralloc_unregister_buffer(gralloc_module_t const* module,
555 buffer_handle_t handle)
556 {
557 if (sFallback != NULL) {
558 return sFallback->unregisterBuffer(sFallback, handle);
559 }
560
561 private_module_t *gr = (private_module_t *)module;
562 cb_handle_t *cb = (cb_handle_t *)handle;
563 if (!gr || !cb_handle_t::validate(cb)) {
564 ERR("gralloc_unregister_buffer(%p): invalid buffer", cb);
565 return -EINVAL;
566 }
567
568 if (cb->hostHandle != 0) {
569 DEFINE_AND_VALIDATE_HOST_CONNECTION;
570 D("Closing host ColorBuffer 0x%x\n", cb->hostHandle);
571 rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
572 }
573
574 //
575 // unmap ashmem region if it was previously mapped in this process
576 // (through register_buffer)
577 //
578 if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) {
579 void *vaddr;
580 int err = munmap((void *)cb->ashmemBase, cb->ashmemSize);
581 if (err) {
582 ERR("gralloc_unregister_buffer(%p): unmap failed", cb);
583 return -EINVAL;
584 }
585 cb->ashmemBase = 0;
586 cb->mappedPid = 0;
587 }
588
589 D("gralloc_unregister_buffer(%p) done\n", cb);
590
591 return 0;
592 }
593
gralloc_lock(gralloc_module_t const * module,buffer_handle_t handle,int usage,int l,int t,int w,int h,void ** vaddr)594 static int gralloc_lock(gralloc_module_t const* module,
595 buffer_handle_t handle, int usage,
596 int l, int t, int w, int h,
597 void** vaddr)
598 {
599 if (sFallback != NULL) {
600 return sFallback->lock(sFallback, handle, usage, l, t, w, h, vaddr);
601 }
602
603 private_module_t *gr = (private_module_t *)module;
604 cb_handle_t *cb = (cb_handle_t *)handle;
605 if (!gr || !cb_handle_t::validate(cb)) {
606 ALOGE("gralloc_lock bad handle\n");
607 return -EINVAL;
608 }
609
610 // validate format
611 if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) {
612 ALOGE("gralloc_lock can't be used with YCbCr_420_888 format");
613 return -EINVAL;
614 }
615
616 // Validate usage,
617 // 1. cannot be locked for hw access
618 // 2. lock for either sw read or write.
619 // 3. locked sw access must match usage during alloc time.
620 bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
621 bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK));
622 bool hw_read = (usage & GRALLOC_USAGE_HW_TEXTURE);
623 bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER);
624 bool hw_vid_enc_read = (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER);
625 bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
626 bool hw_cam_read = (usage & GRALLOC_USAGE_HW_CAMERA_READ);
627 bool sw_read_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_READ_MASK));
628 bool sw_write_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_WRITE_MASK));
629
630 if ( (hw_read || hw_write) ||
631 (!sw_read && !sw_write &&
632 !hw_cam_write && !hw_cam_read &&
633 !hw_vid_enc_read) ||
634 (sw_read && !sw_read_allowed) ||
635 (sw_write && !sw_write_allowed) ) {
636 ALOGE("gralloc_lock usage mismatch usage=0x%x cb->usage=0x%x\n", usage,
637 cb->usage);
638 return -EINVAL;
639 }
640
641 intptr_t postCount = 0;
642 void *cpu_addr = NULL;
643
644 //
645 // make sure ashmem area is mapped if needed
646 //
647 if (cb->canBePosted() || sw_read || sw_write ||
648 hw_cam_write || hw_cam_read ||
649 hw_vid_enc_read) {
650 if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
651 return -EACCES;
652 }
653
654 if (cb->canBePosted()) {
655 postCount = *((intptr_t *)cb->ashmemBase);
656 cpu_addr = (void *)(cb->ashmemBase + sizeof(intptr_t));
657 }
658 else {
659 cpu_addr = (void *)(cb->ashmemBase);
660 }
661 }
662
663 if (cb->hostHandle) {
664 // Make sure we have host connection
665 DEFINE_AND_VALIDATE_HOST_CONNECTION;
666
667 //
668 // flush color buffer write cache on host and get its sync status.
669 //
670 int hostSyncStatus = rcEnc->rcColorBufferCacheFlush(rcEnc, cb->hostHandle,
671 postCount,
672 sw_read);
673 if (hostSyncStatus < 0) {
674 // host failed the color buffer sync - probably since it was already
675 // locked for write access. fail the lock.
676 ALOGE("gralloc_lock cacheFlush failed postCount=%d sw_read=%d\n",
677 postCount, sw_read);
678 return -EBUSY;
679 }
680
681 }
682
683 //
684 // is virtual address required ?
685 //
686 if (sw_read || sw_write || hw_cam_write || hw_cam_read || hw_vid_enc_read) {
687 *vaddr = cpu_addr;
688 }
689
690 if (sw_write || hw_cam_write) {
691 //
692 // Keep locked region if locked for s/w write access.
693 //
694 cb->lockedLeft = l;
695 cb->lockedTop = t;
696 cb->lockedWidth = w;
697 cb->lockedHeight = h;
698 }
699
700 DD("gralloc_lock success. vaddr: %p, *vaddr: %p, usage: %x, cpu_addr: %p",
701 vaddr, vaddr ? *vaddr : 0, usage, cpu_addr);
702
703 return 0;
704 }
705
gralloc_unlock(gralloc_module_t const * module,buffer_handle_t handle)706 static int gralloc_unlock(gralloc_module_t const* module,
707 buffer_handle_t handle)
708 {
709 if (sFallback != NULL) {
710 return sFallback->unlock(sFallback, handle);
711 }
712
713 private_module_t *gr = (private_module_t *)module;
714 cb_handle_t *cb = (cb_handle_t *)handle;
715 if (!gr || !cb_handle_t::validate(cb)) {
716 return -EINVAL;
717 }
718
719 //
720 // if buffer was locked for s/w write, we need to update the host with
721 // the updated data
722 //
723 if (cb->lockedWidth > 0 && cb->lockedHeight > 0 && cb->hostHandle) {
724
725 // Make sure we have host connection
726 DEFINE_AND_VALIDATE_HOST_CONNECTION;
727
728 void *cpu_addr;
729 if (cb->canBePosted()) {
730 cpu_addr = (void *)(cb->ashmemBase + sizeof(int));
731 }
732 else {
733 cpu_addr = (void *)(cb->ashmemBase);
734 }
735
736 if (cb->lockedWidth < cb->width || cb->lockedHeight < cb->height) {
737 int bpp = glUtilsPixelBitSize(cb->glFormat, cb->glType) >> 3;
738 char *tmpBuf = new char[cb->lockedWidth * cb->lockedHeight * bpp];
739
740 int dst_line_len = cb->lockedWidth * bpp;
741 int src_line_len = cb->width * bpp;
742 char *src = (char *)cpu_addr + cb->lockedTop*src_line_len + cb->lockedLeft*bpp;
743 char *dst = tmpBuf;
744 for (int y=0; y<cb->lockedHeight; y++) {
745 memcpy(dst, src, dst_line_len);
746 src += src_line_len;
747 dst += dst_line_len;
748 }
749
750 rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle,
751 cb->lockedLeft, cb->lockedTop,
752 cb->lockedWidth, cb->lockedHeight,
753 cb->glFormat, cb->glType,
754 tmpBuf);
755
756 delete [] tmpBuf;
757 }
758 else {
759 rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle, 0, 0,
760 cb->width, cb->height,
761 cb->glFormat, cb->glType,
762 cpu_addr);
763 }
764 }
765
766 cb->lockedWidth = cb->lockedHeight = 0;
767 return 0;
768 }
769
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)770 static int gralloc_lock_ycbcr(gralloc_module_t const* module,
771 buffer_handle_t handle, int usage,
772 int l, int t, int w, int h,
773 android_ycbcr *ycbcr)
774 {
775 // Not supporting fallback module for YCbCr
776 if (sFallback != NULL) {
777 return -EINVAL;
778 }
779
780 if (!ycbcr) {
781 ALOGE("gralloc_lock_ycbcr got NULL ycbcr struct");
782 return -EINVAL;
783 }
784
785 private_module_t *gr = (private_module_t *)module;
786 cb_handle_t *cb = (cb_handle_t *)handle;
787 if (!gr || !cb_handle_t::validate(cb)) {
788 ALOGE("gralloc_lock_ycbcr bad handle\n");
789 return -EINVAL;
790 }
791
792 if (cb->frameworkFormat != HAL_PIXEL_FORMAT_YCbCr_420_888) {
793 ALOGE("gralloc_lock_ycbcr can only be used with "
794 "HAL_PIXEL_FORMAT_YCbCr_420_888, got %x instead",
795 cb->frameworkFormat);
796 return -EINVAL;
797 }
798
799 // Validate usage
800 // For now, only allow camera write, software read.
801 bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK));
802 bool hw_cam_write = (usage & GRALLOC_USAGE_HW_CAMERA_WRITE);
803 bool sw_read_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_READ_MASK));
804
805 if ( (!hw_cam_write && !sw_read) ||
806 (sw_read && !sw_read_allowed) ) {
807 ALOGE("gralloc_lock_ycbcr usage mismatch usage:0x%x cb->usage:0x%x\n",
808 usage, cb->usage);
809 return -EINVAL;
810 }
811
812 // Make sure memory is mapped, get address
813 if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) {
814 return -EACCES;
815 }
816
817 uint8_t *cpu_addr = NULL;
818
819 if (cb->canBePosted()) {
820 cpu_addr = (uint8_t *)(cb->ashmemBase + sizeof(int));
821 }
822 else {
823 cpu_addr = (uint8_t *)(cb->ashmemBase);
824 }
825
826 // Calculate offsets to underlying YUV data
827 size_t yStride;
828 size_t cStride;
829 size_t yOffset;
830 size_t uOffset;
831 size_t vOffset;
832 size_t cStep;
833 switch (cb->format) {
834 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
835 yStride = cb->width;
836 cStride = cb->width;
837 yOffset = 0;
838 vOffset = yStride * cb->height;
839 uOffset = vOffset + 1;
840 cStep = 2;
841 break;
842 default:
843 ALOGE("gralloc_lock_ycbcr unexpected internal format %x",
844 cb->format);
845 return -EINVAL;
846 }
847
848 ycbcr->y = cpu_addr + yOffset;
849 ycbcr->cb = cpu_addr + uOffset;
850 ycbcr->cr = cpu_addr + vOffset;
851 ycbcr->ystride = yStride;
852 ycbcr->cstride = cStride;
853 ycbcr->chroma_step = cStep;
854
855 // Zero out reserved fields
856 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
857
858 //
859 // Keep locked region if locked for s/w write access.
860 //
861 cb->lockedLeft = l;
862 cb->lockedTop = t;
863 cb->lockedWidth = w;
864 cb->lockedHeight = h;
865
866 DD("gralloc_lock_ycbcr success. usage: %x, ycbcr.y: %p, .cb: %p, .cr: %p, "
867 ".ystride: %d , .cstride: %d, .chroma_step: %d", usage,
868 ycbcr->y, ycbcr->cb, ycbcr->cr, ycbcr->ystride, ycbcr->cstride,
869 ycbcr->chroma_step);
870
871 return 0;
872 }
873
gralloc_device_open(const hw_module_t * module,const char * name,hw_device_t ** device)874 static int gralloc_device_open(const hw_module_t* module,
875 const char* name,
876 hw_device_t** device)
877 {
878 int status = -EINVAL;
879
880 D("gralloc_device_open %s\n", name);
881
882 pthread_once( &sFallbackOnce, fallback_init );
883 if (sFallback != NULL) {
884 return sFallback->common.methods->open(&sFallback->common, name, device);
885 }
886
887 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
888
889 // Create host connection and keep it in the TLS.
890 // return error if connection with host can not be established
891 HostConnection *hostCon = HostConnection::get();
892 if (!hostCon) {
893 ALOGE("gralloc: failed to get host connection while opening %s\n", name);
894 return -EIO;
895 }
896
897 //
898 // Allocate memory for the gralloc device (alloc interface)
899 //
900 gralloc_device_t *dev;
901 dev = (gralloc_device_t*)malloc(sizeof(gralloc_device_t));
902 if (NULL == dev) {
903 return -ENOMEM;
904 }
905
906 // Initialize our device structure
907 //
908 dev->device.common.tag = HARDWARE_DEVICE_TAG;
909 dev->device.common.version = 0;
910 dev->device.common.module = const_cast<hw_module_t*>(module);
911 dev->device.common.close = gralloc_device_close;
912
913 dev->device.alloc = gralloc_alloc;
914 dev->device.free = gralloc_free;
915 dev->allocListHead = NULL;
916 pthread_mutex_init(&dev->lock, NULL);
917
918 *device = &dev->device.common;
919 status = 0;
920 }
921 else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
922
923 // return error if connection with host can not be established
924 DEFINE_AND_VALIDATE_HOST_CONNECTION;
925
926 //
927 // Query the host for Framebuffer attributes
928 //
929 D("gralloc: query Frabuffer attribs\n");
930 EGLint width = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
931 D("gralloc: width=%d\n", width);
932 EGLint height = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
933 D("gralloc: height=%d\n", height);
934 EGLint xdpi = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
935 D("gralloc: xdpi=%d\n", xdpi);
936 EGLint ydpi = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
937 D("gralloc: ydpi=%d\n", ydpi);
938 EGLint fps = rcEnc->rcGetFBParam(rcEnc, FB_FPS);
939 D("gralloc: fps=%d\n", fps);
940 EGLint min_si = rcEnc->rcGetFBParam(rcEnc, FB_MIN_SWAP_INTERVAL);
941 D("gralloc: min_swap=%d\n", min_si);
942 EGLint max_si = rcEnc->rcGetFBParam(rcEnc, FB_MAX_SWAP_INTERVAL);
943 D("gralloc: max_swap=%d\n", max_si);
944
945 //
946 // Allocate memory for the framebuffer device
947 //
948 fb_device_t *dev;
949 dev = (fb_device_t*)malloc(sizeof(fb_device_t));
950 if (NULL == dev) {
951 return -ENOMEM;
952 }
953 memset(dev, 0, sizeof(fb_device_t));
954
955 // Initialize our device structure
956 //
957 dev->device.common.tag = HARDWARE_DEVICE_TAG;
958 dev->device.common.version = 0;
959 dev->device.common.module = const_cast<hw_module_t*>(module);
960 dev->device.common.close = fb_close;
961 dev->device.setSwapInterval = fb_setSwapInterval;
962 dev->device.post = fb_post;
963 dev->device.setUpdateRect = 0; //fb_setUpdateRect;
964 dev->device.compositionComplete = fb_compositionComplete; //XXX: this is a dummy
965
966 const_cast<uint32_t&>(dev->device.flags) = 0;
967 const_cast<uint32_t&>(dev->device.width) = width;
968 const_cast<uint32_t&>(dev->device.height) = height;
969 const_cast<int&>(dev->device.stride) = width;
970 const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGBA_8888;
971 const_cast<float&>(dev->device.xdpi) = xdpi;
972 const_cast<float&>(dev->device.ydpi) = ydpi;
973 const_cast<float&>(dev->device.fps) = fps;
974 const_cast<int&>(dev->device.minSwapInterval) = min_si;
975 const_cast<int&>(dev->device.maxSwapInterval) = max_si;
976 *device = &dev->device.common;
977
978 status = 0;
979 }
980
981 return status;
982 }
983
984 //
985 // define the HMI symbol - our module interface
986 //
987 static struct hw_module_methods_t gralloc_module_methods = {
988 open: gralloc_device_open
989 };
990
991 struct private_module_t HAL_MODULE_INFO_SYM = {
992 base: {
993 common: {
994 tag: HARDWARE_MODULE_TAG,
995 module_api_version: GRALLOC_MODULE_API_VERSION_0_2,
996 hal_api_version: 0,
997 id: GRALLOC_HARDWARE_MODULE_ID,
998 name: "Graphics Memory Allocator Module",
999 author: "The Android Open Source Project",
1000 methods: &gralloc_module_methods,
1001 dso: NULL,
1002 reserved: {0, }
1003 },
1004 registerBuffer: gralloc_register_buffer,
1005 unregisterBuffer: gralloc_unregister_buffer,
1006 lock: gralloc_lock,
1007 unlock: gralloc_unlock,
1008 perform: NULL,
1009 lock_ycbcr: gralloc_lock_ycbcr,
1010 }
1011 };
1012
1013 /* This function is called once to detect whether the emulator supports
1014 * GPU emulation (this is done by looking at the qemu.gles kernel
1015 * parameter, which must be > 0 if this is the case).
1016 *
1017 * If not, then load gralloc.default instead as a fallback.
1018 */
1019 static void
fallback_init(void)1020 fallback_init(void)
1021 {
1022 char prop[PROPERTY_VALUE_MAX];
1023 void* module;
1024
1025 property_get("ro.kernel.qemu.gles", prop, "0");
1026 if (atoi(prop) > 0) {
1027 return;
1028 }
1029 ALOGD("Emulator without GPU emulation detected.");
1030 #if __LP64__
1031 module = dlopen("/system/lib64/hw/gralloc.default.so", RTLD_LAZY|RTLD_LOCAL);
1032 #else
1033 module = dlopen("/system/lib/hw/gralloc.default.so", RTLD_LAZY|RTLD_LOCAL);
1034 #endif
1035 if (module != NULL) {
1036 sFallback = reinterpret_cast<gralloc_module_t*>(dlsym(module, HAL_MODULE_INFO_SYM_AS_STR));
1037 if (sFallback == NULL) {
1038 dlclose(module);
1039 }
1040 }
1041 if (sFallback == NULL) {
1042 ALOGE("Could not find software fallback module!?");
1043 }
1044 }
1045