Initial import
[renesas/gralloc-kms.git] / hardware / renesas / 0001-hardware-renesas-DRM-gralloc-module.patch
1 From a559a2fd009a33aafdf0f6a6e3fd83a8f55c71e4 Mon Sep 17 00:00:00 2001
2 From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
3 Date: Sat, 15 Sep 2012 04:36:43 +0200
4 Subject: [PATCH] hardware/renesas: DRM gralloc module
5
6 Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 ---
8  libgralloc/Android.mk      |   34 ++++
9  libgralloc/framebuffer.cpp |  393 ++++++++++++++++++++++++++++++++++++++++++
10  libgralloc/gralloc.cpp     |  412 ++++++++++++++++++++++++++++++++++++++++++++
11  libgralloc/gralloc_priv.h  |  123 +++++++++++++
12  4 files changed, 962 insertions(+), 0 deletions(-)
13  create mode 100644 libgralloc/Android.mk
14  create mode 100644 libgralloc/framebuffer.cpp
15  create mode 100644 libgralloc/gralloc.cpp
16  create mode 100644 libgralloc/gralloc_priv.h
17
18 diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
19 new file mode 100644
20 index 0000000..ee81ca3
21 --- /dev/null
22 +++ b/libgralloc/Android.mk
23 @@ -0,0 +1,34 @@
24 +# Copyright (C) 2008 The Android Open Source Project
25 +#
26 +# Licensed under the Apache License, Version 2.0 (the "License");
27 +# you may not use this file except in compliance with the License.
28 +# You may obtain a copy of the License at
29 +#
30 +#      http://www.apache.org/licenses/LICENSE-2.0
31 +#
32 +# Unless required by applicable law or agreed to in writing, software
33 +# distributed under the License is distributed on an "AS IS" BASIS,
34 +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 +# See the License for the specific language governing permissions and
36 +# limitations under the License.
37 +
38 +
39 +LOCAL_PATH := $(call my-dir)
40 +
41 +# HAL module implemenation stored in
42 +# hw/<OVERLAY_HARDWARE_MODULE_ID>.<ro.product.board>.so
43 +include $(CLEAR_VARS)
44 +
45 +LOCAL_MODULE_TAGS := optional
46 +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
47 +LOCAL_SHARED_LIBRARIES := liblog libcutils libdrm libkms
48 +
49 +LOCAL_SRC_FILES :=     \
50 +       gralloc.cpp     \
51 +       framebuffer.cpp
52 +
53 +LOCAL_MODULE := gralloc.drm
54 +LOCAL_CFLAGS := -DLOG_TAG=\"gralloc\"
55 +LOCAL_C_INCLUDES := external/drm/include/drm
56 +
57 +include $(BUILD_SHARED_LIBRARY)
58 diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
59 new file mode 100644
60 index 0000000..b81e540
61 --- /dev/null
62 +++ b/libgralloc/framebuffer.cpp
63 @@ -0,0 +1,393 @@
64 +/*
65 + * Copyright (C) 2008 The Android Open Source Project
66 + *
67 + * Licensed under the Apache License, Version 2.0 (the "License");
68 + * you may not use this file except in compliance with the License.
69 + * You may obtain a copy of the License at
70 + *
71 + *      http://www.apache.org/licenses/LICENSE-2.0
72 + *
73 + * Unless required by applicable law or agreed to in writing, software
74 + * distributed under the License is distributed on an "AS IS" BASIS,
75 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76 + * See the License for the specific language governing permissions and
77 + * limitations under the License.
78 + */
79 +
80 +#include <dlfcn.h>
81 +#include <errno.h>
82 +#include <fcntl.h>
83 +#include <stdlib.h>
84 +#include <string.h>
85 +
86 +#include <sys/ioctl.h>
87 +#include <sys/mman.h>
88 +
89 +#include <cutils/ashmem.h>
90 +#include <cutils/atomic.h>
91 +#include <cutils/log.h>
92 +
93 +#include <hardware/hardware.h>
94 +#include <hardware/gralloc.h>
95 +
96 +#if HAVE_ANDROID_OS
97 +#include <libdrm/drm_fourcc.h>
98 +#include <libdrm/xf86drm.h>
99 +#include <libdrm/xf86drmMode.h>
100 +#include <libdrm/libkms.h>
101 +#endif
102 +
103 +#include "gralloc_priv.h"
104 +
105 +// Numbers of buffers for page flipping.
106 +#define FB_NUM_BUFFERS         2
107 +#define FB_FORMAT              DRM_FORMAT_RGB565
108 +
109 +enum {
110 +       PAGE_FLIP = 0x00000001,
111 +       LOCKED = 0x00000002
112 +};
113 +
114 +struct fb_context_t {
115 +       framebuffer_device_t device;
116 +};
117 +
118 +/* -----------------------------------------------------------------------------
119 + *
120 + */
121 +
122 +static int fb_setSwapInterval(struct framebuffer_device_t *dev, int interval)
123 +{
124 +       fb_context_t *ctx = (fb_context_t *)dev;
125 +
126 +       if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
127 +               return -EINVAL;
128 +
129 +       // FIXME: implement fb_setSwapInterval
130 +       return 0;
131 +}
132 +
133 +static int fb_post(struct framebuffer_device_t *dev, buffer_handle_t buffer)
134 +{
135 +       if (private_handle_t::validate(buffer) < 0)
136 +               return -EINVAL;
137 +
138 +       fb_context_t *ctx = (fb_context_t *)dev;
139 +
140 +       private_handle_t const *hnd =
141 +               static_cast<private_handle_t const *>(buffer);
142 +       private_module_t *m =
143 +               reinterpret_cast<private_module_t *>(dev->common.module);
144 +
145 +       if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
146 +               int err = drmModePageFlip(m->fd, m->crtc,
147 +                                         m->buffers[hnd->index].fb,
148 +                                         0 /* DRM_MODE_PAGE_FLIP_EVENT */, 0);
149 +               if (err < 0) {
150 +                       LOGE("drmModePageFlip failed (%d)", err);
151 +                       m->base.unlock(&m->base, buffer);
152 +                       return err;
153 +               }
154 +       } else {
155 +               /* If we can't do the page_flip, just copy the buffer to the
156 +                * front.
157 +                * FIXME: use copybit HAL instead of memcpy
158 +                */
159 +               void *buffer_vaddr;
160 +
161 +               m->base.lock(&m->base, buffer,
162 +                            GRALLOC_USAGE_SW_READ_RARELY, 0, 0,
163 +                            m->mode->hdisplay, m->mode->vdisplay,
164 +                            &buffer_vaddr);
165 +
166 +               memcpy(m->buffers[0].vaddr, buffer_vaddr,
167 +                      m->stride * m->mode->vdisplay);
168 +
169 +               m->base.unlock(&m->base, buffer);
170 +       }
171 +
172 +       return 0;
173 +}
174 +
175 +/* -----------------------------------------------------------------------------
176 + *
177 + */
178 +
179 +static void fb_free_buffer(struct private_module_t *module,
180 +                          struct private_buffer_t *buffer)
181 +{
182 +       if (buffer->fb) {
183 +               drmModeRmFB(module->fd, buffer->fb);
184 +               buffer->fb = 0;
185 +       }
186 +       if (buffer->vaddr) {
187 +               kms_bo_unmap(buffer->bo);
188 +               buffer->vaddr = 0;
189 +       }
190 +       if (buffer->bo)
191 +               kms_bo_destroy(&buffer->bo);
192 +}
193 +
194 +static int fb_alloc_buffer(struct private_module_t *module,
195 +                          struct private_buffer_t *buffer,
196 +                          const drmModeModeInfo *mode)
197 +{
198 +       unsigned int bo_attrs[] = {
199 +               KMS_WIDTH, mode->hdisplay,
200 +               KMS_HEIGHT, mode->vdisplay,
201 +               KMS_BO_TYPE, KMS_BO_TYPE_SCANOUT_X8R8G8B8,
202 +               KMS_TERMINATE_PROP_LIST,
203 +       };
204 +       uint32_t handles[4] = { 0 };
205 +       uint32_t pitches[4] = { 0 };
206 +       uint32_t offsets[4] = { 0 };
207 +       int err;
208 +
209 +       err = kms_bo_create(module->kms, bo_attrs, &buffer->bo);
210 +       if (err < 0)
211 +               goto done;
212 +
213 +       err = kms_bo_map(buffer->bo, &buffer->vaddr);
214 +       if (err < 0)
215 +               goto done;
216 +
217 +       kms_bo_get_prop(buffer->bo, KMS_HANDLE, &buffer->handle);
218 +
219 +       handles[0] = buffer->handle;
220 +       pitches[0] = mode->hdisplay * 2;
221 +       err = drmModeAddFB2(module->fd, mode->hdisplay, mode->vdisplay,
222 +                           FB_FORMAT, handles, pitches, offsets, &buffer->fb,
223 +                           0);
224 +
225 +done:
226 +       if (err < 0)
227 +               fb_free_buffer(module, buffer);
228 +
229 +       return err;
230 +}
231 +
232 +int fb_map_locked(struct private_module_t *module)
233 +{
234 +       int err;
235 +
236 +       // already initialized...
237 +       if (module->num_buffers)
238 +               return 0;
239 +
240 +       int fd = drmOpen("shmob-drm", 0);
241 +       if (fd < 0)
242 +               return -errno;
243 +
244 +       module->fd = fd;
245 +
246 +       drmModeModeInfo *mode = 0;
247 +       drmVersion *version = 0;
248 +       drmModeRes *resources = 0;
249 +       drmModeConnector *connector = 0;
250 +       drmModeEncoder *encoder = 0;
251 +
252 +       version = drmGetVersion(fd);
253 +       if (!version) {
254 +               err = -errno;
255 +               goto done;
256 +       }
257 +
258 +       resources = drmModeGetResources(fd);
259 +       if (!resources) {
260 +               err = -errno;
261 +               goto done;
262 +       }
263 +
264 +       /* Get the default mode associated with the first connector. */
265 +       if (resources->count_connectors == 0) {
266 +               err = -EINVAL;
267 +               goto done;
268 +       }
269 +
270 +       connector = drmModeGetConnector(fd, resources->connectors[0]);
271 +       if (!connector) {
272 +               err = -errno;
273 +               goto done;
274 +       }
275 +
276 +       if (connector->count_modes == 0) {
277 +               err = -EINVAL;
278 +               goto done;
279 +       }
280 +
281 +       if (connector->count_encoders == 0) {
282 +               err = -EINVAL;
283 +               goto done;
284 +       }
285 +
286 +       encoder = drmModeGetEncoder(fd, *connector->encoders);
287 +       if (!encoder) {
288 +               err = -errno;
289 +               goto done;
290 +       }
291 +
292 +       for (int i = 0; i < resources->count_crtcs; ++i) {
293 +               if (encoder->possible_crtcs & (1U << i)) {
294 +                       module->crtc = resources->crtcs[i];
295 +                       break;
296 +               }
297 +       }
298 +
299 +       if (module->crtc == 0) {
300 +               err = -EINVAL;
301 +               goto done;
302 +       }
303 +
304 +       float xdpi;
305 +       float ydpi;
306 +       float fps;
307 +
308 +       mode = &connector->modes[0];
309 +
310 +       if (connector->mmWidth == 0 || connector->mmHeight == 0) {
311 +               /* The driver doesn't return that information, default to
312 +                * 160 dpi.
313 +                */
314 +               xdpi = 160;
315 +               ydpi = 160;
316 +       } else {
317 +               xdpi = (mode->hdisplay * 25.4f) / connector->mmWidth;
318 +               ydpi = (mode->vdisplay * 25.4f) / connector->mmHeight;
319 +       }
320 +
321 +       if (mode->htotal && mode->vtotal)
322 +               fps = mode->clock * 1000.0f / (mode->htotal * mode->vtotal);
323 +       else
324 +               fps = 60.0;
325 +
326 +       /* Create two frame buffers. */
327 +       module->buffers = new private_buffer_t[FB_NUM_BUFFERS];
328 +       if (!module->buffers) {
329 +               err = -ENOMEM;
330 +               goto done;
331 +       }
332 +
333 +       memset(module->buffers, 0, FB_NUM_BUFFERS * sizeof *module->buffers);
334 +
335 +       err = kms_create(fd, &module->kms);
336 +       if (err < 0)
337 +               goto done;
338 +
339 +       for (unsigned int i = 0; i < FB_NUM_BUFFERS; ++i) {
340 +               err = fb_alloc_buffer(module, &module->buffers[i], mode);
341 +               if (err < 0)
342 +                       goto done;
343 +       }
344 +
345 +       err = drmModeSetCrtc(fd, module->crtc, module->buffers[0].fb, 0, 0,
346 +                            &connector->connector_id, 1, mode);
347 +       if (err < 0)
348 +               goto done;
349 +
350 +       LOGI("using (fd=%d)\n"
351 +            "desc         = %s\n"
352 +            "hdisplay     = %u px\n"
353 +            "vdisplay     = %u px\n"
354 +            "format       = 0x%08x\n",
355 +            fd, version->desc,
356 +            mode->hdisplay, mode->vdisplay,
357 +            FB_FORMAT);
358 +
359 +       LOGI("width        = %d mm (%f dpi)\n"
360 +            "height       = %d mm (%f dpi)\n"
361 +            "refresh rate = %.2f Hz\n",
362 +            connector->mmWidth, xdpi, connector->mmHeight, ydpi, fps);
363 +
364 +       module->flags = PAGE_FLIP;
365 +       module->num_buffers = FB_NUM_BUFFERS;
366 +       module->mode = mode;
367 +       module->xdpi = xdpi;
368 +       module->ydpi = ydpi;
369 +       module->fps = fps;
370 +       module->stride = mode->hdisplay * 2;
371 +
372 +done:
373 +       if (encoder)
374 +               drmModeFreeEncoder(encoder);
375 +       if (resources)
376 +               drmModeFreeResources(resources);
377 +       if (version)
378 +               drmFreeVersion(version);
379 +
380 +       if (err < 0) {
381 +               if (module->buffers) {
382 +                       for (unsigned int i = 0; i < FB_NUM_BUFFERS; ++i)
383 +                               fb_free_buffer(module, &module->buffers[i]);
384 +                       delete[] module->buffers;
385 +               }
386 +               if (connector)
387 +                       drmModeFreeConnector(connector);
388 +               if (fd != -1)
389 +                       drmClose(fd);
390 +       }
391 +
392 +       return err;
393 +}
394 +
395 +static int fb_map(struct private_module_t *module)
396 +{
397 +       pthread_mutex_lock(&module->lock);
398 +       int err = fb_map_locked(module);
399 +       pthread_mutex_unlock(&module->lock);
400 +       return err;
401 +}
402 +
403 +/* -----------------------------------------------------------------------------
404 + *
405 + */
406 +
407 +static int fb_close(struct hw_device_t *dev)
408 +{
409 +       fb_context_t *ctx = (fb_context_t*)dev;
410 +       free(ctx);
411 +       return 0;
412 +}
413 +
414 +int fb_device_open(hw_module_t const *module, const char *name,
415 +                  hw_device_t **device)
416 +{
417 +       alloc_device_t *gralloc_device;
418 +       int err;
419 +
420 +       err = gralloc_open(module, &gralloc_device);
421 +       if (err < 0)
422 +               return err;
423 +
424 +       /* Initialize our state here */
425 +       fb_context_t *dev = (fb_context_t *)malloc(sizeof *dev);
426 +       memset(dev, 0, sizeof *dev);
427 +
428 +       /* Initialize the procs */
429 +       dev->device.common.tag = HARDWARE_DEVICE_TAG;
430 +       dev->device.common.version = 0;
431 +       dev->device.common.module = const_cast<hw_module_t *>(module);
432 +       dev->device.common.close = fb_close;
433 +       dev->device.setSwapInterval = fb_setSwapInterval;
434 +       dev->device.post = fb_post;
435 +       dev->device.setUpdateRect = 0;
436 +
437 +       private_module_t *m = (private_module_t*)module;
438 +       err = fb_map(m);
439 +       if (err < 0)
440 +               return err;
441 +
442 +       const_cast<uint32_t&>(dev->device.flags) = 0;
443 +       const_cast<uint32_t&>(dev->device.width) = m->mode->hdisplay;
444 +       const_cast<uint32_t&>(dev->device.height) = m->mode->vdisplay;
445 +       const_cast<int&>(dev->device.stride) = m->stride;
446 +       const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGB_565;
447 +       const_cast<float&>(dev->device.xdpi) = m->xdpi;
448 +       const_cast<float&>(dev->device.ydpi) = m->ydpi;
449 +       const_cast<float&>(dev->device.fps) = m->fps;
450 +       const_cast<int&>(dev->device.minSwapInterval) = 1;
451 +       const_cast<int&>(dev->device.maxSwapInterval) = 1;
452 +
453 +       *device = &dev->device.common;
454 +
455 +       return 0;
456 +}
457 diff --git a/libgralloc/gralloc.cpp b/libgralloc/gralloc.cpp
458 new file mode 100644
459 index 0000000..03282b3
460 --- /dev/null
461 +++ b/libgralloc/gralloc.cpp
462 @@ -0,0 +1,412 @@
463 +/*
464 + * Copyright (C) 2008 The Android Open Source Project
465 + *
466 + * Licensed under the Apache License, Version 2.0 (the "License");
467 + * you may not use this file except in compliance with the License.
468 + * You may obtain a copy of the License at
469 + *
470 + *      http://www.apache.org/licenses/LICENSE-2.0
471 + *
472 + * Unless required by applicable law or agreed to in writing, software
473 + * distributed under the License is distributed on an "AS IS" BASIS,
474 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
475 + * See the License for the specific language governing permissions and
476 + * limitations under the License.
477 + */
478 +
479 +#include <errno.h>
480 +#include <fcntl.h>
481 +#include <limits.h>
482 +#include <pthread.h>
483 +#include <stdint.h>
484 +#include <stdlib.h>
485 +#include <string.h>
486 +#include <unistd.h>
487 +
488 +#include <sys/cdefs.h>
489 +#include <sys/ioctl.h>
490 +#include <sys/mman.h>
491 +#include <sys/stat.h>
492 +#include <sys/types.h>
493 +#ifdef HAVE_ANDROID_OS      // just want PAGE_SIZE define
494 +# include <asm/page.h>
495 +#else
496 +# include <sys/user.h>
497 +#endif
498 +
499 +#include <cutils/ashmem.h>
500 +#include <cutils/atomic.h>
501 +#include <cutils/log.h>
502 +#include <cutils/native_handle.h>
503 +
504 +#include <hardware/gralloc.h>
505 +#include <hardware/hardware.h>
506 +
507 +#include "gralloc_priv.h"
508 +
509 +struct gralloc_context_t {
510 +    alloc_device_t  device;
511 +    /* our private data here */
512 +};
513 +
514 +static size_t roundUpToPageSize(size_t x)
515 +{
516 +       return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
517 +}
518 +
519 +/* -----------------------------------------------------------------------------
520 + * Map/unmap
521 + */
522 +
523 +static int gralloc_map(gralloc_module_t const *module, private_handle_t *hnd,
524 +                      void **vaddr)
525 +{
526 +       if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
527 +               void *addr;
528 +
529 +               addr = mmap(0, hnd->size, PROT_READ|PROT_WRITE, MAP_SHARED,
530 +                           hnd->fd, 0);
531 +               if (addr == MAP_FAILED) {
532 +                       LOGE("Could not mmap %s", strerror(errno));
533 +                       return -errno;
534 +               }
535 +
536 +               hnd->base = intptr_t(addr);
537 +       }
538 +
539 +       *vaddr = (void *)hnd->base;
540 +       return 0;
541 +}
542 +
543 +static int gralloc_unmap(gralloc_module_t const *module, private_handle_t *hnd)
544 +{
545 +       if (hnd->base == 0)
546 +               return 0;
547 +
548 +       if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
549 +               if (munmap((void *)hnd->base, hnd->size) < 0)
550 +                       LOGE("Could not unmap %s", strerror(errno));
551 +       }
552 +
553 +       hnd->base = 0;
554 +       return 0;
555 +}
556 +/* -----------------------------------------------------------------------------
557 + * Buffer registration
558 + */
559 +
560 +static int gralloc_register_buffer(gralloc_module_t const *module,
561 +                                  buffer_handle_t handle)
562 +{
563 +       if (private_handle_t::validate(handle) < 0)
564 +               return -EINVAL;
565 +
566 +       private_handle_t *hnd =
567 +               const_cast<private_handle_t *>(
568 +               static_cast<const private_handle_t *>(handle));
569 +
570 +       /* If this handle was created in this process, then we keep it as is. */
571 +       if (hnd->pid == getpid())
572 +               return 0;
573 +
574 +       void *vaddr;
575 +       return gralloc_map(module, hnd, &vaddr);
576 +}
577 +
578 +static int gralloc_unregister_buffer(gralloc_module_t const *module,
579 +                                    buffer_handle_t handle)
580 +{
581 +       if (private_handle_t::validate(handle) < 0)
582 +               return -EINVAL;
583 +
584 +       private_handle_t *hnd =
585 +               const_cast<private_handle_t *>(
586 +               static_cast<const private_handle_t *>(handle));
587 +
588 +       /* Never unmap buffers that were created in this process. */
589 +       if (hnd->pid == getpid())
590 +               return 0;
591 +
592 +       gralloc_unmap(module, hnd);
593 +       return 0;
594 +}
595 +
596 +/* -----------------------------------------------------------------------------
597 + * Lock/unlock
598 + */
599 +
600 +static int gralloc_lock(gralloc_module_t const *module,
601 +                       buffer_handle_t handle, int usage, int l, int t,
602 +                       int w, int h, void **vaddr)
603 +{
604 +       /* This is called when a buffer is being locked for software access. In
605 +        * this implementation we have nothing to do since not synchronization
606 +        * with the h/w is needed. Typically this is used to wait for the h/w to
607 +        * finish with this buffer if relevant. The data cache may need to be
608 +        * flushed or invalidated depending on the usage bits and the hardware.
609 +        */
610 +       if (private_handle_t::validate(handle) < 0)
611 +               return -EINVAL;
612 +
613 +       private_handle_t *hnd =
614 +               const_cast<private_handle_t *>(
615 +               static_cast<const private_handle_t *>(handle));
616 +       *vaddr = (void*)hnd->base;
617 +       return 0;
618 +}
619 +
620 +static int gralloc_unlock(gralloc_module_t const *module,
621 +                         buffer_handle_t handle)
622 +{
623 +       /* We're done with a software buffer. Nothing to do in this
624 +        * implementation. Typically this is used to flush the data cache.
625 +        */
626 +       if (private_handle_t::validate(handle) < 0)
627 +               return -EINVAL;
628 +
629 +       return 0;
630 +}
631 +
632 +/* -----------------------------------------------------------------------------
633 + * Alloc/free
634 + */
635 +
636 +/* Allocate a buffer from system memory through ashmem. */
637 +static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage,
638 +                               buffer_handle_t *handle)
639 +{
640 +       void *vaddr;
641 +       int err;
642 +       int fd;
643 +
644 +       size = roundUpToPageSize(size);
645 +
646 +       fd = ashmem_create_region("gralloc-buffer", size);
647 +       if (fd < 0) {
648 +               LOGE("couldn't create ashmem (%s)", strerror(-errno));
649 +               return -errno;
650 +       }
651 +
652 +       private_handle_t *hnd = new private_handle_t(fd, size, 0);
653 +       gralloc_module_t *module =
654 +               reinterpret_cast<gralloc_module_t *>(dev->common.module);
655 +       err = gralloc_map(module, hnd, &vaddr);
656 +       if (err < 0) {
657 +               LOGE("gralloc failed err=%s", strerror(-err));
658 +               close(fd);
659 +               delete hnd;
660 +               return err;
661 +       }
662 +
663 +       *handle = hnd;
664 +       return 0;
665 +}
666 +
667 +/* Allocate a buffer from display memory. */
668 +static int gralloc_alloc_framebuffer_locked(alloc_device_t *dev, size_t size,
669 +                                           int usage, buffer_handle_t *handle)
670 +{
671 +       private_module_t *m =
672 +               reinterpret_cast<private_module_t *>(dev->common.module);
673 +
674 +       /* Allocate the framebuffer if not done already. The frame buffer is
675 +        * mapped once and forever.
676 +        */
677 +       int err = fb_map_locked(m);
678 +       if (err < 0)
679 +               return err;
680 +
681 +       if (m->num_buffers == 1) {
682 +               /* If we have only one buffer, we never use page-flipping.
683 +                * Instead, we return a regular buffer which will be memcpy'ed
684 +                * to the main screen when post is called.
685 +                */
686 +               usage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
687 +               return gralloc_alloc_buffer(dev, m->stride * m->mode->vdisplay,
688 +                                           usage, handle);
689 +       }
690 +
691 +       unsigned int index;
692 +
693 +       // Find a free slot.
694 +       for (index = 0; index < m->num_buffers ; index++) {
695 +               if (!m->buffers[index].busy) {
696 +                       m->buffers[index].busy = true;
697 +                       break;
698 +               }
699 +       }
700 +
701 +       if (index == m->num_buffers)
702 +               return -ENOMEM;
703 +
704 +       // Create a "fake" handle for it.
705 +       private_handle_t *hnd =
706 +               new private_handle_t(dup(m->fd), size,
707 +                                    private_handle_t::PRIV_FLAGS_FRAMEBUFFER);
708 +
709 +       hnd->index = index;
710 +       hnd->base = (int)m->buffers[index].vaddr;
711 +       *handle = hnd;
712 +
713 +       return 0;
714 +}
715 +
716 +static int gralloc_alloc_framebuffer(alloc_device_t *dev, size_t size,
717 +                                    int usage, buffer_handle_t *handle)
718 +{
719 +       private_module_t *m =
720 +               reinterpret_cast<private_module_t *>(dev->common.module);
721 +
722 +       pthread_mutex_lock(&m->lock);
723 +       int err = gralloc_alloc_framebuffer_locked(dev, size, usage, handle);
724 +       pthread_mutex_unlock(&m->lock);
725 +
726 +       return err;
727 +}
728 +
729 +static int gralloc_alloc(alloc_device_t *dev, int w, int h, int format,
730 +                        int usage, buffer_handle_t *handle, int *stride)
731 +{
732 +       if (!handle || !stride)
733 +               return -EINVAL;
734 +
735 +       unsigned int align = 4;
736 +       unsigned int bpp;
737 +       size_t size;
738 +
739 +       switch (format) {
740 +       case HAL_PIXEL_FORMAT_RGBA_8888:
741 +       case HAL_PIXEL_FORMAT_RGBX_8888:
742 +       case HAL_PIXEL_FORMAT_BGRA_8888:
743 +               bpp = 4;
744 +               break;
745 +       case HAL_PIXEL_FORMAT_RGB_888:
746 +               bpp = 3;
747 +               break;
748 +       case HAL_PIXEL_FORMAT_RGB_565:
749 +       case HAL_PIXEL_FORMAT_RGBA_5551:
750 +       case HAL_PIXEL_FORMAT_RGBA_4444:
751 +               bpp = 2;
752 +               break;
753 +       default:
754 +               return -EINVAL;
755 +       }
756 +
757 +       size_t bpr = (w*bpp + (align-1)) & ~(align-1);
758 +       size = bpr * h;
759 +       *stride = bpr / bpp;
760 +
761 +       if (usage & GRALLOC_USAGE_HW_FB)
762 +               return gralloc_alloc_framebuffer(dev, size, usage, handle);
763 +       else
764 +               return gralloc_alloc_buffer(dev, size, usage, handle);
765 +}
766 +
767 +static int gralloc_free(alloc_device_t *dev, buffer_handle_t handle)
768 +{
769 +       private_module_t *m =
770 +               reinterpret_cast<private_module_t *>(dev->common.module);
771 +       private_handle_t *hnd =
772 +               const_cast<private_handle_t *>(
773 +               static_cast<const private_handle_t *>(handle));
774 +
775 +       if (private_handle_t::validate(handle) < 0)
776 +               return -EINVAL;
777 +
778 +       if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
779 +               pthread_mutex_lock(&m->lock);
780 +               m->buffers[hnd->index].busy = false;
781 +               pthread_mutex_unlock(&m->lock);
782 +       } else {
783 +               gralloc_unmap(&m->base, hnd);
784 +       }
785 +
786 +       close(hnd->fd);
787 +       delete hnd;
788 +       return 0;
789 +}
790 +
791 +/* -----------------------------------------------------------------------------
792 + * Open/close
793 + */
794 +
795 +static int gralloc_close(struct hw_device_t *dev)
796 +{
797 +       gralloc_context_t *ctx = reinterpret_cast<gralloc_context_t *>(dev);
798 +
799 +       if (ctx) {
800 +               /* TODO: keep a list of all buffer_handle_t created, and free
801 +                * them all here.
802 +                */
803 +               delete ctx;
804 +       }
805 +
806 +       return 0;
807 +}
808 +
809 +static int gralloc_device_open(const hw_module_t *module, const char *name,
810 +                       hw_device_t **device)
811 +{
812 +       int status = -EINVAL;
813 +
814 +       if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
815 +               gralloc_context_t *dev;
816 +
817 +               dev = new(gralloc_context_t);
818 +               memset(dev, 0, sizeof *dev);
819 +
820 +               /* initialize the procs */
821 +               dev->device.common.tag = HARDWARE_DEVICE_TAG;
822 +               dev->device.common.version = 0;
823 +               dev->device.common.module = const_cast<hw_module_t *>(module);
824 +               dev->device.common.close = gralloc_close;
825 +
826 +               dev->device.alloc = gralloc_alloc;
827 +               dev->device.free = gralloc_free;
828 +
829 +               *device = &dev->device.common;
830 +               status = 0;
831 +       } else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
832 +               status = fb_device_open(module, name, device);
833 +       }
834 +
835 +       return status;
836 +}
837 +
838 +/* -----------------------------------------------------------------------------
839 + * Module
840 + */
841 +
842 +static struct hw_module_methods_t gralloc_module_methods = {
843 +       open: gralloc_device_open,
844 +};
845 +
846 +struct private_module_t HAL_MODULE_INFO_SYM = {
847 +       base: {
848 +               common: {
849 +                       tag: HARDWARE_MODULE_TAG,
850 +                       version_major: 1,
851 +                       version_minor: 0,
852 +                       id: GRALLOC_HARDWARE_MODULE_ID,
853 +                       name: "Graphics Memory Allocator Module",
854 +                       author: "Renesas Electronics Inc.",
855 +                       methods: &gralloc_module_methods
856 +               },
857 +               registerBuffer: gralloc_register_buffer,
858 +               unregisterBuffer: gralloc_unregister_buffer,
859 +               lock: gralloc_lock,
860 +               unlock: gralloc_unlock,
861 +       },
862 +       lock: PTHREAD_MUTEX_INITIALIZER,
863 +       fd: -1,
864 +       crtc: 0,
865 +       mode: 0,
866 +       kms: 0,
867 +       num_buffers: 0,
868 +       buffers: 0,
869 +       xdpi: 0.0f,
870 +       ydpi: 0.0f,
871 +       fps: 0.0f,
872 +       stride: 0,
873 +       flags: 0,
874 +};
875 diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
876 new file mode 100644
877 index 0000000..02854aa
878 --- /dev/null
879 +++ b/libgralloc/gralloc_priv.h
880 @@ -0,0 +1,123 @@
881 +/*
882 + * Copyright (C) 2008 The Android Open Source Project
883 + *
884 + * Licensed under the Apache License, Version 2.0 (the "License");
885 + * you may not use this file except in compliance with the License.
886 + * You may obtain a copy of the License at
887 + *
888 + *      http://www.apache.org/licenses/LICENSE-2.0
889 + *
890 + * Unless required by applicable law or agreed to in writing, software
891 + * distributed under the License is distributed on an "AS IS" BASIS,
892 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
893 + * See the License for the specific language governing permissions and
894 + * limitations under the License.
895 + */
896 +
897 +#ifndef GRALLOC_PRIV_H_
898 +#define GRALLOC_PRIV_H_
899 +
900 +#include <errno.h>
901 +#include <limits.h>
902 +#include <pthread.h>
903 +#include <stdint.h>
904 +#include <unistd.h>
905 +
906 +#include <sys/cdefs.h>
907 +
908 +#include <cutils/native_handle.h>
909 +
910 +#include <hardware/gralloc.h>
911 +
912 +#include <libdrm/xf86drmMode.h>
913 +
914 +int fb_device_open(const hw_module_t *module, const char *name,
915 +                  hw_device_t **device);
916 +int fb_map_locked(struct private_module_t *module);
917 +
918 +/* -----------------------------------------------------------------------------
919 + * Module
920 + */
921 +
922 +struct private_buffer_t {
923 +       struct kms_bo *bo;
924 +       void *vaddr;
925 +       bool busy;
926 +       unsigned int handle;
927 +       uint32_t fb;
928 +};
929 +
930 +struct private_module_t {
931 +       gralloc_module_t base;
932 +       pthread_mutex_t lock;
933 +
934 +       int fd;
935 +       uint32_t crtc;
936 +       drmModeModeInfo *mode;
937 +       struct kms_driver *kms;
938 +
939 +       uint32_t num_buffers;
940 +       struct private_buffer_t *buffers;
941 +
942 +       float xdpi;
943 +       float ydpi;
944 +       float fps;
945 +       unsigned int stride;
946 +
947 +       uint32_t flags;
948 +};
949 +
950 +/* -----------------------------------------------------------------------------
951 + * Handle
952 + */
953 +
954 +struct private_handle_t : public native_handle {
955 +       enum {
956 +               PRIV_FLAGS_FRAMEBUFFER = 0x00000001
957 +       };
958 +
959 +       // File descriptors
960 +       int fd;
961 +
962 +       // Ints
963 +       int magic;
964 +       int flags;
965 +       int size;
966 +       int pid;
967 +
968 +       int index;
969 +       int base;
970 +
971 +       static const int sNumInts = 6;
972 +       static const int sNumFds = 1;
973 +       static const int sMagic = 0x3141592;
974 +
975 +       private_handle_t(int fd, int size, int flags) :
976 +               fd(fd), magic(sMagic), flags(flags), size(size), pid(getpid()),
977 +               index(0)
978 +       {
979 +               version = sizeof(native_handle);
980 +               numInts = sNumInts;
981 +               numFds = sNumFds;
982 +       }
983 +
984 +       ~private_handle_t() {
985 +               magic = 0;
986 +       }
987 +
988 +       static int validate(const native_handle *h) {
989 +               const private_handle_t *hnd = (const private_handle_t *)h;
990 +
991 +               if (!h || h->version != sizeof(native_handle) ||
992 +                   h->numInts != sNumInts || h->numFds != sNumFds ||
993 +                   hnd->magic != sMagic)
994 +               {
995 +                       LOGE("invalid gralloc handle (at %p)", h);
996 +                       return -EINVAL;
997 +               }
998 +
999 +               return 0;
1000 +       }
1001 +};
1002 +
1003 +#endif /* GRALLOC_PRIV_H_ */
1004 -- 
1005 1.7.8.6
1006