Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the
  6.  * "Software"), to deal in the Software without restriction, including
  7.  * without limitation the rights to use, copy, modify, merge, publish,
  8.  * distribute, sub license, and/or sell copies of the Software, and to
  9.  * permit persons to whom the Software is furnished to do so, subject to
  10.  * the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the
  13.  * next paragraph) shall be included in all copies or substantial portions
  14.  * of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  19.  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
  20.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #ifdef IN_LIBVA
  28. # include "va/wayland/va_wayland.h"
  29. #else
  30. # include <va/va_wayland.h>
  31. #endif
  32. #include "va_display.h"
  33.  
  34. struct display {
  35.     struct wl_display          *display;
  36.     struct wl_registry         *registry;
  37.     struct wl_compositor       *compositor;
  38.     struct wl_shell            *shell;
  39.     struct wl_shell_surface    *shell_surface;
  40.     struct wl_surface          *surface;
  41.     unsigned int                ref_count;
  42.     int                         event_fd;
  43. };
  44.  
  45. static struct display *g_display;
  46.  
  47. static void
  48. registry_handle_global(
  49.     void               *data,
  50.     struct wl_registry *registry,
  51.     uint32_t            id,
  52.     const char         *interface,
  53.     uint32_t            version
  54. )
  55. {
  56.     struct display * const d = data;
  57.  
  58.     if (strcmp(interface, "wl_compositor") == 0)
  59.         d->compositor =
  60.             wl_registry_bind(registry, id, &wl_compositor_interface, 1);
  61.     else if (strcmp(interface, "wl_shell") == 0)
  62.         d->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
  63. }
  64.  
  65. static const struct wl_registry_listener registry_listener = {
  66.     registry_handle_global,
  67.     NULL,
  68. };
  69.  
  70. static VADisplay
  71. va_open_display_wayland(void)
  72. {
  73.     struct display *d;
  74.  
  75.     if (g_display) {
  76.         d = g_display;
  77.         d->ref_count++;
  78.     }
  79.     else {
  80.         d = calloc(1, sizeof(*d));
  81.         if (!d)
  82.             return NULL;
  83.         d->event_fd = -1;
  84.  
  85.         d->display = wl_display_connect(NULL);
  86.         if (!d->display) {
  87.             free(d);
  88.             return NULL;
  89.         }
  90.         wl_display_set_user_data(d->display, d);
  91.         d->registry = wl_display_get_registry(d->display);
  92.         wl_registry_add_listener(d->registry, &registry_listener, d);
  93.         d->event_fd = wl_display_get_fd(d->display);
  94.         wl_display_dispatch(d->display);
  95.  
  96.         d->ref_count = 1;
  97.         g_display = d;
  98.     }
  99.     return vaGetDisplayWl(d->display);
  100. }
  101.  
  102. static void
  103. va_close_display_wayland(VADisplay va_dpy)
  104. {
  105.     struct display * const d = g_display;
  106.  
  107.     if (!d || --d->ref_count > 0)
  108.         return;
  109.  
  110.     if (d->surface) {
  111.         wl_surface_destroy(d->surface);
  112.         d->surface = NULL;
  113.     }
  114.  
  115.     if (d->shell_surface) {
  116.         wl_shell_surface_destroy(d->shell_surface);
  117.         d->shell_surface = NULL;
  118.     }
  119.  
  120.     if (d->shell) {
  121.         wl_shell_destroy(d->shell);
  122.         d->shell = NULL;
  123.     }
  124.  
  125.     if (d->compositor) {
  126.         wl_compositor_destroy(d->compositor);
  127.         d->compositor = NULL;
  128.     }
  129.  
  130.     if (d->display) {
  131.         wl_display_disconnect(d->display);
  132.         d->display = NULL;
  133.     }
  134.     free(g_display);
  135.     g_display = NULL;
  136. }
  137.  
  138. static int
  139. ensure_window(VADisplay va_dpy, unsigned int width, unsigned int height)
  140. {
  141.     struct display * const d = g_display;
  142.  
  143.     if (!d->surface) {
  144.         d->surface = wl_compositor_create_surface(d->compositor);
  145.         if (!d->surface)
  146.             return 0;
  147.     }
  148.  
  149.     if (!d->shell_surface) {
  150.         d->shell_surface = wl_shell_get_shell_surface(d->shell, d->surface);
  151.         if (!d->shell_surface)
  152.             return 0;
  153.         wl_shell_surface_set_toplevel(d->shell_surface);
  154.     }
  155.     return 1;
  156. }
  157.  
  158. static VAStatus
  159. va_put_surface_wayland(
  160.     VADisplay          va_dpy,
  161.     VASurfaceID        surface,
  162.     const VARectangle *src_rect,
  163.     const VARectangle *dst_rect
  164. )
  165. {
  166.     struct display * const d = g_display;
  167.     VAStatus va_status;
  168.     struct wl_buffer *buffer;
  169.  
  170.     if (!ensure_window(va_dpy, dst_rect->width, dst_rect->height))
  171.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  172.  
  173.     va_status = vaGetSurfaceBufferWl(va_dpy, surface, VA_FRAME_PICTURE, &buffer);
  174.     if (va_status != VA_STATUS_SUCCESS)
  175.         return va_status;
  176.  
  177.     wl_surface_attach(d->surface, buffer, 0, 0);
  178.     wl_surface_damage(
  179.          d->surface,
  180.          dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height
  181.      );
  182.  
  183.     wl_surface_commit(d->surface);
  184.     wl_display_flush(d->display);
  185.     return VA_STATUS_SUCCESS;
  186. }
  187.  
  188. const VADisplayHooks va_display_hooks_wayland = {
  189.     "wayland",
  190.     va_open_display_wayland,
  191.     va_close_display_wayland,
  192.     va_put_surface_wayland,
  193. };
  194.