Chromium Code Reviews| Index: components/exo/wayland/server.cc |
| diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc |
| index 60a5028c07352c983a50848a412ad5e690f8745a..056bba8bb7aa9b93e3b0a79c677353383ce5f329 100644 |
| --- a/components/exo/wayland/server.cc |
| +++ b/components/exo/wayland/server.cc |
| @@ -56,6 +56,8 @@ |
| #include "ui/display/display_observer.h" |
| #include "ui/display/screen.h" |
| #include "ui/events/keycodes/dom/keycode_converter.h" |
| +#include "ui/gfx/buffer_format_util.h" |
| +#include "ui/gfx/buffer_types.h" |
| #include "ui/views/widget/widget.h" |
| #include "ui/views/widget/widget_observer.h" |
| #include "ui/wm/public/activation_change_observer.h" |
| @@ -450,7 +452,8 @@ const struct drm_supported_format { |
| {WL_DRM_FORMAT_XBGR8888, gfx::BufferFormat::RGBX_8888}, |
| {WL_DRM_FORMAT_ABGR8888, gfx::BufferFormat::RGBA_8888}, |
| {WL_DRM_FORMAT_XRGB8888, gfx::BufferFormat::BGRX_8888}, |
| - {WL_DRM_FORMAT_ARGB8888, gfx::BufferFormat::BGRA_8888}}; |
| + {WL_DRM_FORMAT_ARGB8888, gfx::BufferFormat::BGRA_8888}, |
| + {WL_DRM_FORMAT_YVU420, gfx::BufferFormat::YVU_420}}; |
| void drm_authenticate(wl_client* client, wl_resource* resource, uint32_t id) { |
| wl_drm_send_authenticated(resource); |
| @@ -511,10 +514,18 @@ void drm_create_prime_buffer(wl_client* client, |
| return; |
| } |
| + std::vector<int> strides{stride0, stride1, stride2}; |
| + std::vector<int> offsets{offset0, offset1, offset2}; |
| + |
| + int planes = |
| + gfx::NumberOfPlanesForBufferFormat(supported_format->buffer_format); |
| + strides.resize(planes); |
| + offsets.resize(planes); |
| + std::vector<base::ScopedFD> fds{name}; |
| std::unique_ptr<Buffer> buffer = |
| GetUserDataAs<Display>(resource)->CreateLinuxDMABufBuffer( |
| - base::ScopedFD(name), gfx::Size(width, height), |
| - supported_format->buffer_format, stride0); |
| + gfx::Size(width, height), supported_format->buffer_format, strides, |
| + offsets, std::move(fds)); |
| if (!buffer) { |
| wl_resource_post_no_memory(resource); |
| return; |
| @@ -559,16 +570,19 @@ const struct dmabuf_supported_format { |
| {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}}; |
| + {DRM_FORMAT_ARGB8888, gfx::BufferFormat::BGRA_8888}, |
| + {DRM_FORMAT_YVU420, gfx::BufferFormat::YVU_420}}; |
| struct LinuxBufferParams { |
| - explicit LinuxBufferParams(Display* display) |
| - : display(display), stride(0), offset(0) {} |
| + explicit LinuxBufferParams(Display* display) : display(display) {} |
| Display* const display; |
| - base::ScopedFD fd; |
| - uint32_t stride; |
| - uint32_t offset; |
| + struct Plane { |
|
reveman
2016/06/10 01:57:32
nit: class/struct before ctor please
Daniele Castagna
2016/06/10 02:08:24
Done.
|
| + base::ScopedFD fd; |
| + uint32_t stride; |
| + uint32_t offset; |
| + }; |
| + std::map<uint32_t, Plane> planes; |
| }; |
| void linux_buffer_params_destroy(wl_client* client, wl_resource* resource) { |
| @@ -583,23 +597,17 @@ void linux_buffer_params_add(wl_client* client, |
| 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()) { |
| + |
| + LinuxBufferParams::Plane plane{base::ScopedFD(fd), stride, offset}; |
| + const auto& emplaced = |
| + linux_buffer_params->planes.emplace(plane_idx, std::move(plane)); |
| + if (!emplaced.second) { // The plane was already there. |
| 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, |
| @@ -637,17 +645,36 @@ void linux_buffer_params_create(wl_client* client, |
| 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"); |
| + |
| + std::vector<base::ScopedFD> fds; |
| + std::vector<int> strides; |
| + std::vector<int> offsets; |
| + |
| + uint32_t plane_idx = 0; |
| + for (auto& plane_entry : linux_buffer_params->planes) { |
| + if (plane_entry.first != plane_idx) { |
| + wl_resource_post_error(resource, |
| + ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INCOMPLETE, |
| + "missing a plane"); |
|
reveman
2016/06/10 01:57:32
should we continue looping after this?
Daniele Castagna
2016/06/10 02:08:24
No, return added.
|
| + } |
| + LinuxBufferParams::Plane& plane = plane_entry.second; |
| + fds.push_back(std::move(plane.fd)); |
|
reveman
2016/06/10 01:57:32
what if plane.fd is not valid?
Daniele Castagna
2016/06/10 02:08:24
We shouldn't add it then. Done.
|
| + strides.push_back(plane.stride); |
| + offsets.push_back(plane.offset); |
| + ++plane_idx; |
| + } |
| + |
| + if (!plane_idx || |
| + plane_idx > 3) { // We don't support any format with more than 3 planes. |
|
reveman
2016/06/10 01:57:32
We know the format here. Could we return an error
Daniele Castagna
2016/06/10 02:08:24
Yes, added the check before looping on the planes.
|
| + wl_resource_post_error(resource, ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_PLANE_IDX, |
| + "plane idx out of bounds"); |
| return; |
| } |
| std::unique_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); |
| + gfx::Size(width, height), supported_format->buffer_format, strides, |
| + offsets, std::move(fds)); |
| if (!buffer) { |
| zwp_linux_buffer_params_v1_send_failed(resource); |
| return; |