-
Notifications
You must be signed in to change notification settings - Fork 182
Support dmabuf in Cuttlefish wayland server #1602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,12 +18,43 @@ | |
| #pragma once | ||
|
|
||
| #include <stdint.h> | ||
| #include <map> | ||
|
|
||
| #include <android-base/unique_fd.h> | ||
|
|
||
| #include <wayland-server-core.h> | ||
|
|
||
| namespace wayland { | ||
|
|
||
| struct DmabufPlane { | ||
| android::base::unique_fd fd; | ||
| uint32_t plane = 0; | ||
| uint32_t offset = 0; | ||
| uint32_t stride = 0; | ||
| uint32_t modifier_hi = 0; | ||
| uint32_t modifier_lo = 0; | ||
| }; | ||
|
|
||
| struct DmabufParams { | ||
| DmabufParams() = default; | ||
|
|
||
| DmabufParams(const DmabufParams& rhs) = delete; | ||
| DmabufParams& operator=(const DmabufParams& rhs) = delete; | ||
|
|
||
| std::map<int32_t, DmabufPlane> planes; | ||
| }; | ||
|
|
||
| struct Dmabuf { | ||
| uint32_t width = 0; | ||
| uint32_t height = 0; | ||
| uint32_t format = 0; | ||
| uint32_t flags = 0; | ||
| DmabufParams* params; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forwarded comment: this should not be a pointer as the params accumulator "DmabufParams" object is destroyed right after the dmabuf is created. |
||
| }; | ||
|
|
||
| // Binds the dmabuf interface to the given wayland server. | ||
| void BindDmabufInterface(wl_display* display); | ||
|
|
||
| bool IsDmabufResource(struct wl_resource* resource); | ||
|
|
||
| } // namespace wayland | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,9 +18,13 @@ | |
|
|
||
| #include <android-base/logging.h> | ||
| #include <drm/drm_fourcc.h> | ||
| #include <sys/mman.h> | ||
| #include <wayland-server-protocol.h> | ||
|
|
||
| #include "cuttlefish/host/libs/wayland/wayland_surfaces.h" | ||
| #include "cuttlefish/host/libs/wayland/wayland_dmabuf.h" | ||
| #include "cuttlefish/host/libs/wayland/wayland_surfaces.h" | ||
| #include "cuttlefish/host/libs/wayland/wayland_utils.h" | ||
|
|
||
| namespace wayland { | ||
| namespace { | ||
|
|
@@ -70,31 +74,67 @@ void Surface::Commit() { | |
| const uint32_t display_number = *state_.virtio_gpu_metadata_.scanout_id; | ||
|
|
||
| struct wl_shm_buffer* shm_buffer = wl_shm_buffer_get(state_.current_buffer); | ||
| CHECK(shm_buffer != nullptr); | ||
|
|
||
| wl_shm_buffer_begin_access(shm_buffer); | ||
|
|
||
| const int32_t buffer_w = wl_shm_buffer_get_width(shm_buffer); | ||
| CHECK(buffer_w == state_.region.w); | ||
| const int32_t buffer_h = wl_shm_buffer_get_height(shm_buffer); | ||
| CHECK(buffer_h == state_.region.h); | ||
| const int32_t buffer_stride_bytes = wl_shm_buffer_get_stride(shm_buffer); | ||
| const std::uint32_t buffer_drm_format = | ||
| GetDrmFormat(wl_shm_buffer_get_format(shm_buffer)); | ||
| uint32_t buffer_w = 0; | ||
| uint32_t buffer_h = 0; | ||
| uint32_t buffer_drm_format = 0; | ||
| uint32_t buffer_stride_bytes = 0; | ||
| uint8_t* buffer_pixels = nullptr; | ||
| uint32_t buffer_size = 0; | ||
|
|
||
| if (shm_buffer != nullptr) { | ||
| wl_shm_buffer_begin_access(shm_buffer); | ||
| buffer_w = wl_shm_buffer_get_width(shm_buffer); | ||
| CHECK(buffer_w == state_.region.w); | ||
| buffer_h = wl_shm_buffer_get_height(shm_buffer); | ||
| CHECK(buffer_h == state_.region.h); | ||
| buffer_drm_format = GetDrmFormat(wl_shm_buffer_get_format(shm_buffer)); | ||
| buffer_stride_bytes = wl_shm_buffer_get_stride(shm_buffer); | ||
| buffer_pixels = | ||
| reinterpret_cast<uint8_t*>(wl_shm_buffer_get_data(shm_buffer)); | ||
| } else { | ||
| CHECK(IsDmabufResource(state_.current_buffer)); | ||
| Dmabuf* dmabuf = GetUserData<Dmabuf>(state_.current_buffer); | ||
| buffer_w = dmabuf->width; | ||
| buffer_h = dmabuf->height; | ||
|
|
||
| if (dmabuf->params != nullptr) { | ||
| const DmabufParams& dmabuf_params = *dmabuf->params; | ||
|
|
||
| CHECK(dmabuf_params.planes.size() == 1); | ||
| const DmabufPlane& dmabuf_plane = dmabuf_params.planes.begin()->second; | ||
|
|
||
| if (dmabuf_plane.fd.ok()) { | ||
| buffer_drm_format = dmabuf->format; | ||
| buffer_stride_bytes = dmabuf_plane.stride; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here |
||
| buffer_size = buffer_h * buffer_stride_bytes; | ||
| auto mapped = mmap(nullptr, buffer_size, PROT_READ | PROT_WRITE, | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forwarded comment: drop the |
||
| MAP_SHARED, dmabuf_plane.fd, 0); | ||
| if (mapped != MAP_FAILED) { | ||
| buffer_pixels = reinterpret_cast<uint8_t*>(mapped); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (!state_.has_notified_surface_create) { | ||
| surfaces_.HandleSurfaceCreated(display_number, buffer_w, buffer_h); | ||
| state_.has_notified_surface_create = true; | ||
| } | ||
|
|
||
| uint8_t* buffer_pixels = | ||
| reinterpret_cast<uint8_t*>(wl_shm_buffer_get_data(shm_buffer)); | ||
|
|
||
| surfaces_.HandleSurfaceFrame(display_number, buffer_w, buffer_h, | ||
| buffer_drm_format, buffer_stride_bytes, | ||
| buffer_pixels); | ||
| if (buffer_pixels != nullptr) { | ||
| surfaces_.HandleSurfaceFrame(display_number, buffer_w, buffer_h, | ||
| buffer_drm_format, buffer_stride_bytes, | ||
| buffer_pixels); | ||
| } | ||
|
|
||
| wl_shm_buffer_end_access(shm_buffer); | ||
| if (shm_buffer != nullptr) { | ||
| wl_shm_buffer_end_access(shm_buffer); | ||
| } else { | ||
| if (buffer_pixels != nullptr) { | ||
| munmap(buffer_pixels, buffer_size); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| wl_buffer_send_release(state_.current_buffer); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forwarded comment: 3rd argument should be
buffer_implementation