From patchwork Thu Dec 12 20:27:21 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 22313 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ie0-f199.google.com (mail-ie0-f199.google.com [209.85.223.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id C2C4A23FC9 for ; Thu, 12 Dec 2013 20:28:00 +0000 (UTC) Received: by mail-ie0-f199.google.com with SMTP id lx4sf3651587iec.10 for ; Thu, 12 Dec 2013 12:28:00 -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:from:to:date:message-id:in-reply-to :references:subject:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:errors-to:sender :x-original-sender:x-original-authentication-results:mailing-list :content-type:content-transfer-encoding; bh=w+NFbKaNjluJfr4CzoWLIf5Cee9jAC4DWNI4pcvZpo8=; b=d4AgW0HbwopifpsBOGzmQNiZ7QnVvhOdShOwNhgfiGGq6vT9Y70Siu9/YBVmunP5L0 NFKtyuhYVH6eiJVrS4eJfdPSsL98L/tAiDMqI0fXdtbiFHwOiczMqcDWGxxGAbW7tFwX jzz9nKXnxDlzoa0chPLn63FVhMrfC5zq3CVRidX6RvBzyt2sl0d9gFuHyg5C5QG4xJrq 6h0FRZpNi4rBkcJGJSiA7bYF2iHBumNjBWqlOi7w/zKQ94JZXIv/zEzxg6ZK4mmW6Tba dzE6NZuh1FMubfZJMEoXQ0nAh5G/sYFNpdQ6cl9bQkKF3MnytMvROhwkmEaVoctONEMb efTg== X-Gm-Message-State: ALoCoQmfioO+WkzTbfKvFTwGdzf858s/n/8V4M/0K5X9l8brFvVPxdmDQRuXlt4fJ4QiEvGP1Mym X-Received: by 10.182.114.73 with SMTP id je9mr3791290obb.23.1386880080283; Thu, 12 Dec 2013 12:28:00 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.40.164 with SMTP id y4ls709504qek.89.gmail; Thu, 12 Dec 2013 12:28:00 -0800 (PST) X-Received: by 10.220.5.133 with SMTP id 5mr365691vcv.73.1386880080110; Thu, 12 Dec 2013 12:28:00 -0800 (PST) Received: from mail-ve0-f179.google.com (mail-ve0-f179.google.com [209.85.128.179]) by mx.google.com with ESMTPS id hs8si8053187veb.98.2013.12.12.12.28.00 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 12 Dec 2013 12:28:00 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.179 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.179; Received: by mail-ve0-f179.google.com with SMTP id jw12so735976veb.10 for ; Thu, 12 Dec 2013 12:28:00 -0800 (PST) X-Received: by 10.58.216.133 with SMTP id oq5mr30037vec.80.1386880079990; Thu, 12 Dec 2013 12:27:59 -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 u4csp383926vcz; Thu, 12 Dec 2013 12:27:59 -0800 (PST) X-Received: by 10.180.149.175 with SMTP id ub15mr46329wib.44.1386880078803; Thu, 12 Dec 2013 12:27:58 -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 z5si10847389wjz.6.2013.12.12.12.27.58 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 12 Dec 2013 12:27:58 -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 1VrCoH-0005oE-9s; Thu, 12 Dec 2013 20:24:37 +0000 Received: from mail-wg0-f51.google.com ([74.125.82.51]) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1VrCo3-0005nW-JR for linaro-mm-sig@lists.linaro.org; Thu, 12 Dec 2013 20:24:23 +0000 Received: by mail-wg0-f51.google.com with SMTP id b13so972446wgh.18 for ; Thu, 12 Dec 2013 12:27:34 -0800 (PST) X-Received: by 10.195.13.234 with SMTP id fb10mr8336877wjd.50.1386880054511; Thu, 12 Dec 2013 12:27:34 -0800 (PST) Received: from lmenx321.lme.st.com (lya72-2-88-175-155-153.fbx.proxad.net. [88.175.155.153]) by mx.google.com with ESMTPSA id xm7sm799152wib.0.2013.12.12.12.27.33 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 12 Dec 2013 12:27:34 -0800 (PST) From: benjamin.gaignard@linaro.org To: wayland-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org Date: Thu, 12 Dec 2013 21:27:21 +0100 Message-Id: <1386880041-3781-3-git-send-email-benjamin.gaignard@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1386880041-3781-1-git-send-email-benjamin.gaignard@linaro.org> References: <1386880041-3781-1-git-send-email-benjamin.gaignard@linaro.org> Subject: [Linaro-mm-sig] [PATCH v3] compositor-drm: allow to be a wl_dmabuf server 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: , MIME-Version: 1.0 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.179 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 From: Benjamin Gaignard Make drm compositor aware of the wl_dmabuf protocol if pixman is used. Add functions to have a wl_dmabuf server inside drm compositor. Change pixman to let it know how use a wl_dmabuf buffer. Signed-off-by: Benjamin Gaignard --- src/compositor-drm.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++-- src/compositor.c | 4 +- src/compositor.h | 2 + src/pixman-renderer.c | 86 ++++++++++++++++++------- 4 files changed, 230 insertions(+), 30 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 4f015d1..dd957cd 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -49,6 +49,8 @@ #include "udev-seat.h" #include "launcher-util.h" #include "vaapi-recorder.h" +#include "wayland-dmabuf.h" +#include "wayland-dmabuf-server-protocol.h" #ifndef DRM_CAP_TIMESTAMP_MONOTONIC #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 @@ -826,7 +828,8 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base, if (es->alpha != 1.0f) return NULL; - if (wl_shm_buffer_get(es->buffer_ref.buffer->resource)) + if (wl_shm_buffer_get(es->buffer_ref.buffer->resource) + || wl_dmabuf_buffer_get(es->buffer_ref.buffer->resource)) return NULL; if (!drm_surface_transform_supported(es)) @@ -951,7 +954,8 @@ drm_output_prepare_cursor_surface(struct weston_output *output_base, if (c->cursors_are_broken) return NULL; if (es->buffer_ref.buffer == NULL || - !wl_shm_buffer_get(es->buffer_ref.buffer->resource) || + (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) && + !wl_dmabuf_buffer_get(es->buffer_ref.buffer->resource))|| es->geometry.width > 64 || es->geometry.height > 64) return NULL; @@ -985,12 +989,25 @@ drm_output_set_cursor(struct drm_output *output) output->current_cursor ^= 1; bo = output->cursor_bo[output->current_cursor]; memset(buf, 0, sizeof buf); - stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer->shm_buffer); - s = wl_shm_buffer_get_data(es->buffer_ref.buffer->shm_buffer); + if (wl_shm_buffer_get(es->buffer_ref.buffer->resource)) { + stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer->shm_buffer); + s = wl_shm_buffer_get_data(es->buffer_ref.buffer->shm_buffer); + } + if (wl_dmabuf_buffer_get(es->buffer_ref.buffer->resource)) { + stride = wl_dmabuf_buffer_get_stride(es->buffer_ref.buffer->dmabuf_buffer, 0); + s = wl_dmabuf_buffer_get_data(es->buffer_ref.buffer->dmabuf_buffer); + if (!s) { + weston_log("failed to get data from dmabuf buffer"); + return; + } + } for (i = 0; i < es->geometry.height; i++) memcpy(buf + i * 64, s + i * stride, es->geometry.width * 4); + if (wl_dmabuf_buffer_get(es->buffer_ref.buffer->resource)) + wl_dmabuf_buffer_put_data(es->buffer_ref.buffer->dmabuf_buffer); + if (gbm_bo_write(bo, buf, sizeof buf) < 0) weston_log("failed update cursor: %m\n"); @@ -1044,7 +1061,8 @@ drm_assign_planes(struct weston_output *output) * non-shm, or small enough to be a cursor */ if ((es->buffer_ref.buffer && - !wl_shm_buffer_get(es->buffer_ref.buffer->resource)) || + (!wl_shm_buffer_get(es->buffer_ref.buffer->resource)) + && !wl_dmabuf_buffer_get(es->buffer_ref.buffer->resource)) || (es->geometry.width <= 64 && es->geometry.height <= 64)) es->keep_buffer = 1; else @@ -1268,6 +1286,142 @@ init_drm(struct drm_compositor *ec, struct udev_device *device) return 0; } +struct dmabuf_driver_buffer { + uint32_t size; + uint32_t handle; + char *data; +}; + +static void +dmabuf_reference_buffer(void *user_data, int prime_fd, struct wl_dmabuf_buffer *buffer) +{ + struct drm_compositor *ec = user_data; + uint32_t handles[4], pitches[4], offsets[4]; + int ret; + uint32_t fd; + struct dmabuf_driver_buffer *driver_buffer; + + if (prime_fd == -1) + return; + + drmPrimeFDToHandle(ec->drm.fd, prime_fd, &handles[0]); + pitches[0] = buffer->stride[0]; + pitches[1] = buffer->stride[1]; + pitches[2] = buffer->stride[2]; + offsets[0] = buffer->offset[0]; + offsets[1] = buffer->offset[1]; + offsets[2] = buffer->offset[2]; + + ret = drmModeAddFB2 (ec->drm.fd, buffer->width, buffer->height, + buffer->format, handles, pitches, offsets, &fd, 0); + if (ret) { + weston_log("addfb2 failed: %m\n"); + return; + } + + driver_buffer = malloc(sizeof *driver_buffer); + if (driver_buffer == NULL) + return; + + driver_buffer->size = buffer->width * buffer->height * 4; + driver_buffer->handle = handles[0]; + driver_buffer->data = NULL; + buffer->driver_buffer = driver_buffer; +} + +static void +dmabuf_unreference_buffer(void *user_data, struct wl_dmabuf_buffer *buffer) +{ + struct dmabuf_driver_buffer *driver_buffer = buffer->driver_buffer; + + if(driver_buffer->data) + munmap(driver_buffer->data, driver_buffer->size); + + free(buffer->driver_buffer); +} + +static void* +dmabuf_get_data(void *user_data, struct wl_dmabuf_buffer *buffer) +{ + struct dmabuf_driver_buffer *driver_buffer = buffer->driver_buffer; + struct drm_compositor *ec = user_data; + + if (!driver_buffer->data) { + int fd; + drmPrimeHandleToFD(ec->drm.fd, driver_buffer->handle, 0, &fd); + driver_buffer->data = mmap (0, driver_buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + close(fd); + } + return driver_buffer->data; +} + + +static void +dmabuf_put_data(void *user_data, struct wl_dmabuf_buffer *buffer) +{ + struct dmabuf_driver_buffer *driver_buffer = buffer->driver_buffer; + + if (!driver_buffer->data) { + munmap (driver_buffer->data, driver_buffer->size); + driver_buffer->data = NULL; + } +} + +static void dmabuf_send_supported_formats(void *user_data, struct wl_resource *resource) +{ + struct drm_compositor *ec = user_data; + drmModePlaneRes *plane_resources; + unsigned int i, j; + + weston_log("send supported formats\n"); + + plane_resources = drmModeGetPlaneResources(ec->drm.fd); + if (!plane_resources) + return; + + for (i = 0; i < plane_resources->count_planes; i++) { + drmModePlane *ovr = drmModeGetPlane(ec->drm.fd, plane_resources->planes[i]); + + for (j = 0 ; j < ovr->count_formats; j++) { + weston_log("server support format %4.4s\n", (char *)&ovr->formats[j]); + wl_dmabuf_send_format(resource, ovr->formats[j]); + } + drmModeFreePlane(ovr); + } + + drmModeFreePlaneResources(plane_resources); +} + +static void dmabuf_send_device_name(void *user_data, struct wl_resource *resource) +{ + struct drm_compositor *ec = user_data; + weston_log("send device name %s\n", ec->drm.filename); + + wl_dmabuf_send_device(resource, ec->drm.filename); +} + +static void dmabuf_send_server_info(void *user_data, struct wl_resource *resource) +{ + dmabuf_send_supported_formats(user_data, resource); + dmabuf_send_device_name(user_data, resource); +} + +static struct wl_dmabuf_callbacks wl_dmabuf_callbacks = { + dmabuf_reference_buffer, + dmabuf_unreference_buffer, + dmabuf_get_data, + dmabuf_put_data, + dmabuf_send_server_info +}; + +static int +init_dmabuf_protocol(struct drm_compositor *ec) +{ + wl_dmabuf_init(ec->base.wl_display, + &wl_dmabuf_callbacks, ec, 0); + return 0; +} + static int init_egl(struct drm_compositor *ec) { @@ -1955,6 +2109,10 @@ create_output_for_connector(struct drm_compositor *ec, weston_log("Failed to init output pixman state\n"); goto err_output; } + if (init_dmabuf_protocol(ec) < 0) { + weston_log("Failed to init wl_dmabuf server\n"); + goto err_output; + } } else if (drm_output_init_egl(output, ec) < 0) { weston_log("Failed to init output gl state\n"); goto err_output; diff --git a/src/compositor.c b/src/compositor.c index 4cb44e5..037b695 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1257,7 +1257,9 @@ surface_accumulate_damage(struct weston_surface *surface, pixman_region32_t *opaque) { if (surface->buffer_ref.buffer && - wl_shm_buffer_get(surface->buffer_ref.buffer->resource)) + (wl_shm_buffer_get(surface->buffer_ref.buffer->resource) + || wl_dmabuf_buffer_get(surface->buffer_ref.buffer->resource)) + ) surface->compositor->renderer->flush_damage(surface); if (surface->transform.enabled) { diff --git a/src/compositor.h b/src/compositor.h index 0dcb604..537a9b7 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -33,6 +33,7 @@ extern "C" { #define WL_HIDE_DEPRECATED #include +#include #include "version.h" #include "matrix.h" @@ -626,6 +627,7 @@ struct weston_buffer { union { struct wl_shm_buffer *shm_buffer; + struct wl_dmabuf_buffer *dmabuf_buffer; void *legacy_buffer; }; int32_t width, height; diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c index 987c539..7802f2d 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -533,6 +533,8 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) { struct pixman_surface_state *ps = get_surface_state(es); struct wl_shm_buffer *shm_buffer; + struct wl_dmabuf_buffer *dmabuf_buffer; + pixman_format_code_t pixman_format; weston_buffer_reference(&ps->buffer_ref, buffer); @@ -544,40 +546,76 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) if (!buffer) return; - + shm_buffer = wl_shm_buffer_get(buffer->resource); + dmabuf_buffer = wl_dmabuf_buffer_get(buffer->resource); - if (! shm_buffer) { - weston_log("Pixman renderer supports only SHM buffers\n"); + if (!shm_buffer && !dmabuf_buffer) { + weston_log("Pixman renderer supports only SHM and DMABUF buffers\n"); weston_buffer_reference(&ps->buffer_ref, NULL); return; } - switch (wl_shm_buffer_get_format(shm_buffer)) { - case WL_SHM_FORMAT_XRGB8888: - pixman_format = PIXMAN_x8r8g8b8; - break; - case WL_SHM_FORMAT_ARGB8888: - pixman_format = PIXMAN_a8r8g8b8; - break; - case WL_SHM_FORMAT_RGB565: - pixman_format = PIXMAN_r5g6b5; + if (shm_buffer) { + switch (wl_shm_buffer_get_format(shm_buffer)) { + case WL_SHM_FORMAT_XRGB8888: + pixman_format = PIXMAN_x8r8g8b8; + break; + case WL_SHM_FORMAT_ARGB8888: + pixman_format = PIXMAN_a8r8g8b8; + break; + case WL_SHM_FORMAT_RGB565: + pixman_format = PIXMAN_r5g6b5; + break; + default: + weston_log("Unsupported SHM buffer format\n"); + weston_buffer_reference(&ps->buffer_ref, NULL); + return; break; - default: - weston_log("Unsupported SHM buffer format\n"); - weston_buffer_reference(&ps->buffer_ref, NULL); - return; - break; + } + + buffer->shm_buffer = shm_buffer; + buffer->width = wl_shm_buffer_get_width(shm_buffer); + buffer->height = wl_shm_buffer_get_height(shm_buffer); + + ps->image = pixman_image_create_bits(pixman_format, + buffer->width, buffer->height, + wl_shm_buffer_get_data(shm_buffer), + wl_shm_buffer_get_stride(shm_buffer)); } - buffer->shm_buffer = shm_buffer; - buffer->width = wl_shm_buffer_get_width(shm_buffer); - buffer->height = wl_shm_buffer_get_height(shm_buffer); + if (dmabuf_buffer) { + void *data; + switch (wl_dmabuf_buffer_get_format(dmabuf_buffer)) { + case WL_DMABUF_FORMAT_XRGB8888: + pixman_format = PIXMAN_x8r8g8b8; + break; + case WL_DMABUF_FORMAT_ARGB8888: + pixman_format = PIXMAN_a8r8g8b8; + break; + case WL_DMABUF_FORMAT_RGB565: + pixman_format = PIXMAN_r5g6b5; + break; + default: + weston_log("Unsupported DMABUF buffer format\n"); + weston_buffer_reference(&ps->buffer_ref, NULL); + return; + break; + } - ps->image = pixman_image_create_bits(pixman_format, - buffer->width, buffer->height, - wl_shm_buffer_get_data(shm_buffer), - wl_shm_buffer_get_stride(shm_buffer)); + buffer->dmabuf_buffer = dmabuf_buffer; + buffer->width = wl_dmabuf_buffer_get_width(dmabuf_buffer); + buffer->height = wl_dmabuf_buffer_get_height(dmabuf_buffer); + + data = wl_dmabuf_buffer_get_data(dmabuf_buffer); + if (data) { + ps->image = pixman_image_create_bits(pixman_format, + buffer->width, buffer->height, data, + wl_dmabuf_buffer_get_stride(dmabuf_buffer, 0)); + wl_dmabuf_buffer_put_data(dmabuf_buffer); + } else + weston_log("failed to get data from dmabuf buffer"); + } } static int