From patchwork Thu Nov 28 09:24:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 21829 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-vc0-f198.google.com (mail-vc0-f198.google.com [209.85.220.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id E8ABB23FC4 for ; Thu, 28 Nov 2013 09:24:54 +0000 (UTC) Received: by mail-vc0-f198.google.com with SMTP id ld13sf18073635vcb.1 for ; Thu, 28 Nov 2013 01:24:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:mime-version:in-reply-to:references :date:message-id:from:to:cc:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list:content-type; bh=a0d3vks05ltFqAzWkgSN/B8Z1PsofRb3l5Y+e9LUlEg=; b=OqXkQV22jG2CBfuRyvZCrkPEvcqwErtpkRaTVoCwEfhkOLjWYogmZPeoj9uc7QFZlu 9NE8dqJ2ci64BR1F1/hc8cGc1I9SHTATF06Yds0Ti62jxBcgYkN8NQQtAw1idK3hI6i9 7N2CynbEYomjyTTJthTUJSYX0vwn1tjQFK9Fl5uIXn85AsqznMkol22IBC3dEFQV+uFJ y75oIaMWODDoVZWQ5nBVWeHZIphF8VCN3VVG/Y9E8r+lJzQTAL2+ewWO8KFBoyz/ImkS KaqorFJBty8ObOptGwZ9LzBKj75SCYjEsmcTkmxMyu7wcrz2U8siGYNAhxDrlNerwP8T ON9Q== X-Gm-Message-State: ALoCoQmyFkQPLAHjtRyagIIVlmVsagjlR5BDGHe2owsQ/0h3BwUS0N8SSa/BxK8s2UPtIOEYzxup X-Received: by 10.58.112.195 with SMTP id is3mr14993953veb.29.1385630694058; Thu, 28 Nov 2013 01:24:54 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.119.196 with SMTP id kw4ls3267804qeb.90.gmail; Thu, 28 Nov 2013 01:24:53 -0800 (PST) X-Received: by 10.52.248.234 with SMTP id yp10mr534937vdc.14.1385630693925; Thu, 28 Nov 2013 01:24:53 -0800 (PST) Received: from mail-ve0-f170.google.com (mail-ve0-f170.google.com [209.85.128.170]) by mx.google.com with ESMTPS id tr2si3547031vdc.3.2013.11.28.01.24.53 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 28 Nov 2013 01:24:53 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.170; Received: by mail-ve0-f170.google.com with SMTP id oy12so5993124veb.15 for ; Thu, 28 Nov 2013 01:24:53 -0800 (PST) X-Received: by 10.52.98.194 with SMTP id ek2mr31355587vdb.11.1385630693824; Thu, 28 Nov 2013 01:24:53 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp1025vcz; Thu, 28 Nov 2013 01:24:52 -0800 (PST) X-Received: by 10.14.182.199 with SMTP id o47mr47391223eem.7.1385630692379; Thu, 28 Nov 2013 01:24:52 -0800 (PST) Received: from ip-10-141-164-156.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id b42si33183086eem.12.2013.11.28.01.24.51 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 28 Nov 2013 01:24:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-141-164-156.ec2.internal) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1VlxnD-0002eK-Lj; Thu, 28 Nov 2013 09:21:51 +0000 Received: from mail-lb0-f177.google.com ([209.85.217.177]) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1Vlxn5-0002eF-Pn for linaro-mm-sig@lists.linaro.org; Thu, 28 Nov 2013 09:21:44 +0000 Received: by mail-lb0-f177.google.com with SMTP id w7so5963279lbi.36 for ; Thu, 28 Nov 2013 01:24:34 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.112.171.228 with SMTP id ax4mr30722584lbc.6.1385630674120; Thu, 28 Nov 2013 01:24:34 -0800 (PST) Received: by 10.114.99.2 with HTTP; Thu, 28 Nov 2013 01:24:33 -0800 (PST) In-Reply-To: References: Date: Thu, 28 Nov 2013 10:24:33 +0100 Message-ID: From: Benjamin Gaignard To: "Jasper St. Pierre" Cc: "linaro-mm-sig@lists.linaro.org" , mesa-dev@lists.freedesktop.org, Jason Ekstrand , "wayland-devel@lists.freedesktop.org" Subject: Re: [Linaro-mm-sig] Move wayland-drm protocol from Mesa to wayland-core X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Errors-To: linaro-mm-sig-bounces@lists.linaro.org Sender: linaro-mm-sig-bounces@lists.linaro.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: benjamin.gaignard@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Jason, >From my point of view wl_drm isn't link to Mesa, it is only about exchange buffers by using a file descriptor and, for example, doesn't rely on EGL. I understand that other graphic stacks could have defined their own way to for zero-copy (and so other protocols). I don't aim to make gstreamer wayland sink works for all of them but at least with wl_drm protocol which is quite generic. Since dmabuf has been adopted in kernel we have the opportunity to rationalize also some code in userland and for that we need a common wayland protocol. Move wl_drm into wayland-core make it more easily accessible for all software even for those who don't use Mesa. Benjamin PS: I have an updated version of my patch for latest wayland 2013/11/27 Jasper St. Pierre : > Wasn't EGLStreams supposed to solve the use case of passing hardware buffers > around in a standard way? > > > On Wed, Nov 27, 2013 at 1:22 PM, Jason Ekstrand > wrote: >> >> >> On Nov 27, 2013 10:53 AM, "Benjamin Gaignard" >> wrote: >> > >> > Hi all, >> > >> > I'm working for Linaro on enabling a zero copy path in GStreamer by >> > using dmabuf. >> > To make this possible I have patched gst wayland sink to use wayland >> > drm protocol: https://bugzilla.gnome.org/show_bug.cgi?id=711155 >> > >> > Today wayland drm protocol is limited to Mesa so I have decided to >> > move it into wayland-core. >> > My hardware doesn't have gpu support yet so I have patched weston >> > (pixman) to allow usage of wl_drm buffers. >> > With this I able to share/use a buffer allocated by DRM in gstreamer >> > pipeline even if I don't have gpu and EGL. >> > >> > What do you think about make wayland drm protocol available like this ? >> >> Benjamin, >> >> The problem here is that wl_drm is really a mesa extension. Well, more of >> an open-source linux graphics stack extension. The point is that there are >> other graphics stacks: Rhaspberry Pi, libhybris, other proprietary stacks, >> etc. and each of these graphics stacks has its own extension for passing >> hardware buffers around. This means that if you want your GStreamer sink to >> work on these other stacks with zero-copy, you will have to talk their >> protocols. Because wl_drm isn't global to all of wayland, it probably >> shouldn't go into the wayland core. >> >> This does not mean, however, that wl_drm can't be exposed in a more >> sensible way. As of 1.3, we are now exporting wayland.xml to >> /usr/share/wayland and we can put other extensions there as well. We could >> have, for instance, a /usr/share/mesa.xml file that provides the mesa >> extensions. Then projects wanting to talk directly to mesa can generate the >> header and C files from the system-installed xml file. This would solve the >> problem of keeping everything in sync. >> >> One last note (this one's been bugging me for a while). If we are going >> to export wl_drm in some way, we should probably rename it to something like >> mesa_drm. We really need to get out of the habit of using the wl_ namespace >> for everything that talks the wayland protocol. If we don't alter the >> details of wl_drm in the rename, it shouldn't be too hard to move everyone >> over from wl_drm to mesa_drm. >> >> Hope that's sensible/helpful. >> --Jason Ekstrand >> >> >> _______________________________________________ >> wayland-devel mailing list >> wayland-devel@lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/wayland-devel >> > > > > -- > Jasper >From fe24018437529affead57dcdf1d9425f11f2c6dd Mon Sep 17 00:00:00 2001 From: Benjamin Gaignard Date: Thu, 28 Nov 2013 09:55:38 +0100 Subject: [PATCH] Move wayland-drm protocol from mesa to wayland-core. Add WL_EXPORT to function declaration. Add {get/put}_data callback to get access to memory. Signed-off-by: Benjamin Gaignard --- protocol/Makefile.am | 6 +- protocol/wayland-drm.xml | 182 ++++++++++++++++++++++ src/Makefile.am | 11 +- src/wayland-drm.c | 377 ++++++++++++++++++++++++++++++++++++++++++++++ src/wayland-drm.h | 131 ++++++++++++++++ 5 files changed, 703 insertions(+), 4 deletions(-) create mode 100644 protocol/wayland-drm.xml create mode 100644 src/wayland-drm.c create mode 100644 src/wayland-drm.h diff --git a/protocol/Makefile.am b/protocol/Makefile.am index e8b6290..836e8dd 100644 --- a/protocol/Makefile.am +++ b/protocol/Makefile.am @@ -1,4 +1,4 @@ -dist_pkgdata_DATA = wayland.xml wayland.dtd +dist_pkgdata_DATA = wayland.xml wayland-drm.xml wayland.dtd if HAVE_XMLLINT .PHONY: validate @@ -6,9 +6,9 @@ if HAVE_XMLLINT .%.xml.valid: %.xml $(AM_V_GEN)$(XMLLINT) --noout --dtdvalid $(srcdir)/wayland.dtd $^ > $@ -validate: .wayland.xml.valid +validate: .wayland.xml.valid .wayland-drm.xml.valid all-local: validate -CLEANFILES = .wayland.xml.valid +CLEANFILES = .wayland.xml.valid .wayland-drm.xml.valid endif diff --git a/protocol/wayland-drm.xml b/protocol/wayland-drm.xml new file mode 100644 index 0000000..8a3ad69 --- /dev/null +++ b/protocol/wayland-drm.xml @@ -0,0 +1,182 @@ + + + + + Copyright © 2008-2011 Kristian Høgsberg + Copyright © 2010-2011 Intel Corporation + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that\n the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bitmask of capabilities. + + + + + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 15f44a5..250906c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,8 +4,11 @@ noinst_LTLIBRARIES = libwayland-util.la include_HEADERS = \ wayland-util.h \ wayland-server-protocol.h \ + wayland-drm-server-protocol.h \ wayland-server.h \ + wayland-drm.h \ wayland-client-protocol.h \ + wayland-drm-client-protocol.h \ wayland-client.h \ wayland-egl.h \ wayland-version.h @@ -22,14 +25,17 @@ libwayland_server_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt -lm libwayland_server_la_LDFLAGS = -version-info 1:0:1 libwayland_server_la_SOURCES = \ wayland-protocol.c \ + wayland-drm-protocol.c \ wayland-server.c \ wayland-shm.c \ + wayland-drm.c \ event-loop.c libwayland_client_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt -lm libwayland_client_la_LDFLAGS = -version-info 2:0:2 libwayland_client_la_SOURCES = \ wayland-protocol.c \ + wayland-drm-protocol.c \ wayland-client.c pkgconfigdir = $(libdir)/pkgconfig @@ -65,7 +71,10 @@ endif BUILT_SOURCES = \ wayland-server-protocol.h \ wayland-client-protocol.h \ - wayland-protocol.c + wayland-protocol.c \ + wayland-drm-server-protocol.h \ + wayland-drm-client-protocol.h \ + wayland-drm-protocol.c CLEANFILES = $(BUILT_SOURCES) DISTCLEANFILES = wayland-version.h diff --git a/src/wayland-drm.c b/src/wayland-drm.c new file mode 100644 index 0000000..b5ce07f --- /dev/null +++ b/src/wayland-drm.c @@ -0,0 +1,377 @@ +/* + * Copyright © 2011 Kristian Høgsberg + * Copyright © 2011 Benjamin Franzke + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Kristian Høgsberg + * Benjamin Franzke + */ + +#include +#include +#include +#include +#include + +#include "wayland-server.h" +#include "wayland-drm.h" +#include "wayland-drm-server-protocol.h" + +#define MIN(x,y) (((x)<(y))?(x):(y)) + +struct wl_drm { + struct wl_display *display; + struct wl_global *wl_drm_global; + + void *user_data; + char *device_name; + uint32_t flags; + + struct wayland_drm_callbacks *callbacks; + + struct wl_buffer_interface buffer_interface; +}; + +static void +destroy_buffer(struct wl_resource *resource) +{ + struct wl_drm_buffer *buffer = resource->data; + struct wl_drm *drm = buffer->drm; + + drm->callbacks->release_buffer(drm->user_data, buffer); + free(buffer); +} + +static void +buffer_destroy(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +create_buffer(struct wl_client *client, struct wl_resource *resource, + uint32_t id, uint32_t name, int fd, + int32_t width, int32_t height, + uint32_t format, + int32_t offset0, int32_t stride0, + int32_t offset1, int32_t stride1, + int32_t offset2, int32_t stride2) +{ + struct wl_drm *drm = resource->data; + struct wl_drm_buffer *buffer; + + buffer = calloc(1, sizeof *buffer); + if (buffer == NULL) { + wl_resource_post_no_memory(resource); + return; + } + + buffer->drm = drm; + buffer->width = width; + buffer->height = height; + buffer->format = format; + buffer->offset[0] = offset0; + buffer->stride[0] = stride0; + buffer->offset[1] = offset1; + buffer->stride[1] = stride1; + buffer->offset[2] = offset2; + buffer->stride[2] = stride2; + + drm->callbacks->reference_buffer(drm->user_data, name, fd, buffer); + if (buffer->driver_buffer == NULL) { + wl_resource_post_error(resource, + WL_DRM_ERROR_INVALID_NAME, + "invalid name"); + return; + } + + buffer->resource = + wl_resource_create(client, &wl_buffer_interface, 1, id); + if (!buffer->resource) { + wl_resource_post_no_memory(resource); + free(buffer); + return; + } + + wl_resource_set_implementation(buffer->resource, + (void (**)(void)) &drm->buffer_interface, + buffer, destroy_buffer); +} + +static void +drm_create_buffer(struct wl_client *client, struct wl_resource *resource, + uint32_t id, uint32_t name, int32_t width, int32_t height, + uint32_t stride, uint32_t format) +{ + switch (format) { + case WL_DRM_FORMAT_ARGB8888: + case WL_DRM_FORMAT_XRGB8888: + case WL_DRM_FORMAT_YUYV: + case WL_DRM_FORMAT_RGB565: + break; + default: + wl_resource_post_error(resource, + WL_DRM_ERROR_INVALID_FORMAT, + "invalid format"); + return; + } + + create_buffer(client, resource, id, + name, -1, width, height, format, 0, stride, 0, 0, 0, 0); +} + +static void +drm_create_planar_buffer(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, uint32_t name, + int32_t width, int32_t height, uint32_t format, + int32_t offset0, int32_t stride0, + int32_t offset1, int32_t stride1, + int32_t offset2, int32_t stride2) +{ + switch (format) { + case WL_DRM_FORMAT_YUV410: + case WL_DRM_FORMAT_YUV411: + case WL_DRM_FORMAT_YUV420: + case WL_DRM_FORMAT_YUV422: + case WL_DRM_FORMAT_YUV444: + case WL_DRM_FORMAT_NV12: + case WL_DRM_FORMAT_NV16: + break; + default: + wl_resource_post_error(resource, + WL_DRM_ERROR_INVALID_FORMAT, + "invalid format"); + return; + } + + create_buffer(client, resource, id, name, -1, width, height, format, + offset0, stride0, offset1, stride1, offset2, stride2); +} + +static void +drm_create_prime_buffer(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, int fd, + int32_t width, int32_t height, uint32_t format, + int32_t offset0, int32_t stride0, + int32_t offset1, int32_t stride1, + int32_t offset2, int32_t stride2) +{ + create_buffer(client, resource, id, 0, fd, width, height, format, + offset0, stride0, offset1, stride1, offset2, stride2); + close(fd); +} + +static void +drm_authenticate(struct wl_client *client, + struct wl_resource *resource, uint32_t id) +{ + struct wl_drm *drm = resource->data; + + if (drm->callbacks->authenticate(drm->user_data, id) < 0) + wl_resource_post_error(resource, + WL_DRM_ERROR_AUTHENTICATE_FAIL, + "authenicate failed"); + else + wl_resource_post_event(resource, WL_DRM_AUTHENTICATED); +} + +static const struct wl_drm_interface drm_interface = { + drm_authenticate, + drm_create_buffer, + drm_create_planar_buffer, + drm_create_prime_buffer +}; + +static void +bind_drm(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + struct wl_drm *drm = data; + struct wl_resource *resource; + uint32_t capabilities; + + resource = wl_resource_create(client, &wl_drm_interface, + MIN(version, 2), id); + if (!resource) { + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(resource, &drm_interface, data, NULL); + + wl_resource_post_event(resource, WL_DRM_DEVICE, drm->device_name); + wl_resource_post_event(resource, WL_DRM_FORMAT, + WL_DRM_FORMAT_ARGB8888); + wl_resource_post_event(resource, WL_DRM_FORMAT, + WL_DRM_FORMAT_XRGB8888); + wl_resource_post_event(resource, WL_DRM_FORMAT, + WL_DRM_FORMAT_RGB565); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV410); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV411); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV420); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV422); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUV444); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV12); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_NV16); + wl_resource_post_event(resource, WL_DRM_FORMAT, WL_DRM_FORMAT_YUYV); + + capabilities = 0; + if (drm->flags & WAYLAND_DRM_PRIME) + capabilities |= WL_DRM_CAPABILITY_PRIME; + + if (version >= 2) + wl_resource_post_event(resource, WL_DRM_CAPABILITIES, capabilities); +} + +struct wl_drm_buffer * +wayland_drm_buffer_get(struct wl_drm *drm, struct wl_resource *resource) +{ + if (resource == NULL) + return NULL; + + if (wl_resource_instance_of(resource, &wl_buffer_interface, + &drm->buffer_interface)) + return wl_resource_get_user_data(resource); + else + return NULL; +} + +WL_EXPORT struct wl_drm * +wayland_drm_init(struct wl_display *display, char *device_name, + struct wayland_drm_callbacks *callbacks, void *user_data, + uint32_t flags) +{ + struct wl_drm *drm; + + drm = malloc(sizeof *drm); + + drm->display = display; + drm->device_name = strdup(device_name); + drm->callbacks = callbacks; + drm->user_data = user_data; + drm->flags = flags; + + drm->buffer_interface.destroy = buffer_destroy; + + drm->wl_drm_global = + wl_global_create(display, &wl_drm_interface, 2, + drm, bind_drm); + + return drm; +} + +WL_EXPORT void +wayland_drm_uninit(struct wl_drm *drm) +{ + free(drm->device_name); + + wl_global_destroy(drm->wl_drm_global); + + free(drm); +} + +WL_EXPORT int +wayland_buffer_is_drm(struct wl_drm_buffer *buffer) +{ + struct wl_drm *drm = buffer->drm; + + return wl_resource_instance_of(buffer->resource, + &wl_buffer_interface, &drm->buffer_interface); +} + +WL_EXPORT uint32_t +wayland_drm_buffer_get_format(struct wl_drm_buffer *buffer) +{ + if (!wayland_buffer_is_drm(buffer)) + return 0; + + return buffer->format; +} + +WL_EXPORT void * +wayland_drm_buffer_get_buffer(struct wl_drm_buffer *buffer) +{ + return buffer->driver_buffer; +} + +WL_EXPORT int32_t +wayland_drm_buffer_get_stride(struct wl_drm_buffer *buffer, int idx) +{ + if (!wayland_buffer_is_drm(buffer)) + return 0; + + return buffer->stride[idx]; +} + +WL_EXPORT void * +wayland_drm_buffer_get_data(struct wl_drm_buffer *buffer) +{ + struct wl_drm *drm; + + if (!wayland_buffer_is_drm(buffer)) + return NULL; + + drm = buffer->drm; + + if (drm->callbacks->get_data) + return drm->callbacks->get_data(drm->user_data, buffer); + + return NULL; +} + +WL_EXPORT void +wayland_drm_buffer_put_data(struct wl_drm_buffer *buffer) +{ + struct wl_drm *drm; + + if (!wayland_buffer_is_drm(buffer)) + return; + + drm = buffer->drm; + + if (drm->callbacks->put_data) + drm->callbacks->put_data(drm->user_data, buffer); + + return; +} + + +WL_EXPORT int32_t +wayland_drm_buffer_get_width(struct wl_drm_buffer *buffer) +{ + if (!wayland_buffer_is_drm(buffer)) + return 0; + + return buffer->width; +} + +WL_EXPORT int32_t +wayland_drm_buffer_get_height(struct wl_drm_buffer *buffer) +{ + if (!wayland_buffer_is_drm(buffer)) + return 0; + + return buffer->height; +} + diff --git a/src/wayland-drm.h b/src/wayland-drm.h new file mode 100644 index 0000000..e21d22b --- /dev/null +++ b/src/wayland-drm.h @@ -0,0 +1,131 @@ +#ifndef WAYLAND_DRM_H +#define WAYLAND_DRM_H + +#include + +#ifndef WL_DRM_FORMAT_ENUM +#define WL_DRM_FORMAT_ENUM +enum wl_drm_format { + WL_DRM_FORMAT_C8 = 0x20203843, + WL_DRM_FORMAT_RGB332 = 0x38424752, + WL_DRM_FORMAT_BGR233 = 0x38524742, + WL_DRM_FORMAT_XRGB4444 = 0x32315258, + WL_DRM_FORMAT_XBGR4444 = 0x32314258, + WL_DRM_FORMAT_RGBX4444 = 0x32315852, + WL_DRM_FORMAT_BGRX4444 = 0x32315842, + WL_DRM_FORMAT_ARGB4444 = 0x32315241, + WL_DRM_FORMAT_ABGR4444 = 0x32314241, + WL_DRM_FORMAT_RGBA4444 = 0x32314152, + WL_DRM_FORMAT_BGRA4444 = 0x32314142, + WL_DRM_FORMAT_XRGB1555 = 0x35315258, + WL_DRM_FORMAT_XBGR1555 = 0x35314258, + WL_DRM_FORMAT_RGBX5551 = 0x35315852, + WL_DRM_FORMAT_BGRX5551 = 0x35315842, + WL_DRM_FORMAT_ARGB1555 = 0x35315241, + WL_DRM_FORMAT_ABGR1555 = 0x35314241, + WL_DRM_FORMAT_RGBA5551 = 0x35314152, + WL_DRM_FORMAT_BGRA5551 = 0x35314142, + WL_DRM_FORMAT_RGB565 = 0x36314752, + WL_DRM_FORMAT_BGR565 = 0x36314742, + WL_DRM_FORMAT_RGB888 = 0x34324752, + WL_DRM_FORMAT_BGR888 = 0x34324742, + WL_DRM_FORMAT_XRGB8888 = 0x34325258, + WL_DRM_FORMAT_XBGR8888 = 0x34324258, + WL_DRM_FORMAT_RGBX8888 = 0x34325852, + WL_DRM_FORMAT_BGRX8888 = 0x34325842, + WL_DRM_FORMAT_ARGB8888 = 0x34325241, + WL_DRM_FORMAT_ABGR8888 = 0x34324241, + WL_DRM_FORMAT_RGBA8888 = 0x34324152, + WL_DRM_FORMAT_BGRA8888 = 0x34324142, + WL_DRM_FORMAT_XRGB2101010 = 0x30335258, + WL_DRM_FORMAT_XBGR2101010 = 0x30334258, + WL_DRM_FORMAT_RGBX1010102 = 0x30335852, + WL_DRM_FORMAT_BGRX1010102 = 0x30335842, + WL_DRM_FORMAT_ARGB2101010 = 0x30335241, + WL_DRM_FORMAT_ABGR2101010 = 0x30334241, + WL_DRM_FORMAT_RGBA1010102 = 0x30334152, + WL_DRM_FORMAT_BGRA1010102 = 0x30334142, + WL_DRM_FORMAT_YUYV = 0x56595559, + WL_DRM_FORMAT_YVYU = 0x55595659, + WL_DRM_FORMAT_UYVY = 0x59565955, + WL_DRM_FORMAT_VYUY = 0x59555956, + WL_DRM_FORMAT_AYUV = 0x56555941, + WL_DRM_FORMAT_NV12 = 0x3231564e, + WL_DRM_FORMAT_NV21 = 0x3132564e, + WL_DRM_FORMAT_NV16 = 0x3631564e, + WL_DRM_FORMAT_NV61 = 0x3136564e, + WL_DRM_FORMAT_YUV410 = 0x39565559, + WL_DRM_FORMAT_YVU410 = 0x39555659, + WL_DRM_FORMAT_YUV411 = 0x31315559, + WL_DRM_FORMAT_YVU411 = 0x31315659, + WL_DRM_FORMAT_YUV420 = 0x32315559, + WL_DRM_FORMAT_YVU420 = 0x32315659, + WL_DRM_FORMAT_YUV422 = 0x36315559, + WL_DRM_FORMAT_YVU422 = 0x36315659, + WL_DRM_FORMAT_YUV444 = 0x34325559, + WL_DRM_FORMAT_YVU444 = 0x34325659, +}; +#endif /* WL_DRM_FORMAT_ENUM */ + +struct wl_drm; + +struct wl_drm_buffer { + struct wl_resource *resource; + struct wl_drm *drm; + int32_t width, height; + uint32_t format; + const void *driver_format; + int32_t offset[3]; + int32_t stride[3]; + void *driver_buffer; +}; + +struct wayland_drm_callbacks { + int (*authenticate)(void *user_data, uint32_t id); + + void (*reference_buffer)(void *user_data, uint32_t name, int fd, + struct wl_drm_buffer *buffer); + + void (*release_buffer)(void *user_data, struct wl_drm_buffer *buffer); + void* (*get_data)(void *user_data, struct wl_drm_buffer *buffer); + void (*put_data)(void *user_data, struct wl_drm_buffer *buffer); +}; + +enum { WAYLAND_DRM_PRIME = 0x01 }; + +struct wl_drm_buffer * +wayland_drm_buffer_get(struct wl_drm *drm, struct wl_resource *resource); + +struct wl_drm * +wayland_drm_init(struct wl_display *display, char *device_name, + struct wayland_drm_callbacks *callbacks, void *user_data, + uint32_t flags); + +void +wayland_drm_uninit(struct wl_drm *drm); + +int +wayland_buffer_is_drm(struct wl_drm_buffer *buffer); + +uint32_t +wayland_drm_buffer_get_format(struct wl_drm_buffer *buffer); + +void * +wayland_drm_buffer_get_buffer(struct wl_drm_buffer *buffer); + +int32_t +wayland_drm_buffer_get_stride(struct wl_drm_buffer *buffer_base, int idx); + +void * +wayland_drm_buffer_get_data(struct wl_drm_buffer *buffer_base); + +void +wayland_drm_buffer_put_data(struct wl_drm_buffer *buffer_base); + +int32_t +wayland_drm_buffer_get_width(struct wl_drm_buffer *buffer_base); + +int32_t +wayland_drm_buffer_get_height(struct wl_drm_buffer *buffer_base); + +#endif -- 1.7.9.5