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 <stdlib.h>
  26. #include <sys/types.h>
  27. #include <sys/mman.h>
  28. #include <unistd.h>
  29.  
  30. #include "pipe/p_compiler.h"
  31. #include "pipe/p_defines.h"
  32. #include "pipe/p_state.h"
  33. #include "util/u_format.h"
  34. #include "util/u_math.h"
  35. #include "util/u_memory.h"
  36. #include "state_tracker/sw_winsys.h"
  37.  
  38. #include <wayland-client.h>
  39. #include "wayland_sw_winsys.h"
  40.  
  41. struct wayland_sw_displaytarget
  42. {
  43.    int fd;
  44.    unsigned size;
  45.  
  46.    unsigned width;
  47.    unsigned height;
  48.    unsigned stride;
  49.  
  50.    enum pipe_format format;
  51.  
  52.    void *map;
  53.    unsigned map_count;
  54. };
  55.  
  56. struct wayland_sw_winsys
  57. {
  58.    struct sw_winsys base;
  59.  
  60.    struct wl_display *display;
  61. };
  62.  
  63. static INLINE struct wayland_sw_displaytarget *
  64. wayland_sw_displaytarget(struct sw_displaytarget *dt)
  65. {
  66.    return (struct wayland_sw_displaytarget *) dt;
  67. }
  68.  
  69. static INLINE struct wayland_sw_winsys *
  70. wayland_sw_winsys(struct sw_winsys *ws)
  71. {
  72.    return (struct wayland_sw_winsys *) ws;
  73. }
  74.  
  75. static void
  76. wayland_displaytarget_display(struct sw_winsys *ws,
  77.                               struct sw_displaytarget *dt,
  78.                               void *context_private)
  79. {
  80. }
  81.  
  82. static void
  83. wayland_displaytarget_unmap(struct sw_winsys *ws,
  84.                             struct sw_displaytarget *dt)
  85. {
  86.    struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt);
  87.  
  88.    wldt->map_count--;
  89.    if (wldt->map_count > 0)
  90.       return;
  91.  
  92.    munmap(wldt->map, wldt->size);
  93.    wldt->map = NULL;
  94. }
  95.  
  96. static void *
  97. wayland_displaytarget_map(struct sw_winsys *ws,
  98.                           struct sw_displaytarget *dt,
  99.                           unsigned flags)
  100. {
  101.    struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt);
  102.    uint mmap_flags = 0;
  103.  
  104.    if (wldt->map) {
  105.       wldt->map_count++;
  106.       return wldt->map;
  107.    }
  108.  
  109.    if (flags & PIPE_TRANSFER_READ)
  110.       mmap_flags |= PROT_READ;
  111.    if (flags & PIPE_TRANSFER_WRITE)
  112.       mmap_flags |= PROT_WRITE;
  113.  
  114.    wldt->map = mmap(NULL, wldt->size, mmap_flags,
  115.                     MAP_SHARED, wldt->fd, 0);
  116.  
  117.    if (wldt->map == MAP_FAILED)
  118.       return NULL;
  119.  
  120.    wldt->map_count = 1;
  121.  
  122.    return wldt->map;
  123. }
  124.  
  125. static void
  126. wayland_displaytarget_destroy(struct sw_winsys *ws,
  127.                               struct sw_displaytarget *dt)
  128. {
  129.    struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt);
  130.  
  131.    if (wldt->map)
  132.       wayland_displaytarget_unmap(ws, dt);
  133.  
  134.    FREE(wldt);
  135. }
  136.  
  137. static boolean
  138. wayland_is_displaytarget_format_supported(struct sw_winsys *ws,
  139.                                           unsigned tex_usage,
  140.                                           enum pipe_format format)
  141. {
  142.    switch (format) {
  143.    case PIPE_FORMAT_B8G8R8X8_UNORM:
  144.    case PIPE_FORMAT_B8G8R8A8_UNORM:
  145.       return TRUE;
  146.    default:
  147.       return FALSE;
  148.    }
  149. }
  150.  
  151. static struct sw_displaytarget *
  152. wayland_displaytarget_create(struct sw_winsys *ws,
  153.                              unsigned tex_usage,
  154.                              enum pipe_format format,
  155.                              unsigned width, unsigned height,
  156.                              unsigned alignment,
  157.                              unsigned *stride)
  158. {
  159.    struct wayland_sw_displaytarget *wldt;
  160.    unsigned nblocksy, format_stride;
  161.    char filename[] = "/tmp/wayland-shm-XXXXXX";
  162.  
  163.    if (!wayland_is_displaytarget_format_supported(ws, tex_usage, format))
  164.       return NULL;
  165.  
  166.    wldt = CALLOC_STRUCT(wayland_sw_displaytarget);
  167.    if (!wldt)
  168.       return NULL;
  169.  
  170.    wldt->map = NULL;
  171.  
  172.    wldt->format = format;
  173.    wldt->width = width;
  174.    wldt->height = height;
  175.  
  176.    format_stride = util_format_get_stride(format, width);
  177.    wldt->stride = align(format_stride, alignment);
  178.  
  179.    nblocksy = util_format_get_nblocksy(format, height);
  180.    wldt->size = wldt->stride * nblocksy;
  181.  
  182.    wldt->fd = mkstemp(filename);
  183.    if (wldt->fd < 0) {
  184.       FREE(wldt);
  185.       return NULL;
  186.    }
  187.  
  188.    if (ftruncate(wldt->fd, wldt->size) < 0) {
  189.       unlink(filename);
  190.       close(wldt->fd);
  191.       FREE(wldt);
  192.       return NULL;
  193.    }
  194.  
  195.    unlink(filename);
  196.  
  197.    *stride = wldt->stride;
  198.  
  199.    return (struct sw_displaytarget *) wldt;
  200. }
  201.  
  202. static struct sw_displaytarget *
  203. wayland_displaytarget_from_handle(struct sw_winsys *ws,
  204.                                   const struct pipe_resource *templet,
  205.                                   struct winsys_handle *whandle,
  206.                                   unsigned *stride)
  207. {
  208.    struct wayland_sw_displaytarget *wldt;
  209.    unsigned nblocksy;
  210.  
  211.    if (!wayland_is_displaytarget_format_supported(ws, 0, templet->format))
  212.       return NULL;
  213.  
  214.    wldt = CALLOC_STRUCT(wayland_sw_displaytarget);
  215.    if (!wldt)
  216.       return NULL;
  217.  
  218.    wldt->fd = whandle->fd;
  219.    wldt->stride = whandle->stride;
  220.    wldt->width = templet->width0;
  221.    wldt->height = templet->height0;
  222.    wldt->format = templet->format;
  223.  
  224.    nblocksy = util_format_get_nblocksy(wldt->format, wldt->height);
  225.  
  226.    wldt->size = wldt->stride * nblocksy;
  227.  
  228.    wldt->map = NULL;
  229.  
  230.    *stride = wldt->stride;
  231.  
  232.    return (struct sw_displaytarget *) wldt;
  233. }
  234.  
  235.  
  236. static boolean
  237. wayland_displaytarget_get_handle(struct sw_winsys *ws,
  238.                                  struct sw_displaytarget *dt,
  239.                                  struct winsys_handle *whandle)
  240. {
  241.    struct wayland_sw_displaytarget *wldt = wayland_sw_displaytarget(dt);
  242.  
  243.    whandle->fd = wldt->fd;
  244.    whandle->stride = wldt->stride;
  245.    whandle->size = wldt->size;
  246.  
  247.    return TRUE;
  248. }
  249.  
  250. static void
  251. wayland_destroy(struct sw_winsys *ws)
  252. {
  253.    struct wayland_sw_winsys *wayland = wayland_sw_winsys(ws);
  254.  
  255.    FREE(wayland);
  256. }
  257.  
  258. struct sw_winsys *
  259. wayland_create_sw_winsys(struct wl_display *display)
  260. {
  261.    struct wayland_sw_winsys *wlws;
  262.  
  263.    wlws = CALLOC_STRUCT(wayland_sw_winsys);
  264.    if (!wlws)
  265.       return NULL;
  266.  
  267.    wlws->display = display;
  268.  
  269.    wlws->base.destroy = wayland_destroy;
  270.    wlws->base.is_displaytarget_format_supported =
  271.       wayland_is_displaytarget_format_supported;
  272.  
  273.    wlws->base.displaytarget_create = wayland_displaytarget_create;
  274.    wlws->base.displaytarget_from_handle = wayland_displaytarget_from_handle;
  275.    wlws->base.displaytarget_get_handle = wayland_displaytarget_get_handle;
  276.    wlws->base.displaytarget_destroy = wayland_displaytarget_destroy;
  277.    wlws->base.displaytarget_map = wayland_displaytarget_map;
  278.    wlws->base.displaytarget_unmap = wayland_displaytarget_unmap;
  279.  
  280.    wlws->base.displaytarget_display = wayland_displaytarget_display;
  281.  
  282.    return &wlws->base;
  283. }
  284.  
  285. /* vim: set sw=3 ts=8 sts=3 expandtab: */
  286.