| Index: components/exo/wayland/server.cc
|
| diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
|
| index b5d8383d151559b51136a8179c95145f09184f47..07a7e02fbc59228edd323ad5f5fb2847850f0bbb 100644
|
| --- a/components/exo/wayland/server.cc
|
| +++ b/components/exo/wayland/server.cc
|
| @@ -14,6 +14,7 @@
|
| #include <xdg-shell-unstable-v5-server-protocol.h>
|
|
|
| #include <algorithm>
|
| +#include <iterator>
|
| #include <string>
|
| #include <utility>
|
|
|
| @@ -44,6 +45,8 @@
|
| #include "ui/events/keycodes/dom/keycode_converter.h"
|
|
|
| #if defined(USE_OZONE)
|
| +#include <drm_fourcc.h>
|
| +#include <linux-dmabuf-unstable-v1-server-protocol.h>
|
| #include <wayland-drm-server-protocol.h>
|
| #endif
|
|
|
| @@ -473,9 +476,9 @@ void drm_create_prime_buffer(wl_client* client,
|
| }
|
|
|
| scoped_ptr<Buffer> buffer =
|
| - GetUserDataAs<Display>(resource)
|
| - ->CreatePrimeBuffer(base::ScopedFD(name), gfx::Size(width, height),
|
| - supported_format->buffer_format, stride0);
|
| + GetUserDataAs<Display>(resource)->CreateLinuxDMABufBuffer(
|
| + base::ScopedFD(name), gfx::Size(width, height),
|
| + supported_format->buffer_format, stride0);
|
| if (!buffer) {
|
| wl_resource_post_no_memory(resource);
|
| return;
|
| @@ -508,6 +511,163 @@ void bind_drm(wl_client* client, void* data, uint32_t version, uint32_t id) {
|
| for (const auto& supported_format : drm_supported_formats)
|
| wl_drm_send_format(resource, supported_format.drm_format);
|
| }
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// linux_buffer_params_interface:
|
| +
|
| +const struct dmabuf_supported_format {
|
| + uint32_t dmabuf_format;
|
| + gfx::BufferFormat buffer_format;
|
| +} dmabuf_supported_formats[] = {
|
| + {DRM_FORMAT_XBGR8888, gfx::BufferFormat::RGBX_8888},
|
| + {DRM_FORMAT_ABGR8888, gfx::BufferFormat::RGBA_8888},
|
| + {DRM_FORMAT_XRGB8888, gfx::BufferFormat::BGRX_8888},
|
| + {DRM_FORMAT_ARGB8888, gfx::BufferFormat::BGRA_8888}};
|
| +
|
| +struct LinuxBufferParams {
|
| + explicit LinuxBufferParams(Display* display)
|
| + : display(display), stride(0), offset(0) {}
|
| +
|
| + Display* const display;
|
| + base::ScopedFD fd;
|
| + uint32_t stride;
|
| + uint32_t offset;
|
| +};
|
| +
|
| +void linux_buffer_params_destroy(wl_client* client, wl_resource* resource) {
|
| + wl_resource_destroy(resource);
|
| +}
|
| +
|
| +void linux_buffer_params_add(wl_client* client,
|
| + wl_resource* resource,
|
| + int32_t fd,
|
| + uint32_t plane_idx,
|
| + uint32_t offset,
|
| + uint32_t stride,
|
| + uint32_t modifier_hi,
|
| + uint32_t modifier_lo) {
|
| + if (plane_idx) {
|
| + wl_resource_post_error(resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX,
|
| + "plane_idx too large");
|
| + return;
|
| + }
|
| +
|
| + LinuxBufferParams* linux_buffer_params =
|
| + GetUserDataAs<LinuxBufferParams>(resource);
|
| + if (linux_buffer_params->fd.is_valid()) {
|
| + wl_resource_post_error(resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_SET,
|
| + "plane already set");
|
| + return;
|
| + }
|
| +
|
| + linux_buffer_params->fd.reset(fd);
|
| + linux_buffer_params->stride = stride;
|
| + linux_buffer_params->offset = offset;
|
| +}
|
| +
|
| +void linux_buffer_params_create(wl_client* client,
|
| + wl_resource* resource,
|
| + int32_t width,
|
| + int32_t height,
|
| + uint32_t format,
|
| + uint32_t flags) {
|
| + if (width <= 0 || height <= 0) {
|
| + wl_resource_post_error(resource,
|
| + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_DIMENSIONS,
|
| + "invalid width or height");
|
| + return;
|
| + }
|
| +
|
| + const auto* supported_format = std::find_if(
|
| + std::begin(dmabuf_supported_formats), std::end(dmabuf_supported_formats),
|
| + [format](const dmabuf_supported_format& supported_format) {
|
| + return supported_format.dmabuf_format == format;
|
| + });
|
| + if (supported_format == std::end(dmabuf_supported_formats)) {
|
| + wl_resource_post_error(resource,
|
| + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_FORMAT,
|
| + "format not supported");
|
| + return;
|
| + }
|
| +
|
| + if (flags & (ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT |
|
| + ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED)) {
|
| + wl_resource_post_error(resource,
|
| + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE,
|
| + "flags not supported");
|
| + return;
|
| + }
|
| +
|
| + LinuxBufferParams* linux_buffer_params =
|
| + GetUserDataAs<LinuxBufferParams>(resource);
|
| + if (linux_buffer_params->offset) {
|
| + wl_resource_post_error(resource,
|
| + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
|
| + "offset not supported");
|
| + return;
|
| + }
|
| +
|
| + scoped_ptr<Buffer> buffer =
|
| + linux_buffer_params->display->CreateLinuxDMABufBuffer(
|
| + std::move(linux_buffer_params->fd), gfx::Size(width, height),
|
| + supported_format->buffer_format, linux_buffer_params->stride);
|
| + if (!buffer) {
|
| + zwp_linux_buffer_params_v1_send_failed(resource);
|
| + return;
|
| + }
|
| +
|
| + wl_resource* buffer_resource =
|
| + wl_resource_create(client, &wl_buffer_interface, 1, 0);
|
| +
|
| + buffer->set_release_callback(base::Bind(&HandleBufferReleaseCallback,
|
| + base::Unretained(buffer_resource)));
|
| +
|
| + zwp_linux_buffer_params_v1_send_created(resource, buffer_resource);
|
| +}
|
| +
|
| +const struct zwp_linux_buffer_params_v1_interface
|
| + linux_buffer_params_implementation = {linux_buffer_params_destroy,
|
| + linux_buffer_params_add,
|
| + linux_buffer_params_create};
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// linux_dmabuf_interface:
|
| +
|
| +void linux_dmabuf_destroy(wl_client* client, wl_resource* resource) {
|
| + wl_resource_destroy(resource);
|
| +}
|
| +
|
| +void linux_dmabuf_create_params(wl_client* client,
|
| + wl_resource* resource,
|
| + uint32_t id) {
|
| + scoped_ptr<LinuxBufferParams> linux_buffer_params =
|
| + make_scoped_ptr(new LinuxBufferParams(GetUserDataAs<Display>(resource)));
|
| +
|
| + wl_resource* linux_buffer_params_resource =
|
| + wl_resource_create(client, &zwp_linux_buffer_params_v1_interface, 1, id);
|
| +
|
| + SetImplementation(linux_buffer_params_resource,
|
| + &linux_buffer_params_implementation,
|
| + std::move(linux_buffer_params));
|
| +}
|
| +
|
| +const struct zwp_linux_dmabuf_v1_interface linux_dmabuf_implementation = {
|
| + linux_dmabuf_destroy, linux_dmabuf_create_params};
|
| +
|
| +void bind_linux_dmabuf(wl_client* client,
|
| + void* data,
|
| + uint32_t version,
|
| + uint32_t id) {
|
| + wl_resource* resource =
|
| + wl_resource_create(client, &zwp_linux_dmabuf_v1_interface, 1, id);
|
| +
|
| + wl_resource_set_implementation(resource, &linux_dmabuf_implementation, data,
|
| + nullptr);
|
| +
|
| + for (const auto& supported_format : dmabuf_supported_formats)
|
| + zwp_linux_dmabuf_v1_send_format(resource, supported_format.dmabuf_format);
|
| +}
|
| +
|
| #endif
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -1594,6 +1754,8 @@ Server::Server(Display* display)
|
| #if defined(USE_OZONE)
|
| wl_global_create(wl_display_.get(), &wl_drm_interface, drm_version, display_,
|
| bind_drm);
|
| + wl_global_create(wl_display_.get(), &zwp_linux_dmabuf_v1_interface, 1,
|
| + display_, bind_linux_dmabuf);
|
| #endif
|
| wl_global_create(wl_display_.get(), &wl_subcompositor_interface, 1, display_,
|
| bind_subcompositor);
|
|
|