Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * va_wayland_drm.c - Wayland/DRM helpers
  3.  *
  4.  * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27. #include "sysdeps.h"
  28. #include <unistd.h>
  29. #include <errno.h>
  30. #include <fcntl.h>
  31. #include <dlfcn.h>
  32. #include <sys/stat.h>
  33. #include <xf86drm.h>
  34. #include "va_drmcommon.h"
  35. #include "drm/va_drm_utils.h"
  36. #include "va_wayland_drm.h"
  37. #include "va_wayland_private.h"
  38. #include "wayland-drm-client-protocol.h"
  39.  
  40. /* XXX: Wayland/DRM support currently lives in Mesa libEGL.so.* library */
  41. #define LIBWAYLAND_DRM_NAME "libEGL.so.1"
  42.  
  43. typedef struct va_wayland_drm_context {
  44.     struct va_wayland_context   base;
  45.     void                       *handle;
  46.     struct wl_drm              *drm;
  47.     struct wl_registry         *registry;
  48.     void                       *drm_interface;
  49.     unsigned int                is_authenticated        : 1;
  50. } VADisplayContextWaylandDRM;
  51.  
  52. static void
  53. drm_handle_device(void *data, struct wl_drm *drm, const char *device)
  54. {
  55.     VADisplayContextP const pDisplayContext = data;
  56.     VADriverContextP const ctx = pDisplayContext->pDriverContext;
  57.     VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque;
  58.     struct drm_state * const drm_state = ctx->drm_state;
  59.     drm_magic_t magic;
  60.     struct stat st;
  61.  
  62.     if (stat(device, &st) < 0) {
  63.         va_wayland_error("failed to identify %s: %s (errno %d)",
  64.                          device, strerror(errno), errno);
  65.         return;
  66.     }
  67.  
  68.     if (!S_ISCHR(st.st_mode)) {
  69.         va_wayland_error("%s is not a device", device);
  70.         return;
  71.     }
  72.  
  73.     drm_state->fd = open(device, O_RDWR);
  74.     if (drm_state->fd < 0) {
  75.         va_wayland_error("failed to open %s: %s (errno %d)",
  76.                          device, strerror(errno), errno);
  77.         return;
  78.     }
  79.  
  80.     drmGetMagic(drm_state->fd, &magic);
  81.     wl_drm_authenticate(wl_drm_ctx->drm, magic);
  82. }
  83.  
  84. static void
  85. drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
  86. {
  87. }
  88.  
  89. static void
  90. drm_handle_authenticated(void *data, struct wl_drm *drm)
  91. {
  92.     VADisplayContextP const pDisplayContext = data;
  93.     VADriverContextP const ctx = pDisplayContext->pDriverContext;
  94.     VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque;
  95.     struct drm_state * const drm_state = ctx->drm_state;
  96.  
  97.     wl_drm_ctx->is_authenticated = 1;
  98.     drm_state->auth_type         = VA_DRM_AUTH_CUSTOM;
  99. }
  100.  
  101. static const struct wl_drm_listener drm_listener = {
  102.     drm_handle_device,
  103.     drm_handle_format,
  104.     drm_handle_authenticated
  105. };
  106.  
  107. static VAStatus
  108. va_DisplayContextGetDriverName(
  109.     VADisplayContextP pDisplayContext,
  110.     char            **driver_name_ptr
  111. )
  112. {
  113.     VADriverContextP const ctx = pDisplayContext->pDriverContext;
  114.  
  115.     return VA_DRM_GetDriverName(ctx, driver_name_ptr);
  116. }
  117.  
  118. void
  119. va_wayland_drm_destroy(VADisplayContextP pDisplayContext)
  120. {
  121.     VADriverContextP const ctx = pDisplayContext->pDriverContext;
  122.     struct va_wayland_drm_context * const wl_drm_ctx = pDisplayContext->opaque;
  123.     struct drm_state * const drm_state = ctx->drm_state;
  124.  
  125.     if (wl_drm_ctx->drm) {
  126.         wl_drm_destroy(wl_drm_ctx->drm);
  127.         wl_drm_ctx->drm = NULL;
  128.     }
  129.     wl_drm_ctx->is_authenticated = 0;
  130.  
  131.     if (wl_drm_ctx->handle) {
  132.         dlclose(wl_drm_ctx->handle);
  133.         wl_drm_ctx->handle = NULL;
  134.     }
  135.  
  136.     if (drm_state) {
  137.         if (drm_state->fd >= 0) {
  138.             close(drm_state->fd);
  139.             drm_state->fd = -1;
  140.         }
  141.         free(ctx->drm_state);
  142.         ctx->drm_state = NULL;
  143.     }
  144. }
  145.  
  146. static void
  147. registry_handle_global(
  148.     void               *data,
  149.     struct wl_registry *registry,
  150.     uint32_t            id,
  151.     const char         *interface,
  152.     uint32_t            version
  153. )
  154. {
  155.     struct va_wayland_drm_context *wl_drm_ctx = data;
  156.  
  157.     if (strcmp(interface, "wl_drm") == 0) {
  158.         wl_drm_ctx->drm =
  159.             wl_registry_bind(wl_drm_ctx->registry, id, wl_drm_ctx->drm_interface, 1);
  160.     }
  161. }
  162.  
  163. static const struct wl_registry_listener registry_listener = {
  164.     registry_handle_global,
  165.     NULL,
  166. };
  167.  
  168. bool
  169. va_wayland_drm_create(VADisplayContextP pDisplayContext)
  170. {
  171.     VADriverContextP const ctx = pDisplayContext->pDriverContext;
  172.     struct va_wayland_drm_context *wl_drm_ctx;
  173.     struct drm_state *drm_state;
  174.     uint32_t id;
  175.  
  176.     wl_drm_ctx = malloc(sizeof(*wl_drm_ctx));
  177.     if (!wl_drm_ctx)
  178.         return false;
  179.     wl_drm_ctx->base.destroy            = va_wayland_drm_destroy;
  180.     wl_drm_ctx->handle                  = NULL;
  181.     wl_drm_ctx->drm                     = NULL;
  182.     wl_drm_ctx->drm_interface           = NULL;
  183.     wl_drm_ctx->is_authenticated        = 0;
  184.     pDisplayContext->opaque             = wl_drm_ctx;
  185.     pDisplayContext->vaGetDriverName    = va_DisplayContextGetDriverName;
  186.  
  187.     drm_state = calloc(1, sizeof(struct drm_state));
  188.     if (!drm_state)
  189.         return false;
  190.     drm_state->fd        = -1;
  191.     drm_state->auth_type = 0;
  192.     ctx->drm_state       = drm_state;
  193.  
  194.     wl_drm_ctx->handle = dlopen(LIBWAYLAND_DRM_NAME, RTLD_LAZY|RTLD_LOCAL);
  195.     if (!wl_drm_ctx->handle)
  196.         return false;
  197.  
  198.     wl_drm_ctx->drm_interface =
  199.         dlsym(wl_drm_ctx->handle, "wl_drm_interface");
  200.     if (!wl_drm_ctx->drm_interface)
  201.         return false;
  202.  
  203.     wl_drm_ctx->registry = wl_display_get_registry(ctx->native_dpy);
  204.     wl_registry_add_listener(wl_drm_ctx->registry, &registry_listener, wl_drm_ctx);
  205.     wl_display_roundtrip(ctx->native_dpy);
  206.  
  207.     /* registry_handle_global should have been called by the
  208.      * wl_display_roundtrip above
  209.      */
  210.  
  211.     if (!wl_drm_ctx->drm)
  212.         return false;
  213.  
  214.     wl_drm_add_listener(wl_drm_ctx->drm, &drm_listener, pDisplayContext);
  215.     wl_display_roundtrip(ctx->native_dpy);
  216.     if (drm_state->fd < 0)
  217.         return false;
  218.  
  219.     wl_display_roundtrip(ctx->native_dpy);
  220.     if (!wl_drm_ctx->is_authenticated)
  221.         return false;
  222.     return true;
  223. }
  224.