Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2011 Benjamin Franzke <benjaminfranzke@googlemail.com>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include "util/u_memory.h"
  26. #include "util/u_inlines.h"
  27.  
  28. #include "pipe/p_compiler.h"
  29. #include "pipe/p_screen.h"
  30. #include "pipe/p_context.h"
  31. #include "pipe/p_state.h"
  32.  
  33. #include "sw/wayland/wayland_sw_winsys.h"
  34.  
  35. #include "egllog.h"
  36.  
  37. #include "native_wayland.h"
  38.  
  39. #include <wayland-client.h>
  40. #include "wayland-egl-priv.h"
  41.  
  42. #include <sys/types.h>
  43. #include <sys/stat.h>
  44. #include <fcntl.h>
  45.  
  46. struct wayland_shm_display {
  47.    struct wayland_display base;
  48.  
  49.    const struct native_event_handler *event_handler;
  50.    struct wl_shm *wl_shm;
  51. };
  52.  
  53. static INLINE struct wayland_shm_display *
  54. wayland_shm_display(const struct native_display *ndpy)
  55. {
  56.    return (struct wayland_shm_display *) ndpy;
  57. }
  58.  
  59.  
  60. static void
  61. wayland_shm_display_destroy(struct native_display *ndpy)
  62. {
  63.    struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy);
  64.  
  65.    FREE(shmdpy->base.configs);
  66.    if (shmdpy->base.own_dpy)
  67.       wl_display_disconnect(shmdpy->base.dpy);
  68.  
  69.    ndpy_uninit(ndpy);
  70.  
  71.    FREE(shmdpy);
  72. }
  73.  
  74. static struct wl_buffer *
  75. wayland_create_shm_buffer(struct wayland_display *display,
  76.                           struct wayland_surface *surface,
  77.                           enum native_attachment attachment)
  78. {
  79.    struct wayland_shm_display *shmdpy = (struct wayland_shm_display *) display;
  80.    struct pipe_screen *screen = shmdpy->base.base.screen;
  81.    struct pipe_resource *resource;
  82.    struct winsys_handle wsh;
  83.    uint width, height;
  84.    enum wl_shm_format format;
  85.    struct wl_buffer *buffer;
  86.    struct wl_shm_pool *pool;
  87.  
  88.    resource = resource_surface_get_single_resource(surface->rsurf, attachment);
  89.    resource_surface_get_size(surface->rsurf, &width, &height);
  90.  
  91.    screen->resource_get_handle(screen, resource, &wsh);
  92.  
  93.    pipe_resource_reference(&resource, NULL);
  94.  
  95.    switch (surface->color_format) {
  96.    case PIPE_FORMAT_B8G8R8A8_UNORM:
  97.       format = WL_SHM_FORMAT_ARGB8888;
  98.       break;
  99.    case PIPE_FORMAT_B8G8R8X8_UNORM:
  100.       format = WL_SHM_FORMAT_XRGB8888;
  101.       break;
  102.    default:
  103.       return NULL;
  104.       break;
  105.    }
  106.  
  107.    pool = wl_shm_create_pool(shmdpy->wl_shm, wsh.fd, wsh.size);
  108.    buffer = wl_shm_pool_create_buffer(pool, 0, width, height,
  109.                                       wsh.stride, format);
  110.    wl_shm_pool_destroy(pool);
  111.  
  112.    return buffer;
  113. }
  114.  
  115. static void
  116. shm_handle_format(void *data, struct wl_shm *shm, uint32_t format)
  117. {
  118.    struct wayland_shm_display *shmdpy = data;
  119.  
  120.    switch (format) {
  121.    case WL_SHM_FORMAT_ARGB8888:
  122.       shmdpy->base.formats |= HAS_ARGB8888;
  123.       break;
  124.    case WL_SHM_FORMAT_XRGB8888:
  125.       shmdpy->base.formats |= HAS_XRGB8888;
  126.       break;
  127.    }
  128. }
  129.  
  130. static const struct wl_shm_listener shm_listener = {
  131.    shm_handle_format
  132. };
  133.  
  134. static void
  135. registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
  136.                        const char *interface, uint32_t version)
  137. {
  138.    struct wayland_shm_display *shmdpy = data;
  139.  
  140.    if (strcmp(interface, "wl_shm") == 0) {
  141.       shmdpy->wl_shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
  142.       wl_shm_add_listener(shmdpy->wl_shm, &shm_listener, shmdpy);
  143.    }
  144. }
  145.  
  146. static const struct wl_registry_listener registry_listener = {
  147.        registry_handle_global
  148. };
  149.  
  150. static boolean
  151. wayland_shm_display_init_screen(struct native_display *ndpy)
  152. {
  153.    struct wayland_shm_display *shmdpy = wayland_shm_display(ndpy);
  154.    struct sw_winsys *winsys = NULL;
  155.  
  156.    shmdpy->base.queue = wl_display_create_queue(shmdpy->base.dpy);
  157.    shmdpy->base.registry = wl_display_get_registry(shmdpy->base.dpy);
  158.    wl_proxy_set_queue((struct wl_proxy *) shmdpy->base.registry,
  159.                       shmdpy->base.queue);
  160.    wl_registry_add_listener(shmdpy->base.registry, &registry_listener, shmdpy);
  161.    if (wayland_roundtrip(&shmdpy->base) < 0 || shmdpy->wl_shm == NULL)
  162.       return FALSE;
  163.  
  164.    if (shmdpy->base.formats == 0)
  165.       wayland_roundtrip(&shmdpy->base);
  166.    if (shmdpy->base.formats == 0)
  167.       return FALSE;
  168.  
  169.    winsys = wayland_create_sw_winsys(shmdpy->base.dpy);
  170.    if (!winsys)
  171.       return FALSE;
  172.  
  173.    shmdpy->base.base.screen =
  174.       shmdpy->event_handler->new_sw_screen(&shmdpy->base.base, winsys);
  175.  
  176.    if (!shmdpy->base.base.screen) {
  177.       _eglLog(_EGL_WARNING, "failed to create shm screen");
  178.       return FALSE;
  179.    }
  180.  
  181.    return TRUE;
  182. }
  183.  
  184. struct wayland_display *
  185. wayland_create_shm_display(struct wl_display *dpy,
  186.                            const struct native_event_handler *event_handler)
  187. {
  188.    struct wayland_shm_display *shmdpy;
  189.  
  190.    shmdpy = CALLOC_STRUCT(wayland_shm_display);
  191.    if (!shmdpy)
  192.       return NULL;
  193.  
  194.    shmdpy->event_handler = event_handler;
  195.  
  196.    shmdpy->base.dpy = dpy;
  197.    if (!shmdpy->base.dpy) {
  198.       wayland_shm_display_destroy(&shmdpy->base.base);
  199.       return NULL;
  200.    }
  201.  
  202.    shmdpy->base.base.init_screen = wayland_shm_display_init_screen;
  203.    shmdpy->base.base.destroy = wayland_shm_display_destroy;
  204.    shmdpy->base.create_buffer = wayland_create_shm_buffer;
  205.  
  206.    return &shmdpy->base;
  207. }
  208.  
  209. /* vim: set sw=3 ts=8 sts=3 expandtab: */
  210.