wayland: add wl_drm protocol
This commit is contained in:
parent
7c014af495
commit
749a032507
7 changed files with 320 additions and 1 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -299,6 +299,7 @@ dependencies = [
|
||||||
"smithay",
|
"smithay",
|
||||||
"smithay-egui",
|
"smithay-egui",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"wayland-scanner",
|
||||||
"xcursor",
|
"xcursor",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ git = "https://github.com/Smithay/smithay-egui.git"
|
||||||
rev = "5cc416ce"
|
rev = "5cc416ce"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
wayland-scanner = "0.29"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
debug = ["egui", "smithay-egui", "serde", "serde_json"]
|
debug = ["egui", "smithay-egui", "serde", "serde_json"]
|
||||||
19
build.rs
19
build.rs
|
|
@ -1,6 +1,12 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
extern crate wayland_scanner;
|
||||||
|
|
||||||
use std::process::Command;
|
use wayland_scanner::{Side, generate_code};
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
process::Command,
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
if let Some(output) = Command::new("git")
|
if let Some(output) = Command::new("git")
|
||||||
|
|
@ -11,4 +17,15 @@ fn main() {
|
||||||
let git_hash = String::from_utf8(output.stdout).unwrap();
|
let git_hash = String::from_utf8(output.stdout).unwrap();
|
||||||
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
|
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let dest = PathBuf::from(&env::var("OUT_DIR").unwrap());
|
||||||
|
// Location of the xml file, relative to the `Cargo.toml`
|
||||||
|
let drm_protocol_file = "resources/wayland-drm.xml";
|
||||||
|
// Target directory for the generate files
|
||||||
|
generate_code(
|
||||||
|
drm_protocol_file,
|
||||||
|
&dest.join("wl_drm.rs"),
|
||||||
|
Side::Server,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
189
resources/wayland-drm.xml
Normal file
189
resources/wayland-drm.xml
Normal file
|
|
@ -0,0 +1,189 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="drm">
|
||||||
|
|
||||||
|
<copyright>
|
||||||
|
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.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<!-- drm support. This object is created by the server and published
|
||||||
|
using the display's global event. -->
|
||||||
|
<interface name="wl_drm" version="2">
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="authenticate_fail" value="0"/>
|
||||||
|
<entry name="invalid_format" value="1"/>
|
||||||
|
<entry name="invalid_name" value="2"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<enum name="format">
|
||||||
|
<!-- The drm format codes match the #defines in drm_fourcc.h.
|
||||||
|
The formats actually supported by the compositor will be
|
||||||
|
reported by the format event. New codes must not be added,
|
||||||
|
unless directly taken from drm_fourcc.h. -->
|
||||||
|
<entry name="c8" value="0x20203843"/>
|
||||||
|
<entry name="rgb332" value="0x38424752"/>
|
||||||
|
<entry name="bgr233" value="0x38524742"/>
|
||||||
|
<entry name="xrgb4444" value="0x32315258"/>
|
||||||
|
<entry name="xbgr4444" value="0x32314258"/>
|
||||||
|
<entry name="rgbx4444" value="0x32315852"/>
|
||||||
|
<entry name="bgrx4444" value="0x32315842"/>
|
||||||
|
<entry name="argb4444" value="0x32315241"/>
|
||||||
|
<entry name="abgr4444" value="0x32314241"/>
|
||||||
|
<entry name="rgba4444" value="0x32314152"/>
|
||||||
|
<entry name="bgra4444" value="0x32314142"/>
|
||||||
|
<entry name="xrgb1555" value="0x35315258"/>
|
||||||
|
<entry name="xbgr1555" value="0x35314258"/>
|
||||||
|
<entry name="rgbx5551" value="0x35315852"/>
|
||||||
|
<entry name="bgrx5551" value="0x35315842"/>
|
||||||
|
<entry name="argb1555" value="0x35315241"/>
|
||||||
|
<entry name="abgr1555" value="0x35314241"/>
|
||||||
|
<entry name="rgba5551" value="0x35314152"/>
|
||||||
|
<entry name="bgra5551" value="0x35314142"/>
|
||||||
|
<entry name="rgb565" value="0x36314752"/>
|
||||||
|
<entry name="bgr565" value="0x36314742"/>
|
||||||
|
<entry name="rgb888" value="0x34324752"/>
|
||||||
|
<entry name="bgr888" value="0x34324742"/>
|
||||||
|
<entry name="xrgb8888" value="0x34325258"/>
|
||||||
|
<entry name="xbgr8888" value="0x34324258"/>
|
||||||
|
<entry name="rgbx8888" value="0x34325852"/>
|
||||||
|
<entry name="bgrx8888" value="0x34325842"/>
|
||||||
|
<entry name="argb8888" value="0x34325241"/>
|
||||||
|
<entry name="abgr8888" value="0x34324241"/>
|
||||||
|
<entry name="rgba8888" value="0x34324152"/>
|
||||||
|
<entry name="bgra8888" value="0x34324142"/>
|
||||||
|
<entry name="xrgb2101010" value="0x30335258"/>
|
||||||
|
<entry name="xbgr2101010" value="0x30334258"/>
|
||||||
|
<entry name="rgbx1010102" value="0x30335852"/>
|
||||||
|
<entry name="bgrx1010102" value="0x30335842"/>
|
||||||
|
<entry name="argb2101010" value="0x30335241"/>
|
||||||
|
<entry name="abgr2101010" value="0x30334241"/>
|
||||||
|
<entry name="rgba1010102" value="0x30334152"/>
|
||||||
|
<entry name="bgra1010102" value="0x30334142"/>
|
||||||
|
<entry name="yuyv" value="0x56595559"/>
|
||||||
|
<entry name="yvyu" value="0x55595659"/>
|
||||||
|
<entry name="uyvy" value="0x59565955"/>
|
||||||
|
<entry name="vyuy" value="0x59555956"/>
|
||||||
|
<entry name="ayuv" value="0x56555941"/>
|
||||||
|
<entry name="xyuv8888" value="0x56555958"/>
|
||||||
|
<entry name="nv12" value="0x3231564e"/>
|
||||||
|
<entry name="nv21" value="0x3132564e"/>
|
||||||
|
<entry name="nv16" value="0x3631564e"/>
|
||||||
|
<entry name="nv61" value="0x3136564e"/>
|
||||||
|
<entry name="yuv410" value="0x39565559"/>
|
||||||
|
<entry name="yvu410" value="0x39555659"/>
|
||||||
|
<entry name="yuv411" value="0x31315559"/>
|
||||||
|
<entry name="yvu411" value="0x31315659"/>
|
||||||
|
<entry name="yuv420" value="0x32315559"/>
|
||||||
|
<entry name="yvu420" value="0x32315659"/>
|
||||||
|
<entry name="yuv422" value="0x36315559"/>
|
||||||
|
<entry name="yvu422" value="0x36315659"/>
|
||||||
|
<entry name="yuv444" value="0x34325559"/>
|
||||||
|
<entry name="yvu444" value="0x34325659"/>
|
||||||
|
<entry name="abgr16f" value="0x48344241"/>
|
||||||
|
<entry name="xbgr16f" value="0x48344258"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<!-- Call this request with the magic received from drmGetMagic().
|
||||||
|
It will be passed on to the drmAuthMagic() or
|
||||||
|
DRIAuthConnection() call. This authentication must be
|
||||||
|
completed before create_buffer could be used. -->
|
||||||
|
<request name="authenticate">
|
||||||
|
<arg name="id" type="uint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Create a wayland buffer for the named DRM buffer. The DRM
|
||||||
|
surface must have a name using the flink ioctl -->
|
||||||
|
<request name="create_buffer">
|
||||||
|
<arg name="id" type="new_id" interface="wl_buffer"/>
|
||||||
|
<arg name="name" type="uint"/>
|
||||||
|
<arg name="width" type="int"/>
|
||||||
|
<arg name="height" type="int"/>
|
||||||
|
<arg name="stride" type="uint"/>
|
||||||
|
<arg name="format" type="uint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Create a wayland buffer for the named DRM buffer. The DRM
|
||||||
|
surface must have a name using the flink ioctl -->
|
||||||
|
<request name="create_planar_buffer">
|
||||||
|
<arg name="id" type="new_id" interface="wl_buffer"/>
|
||||||
|
<arg name="name" type="uint"/>
|
||||||
|
<arg name="width" type="int"/>
|
||||||
|
<arg name="height" type="int"/>
|
||||||
|
<arg name="format" type="uint"/>
|
||||||
|
<arg name="offset0" type="int"/>
|
||||||
|
<arg name="stride0" type="int"/>
|
||||||
|
<arg name="offset1" type="int"/>
|
||||||
|
<arg name="stride1" type="int"/>
|
||||||
|
<arg name="offset2" type="int"/>
|
||||||
|
<arg name="stride2" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Notification of the path of the drm device which is used by
|
||||||
|
the server. The client should use this device for creating
|
||||||
|
local buffers. Only buffers created from this device should
|
||||||
|
be be passed to the server using this drm object's
|
||||||
|
create_buffer request. -->
|
||||||
|
<event name="device">
|
||||||
|
<arg name="name" type="string"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="format">
|
||||||
|
<arg name="format" type="uint"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<!-- Raised if the authenticate request succeeded -->
|
||||||
|
<event name="authenticated"/>
|
||||||
|
|
||||||
|
<enum name="capability" since="2">
|
||||||
|
<description summary="wl_drm capability bitmask">
|
||||||
|
Bitmask of capabilities.
|
||||||
|
</description>
|
||||||
|
<entry name="prime" value="1" summary="wl_drm prime available"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<event name="capabilities">
|
||||||
|
<arg name="value" type="uint"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<!-- Version 2 additions -->
|
||||||
|
|
||||||
|
<!-- Create a wayland buffer for the prime fd. Use for regular and planar
|
||||||
|
buffers. Pass 0 for offset and stride for unused planes. -->
|
||||||
|
<request name="create_prime_buffer" since="2">
|
||||||
|
<arg name="id" type="new_id" interface="wl_buffer"/>
|
||||||
|
<arg name="name" type="fd"/>
|
||||||
|
<arg name="width" type="int"/>
|
||||||
|
<arg name="height" type="int"/>
|
||||||
|
<arg name="format" type="uint"/>
|
||||||
|
<arg name="offset0" type="int"/>
|
||||||
|
<arg name="stride0" type="int"/>
|
||||||
|
<arg name="offset1" type="int"/>
|
||||||
|
<arg name="stride1" type="int"/>
|
||||||
|
<arg name="offset2" type="int"/>
|
||||||
|
<arg name="stride2" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
|
@ -14,6 +14,7 @@ mod logger;
|
||||||
pub mod shell;
|
pub mod shell;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
pub mod wayland;
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
pub mod debug;
|
pub mod debug;
|
||||||
|
|
|
||||||
106
src/wayland/drm.rs
Normal file
106
src/wayland/drm.rs
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
// Re-export only the actual code, and then only use this re-export
|
||||||
|
// The `generated` module below is just some boilerplate to properly isolate stuff
|
||||||
|
// and avoid exposing internal details.
|
||||||
|
//
|
||||||
|
// You can use all the types from my_protocol as if they went from `wayland_client::protocol`.
|
||||||
|
pub use generated::server::wl_drm;
|
||||||
|
|
||||||
|
mod generated {
|
||||||
|
// The generated code tends to trigger a lot of warnings
|
||||||
|
// so we isolate it into a very permissive module
|
||||||
|
#![allow(dead_code,non_camel_case_types,unused_unsafe,unused_variables)]
|
||||||
|
#![allow(non_upper_case_globals,non_snake_case,unused_imports)]
|
||||||
|
|
||||||
|
pub mod server {
|
||||||
|
use smithay::reexports::{wayland_commons, wayland_server};
|
||||||
|
|
||||||
|
// These imports are used by the generated code
|
||||||
|
pub(crate) use wayland_server::{Main, AnonymousObject, Resource, ResourceMap};
|
||||||
|
pub(crate) use wayland_commons::map::{Object, ObjectMetadata};
|
||||||
|
pub(crate) use wayland_commons::{Interface, MessageGroup};
|
||||||
|
pub(crate) use wayland_commons::wire::{Argument, MessageDesc, ArgumentType, Message};
|
||||||
|
pub(crate) use wayland_commons::smallvec;
|
||||||
|
pub(crate) use wayland_server::sys;
|
||||||
|
pub(crate) use wayland_server::protocol::wl_buffer;
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/wl_drm.rs"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use smithay::{
|
||||||
|
backend::allocator::{
|
||||||
|
Format, Fourcc, Modifier,
|
||||||
|
dmabuf::{Dmabuf, DmabufFlags},
|
||||||
|
},
|
||||||
|
reexports::wayland_server::{Client, Display, Filter, Global, Main},
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
convert::TryFrom,
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init_wl_drm_global<F>(
|
||||||
|
display: &mut Display,
|
||||||
|
device_path: PathBuf,
|
||||||
|
mut formats: Vec<Format>,
|
||||||
|
client_filter: F,
|
||||||
|
) -> Global<wl_drm::WlDrm>
|
||||||
|
where
|
||||||
|
F: FnMut(Client) -> bool + 'static
|
||||||
|
{
|
||||||
|
formats.dedup_by(|f1, f2| f1.code == f2.code);
|
||||||
|
let global = Filter::new(move |(drm, version): (Main<wl_drm::WlDrm>, u32), _, _| {
|
||||||
|
drm.quick_assign(move |drm, req, _| {
|
||||||
|
match req {
|
||||||
|
wl_drm::Request::Authenticate { .. } => drm.authenticated(),
|
||||||
|
wl_drm::Request::CreateBuffer { id, .. } => {
|
||||||
|
id.as_ref().post_error(wl_drm::Error::InvalidName.to_raw(), String::from("Flink handles are unsupported, use PRIME"));
|
||||||
|
},
|
||||||
|
wl_drm::Request::CreatePlanarBuffer { id, .. } => {
|
||||||
|
id.as_ref().post_error(wl_drm::Error::InvalidName.to_raw(), String::from("Flink handles are unsupported, use PRIME"));
|
||||||
|
},
|
||||||
|
wl_drm::Request::CreatePrimeBuffer {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
format,
|
||||||
|
offset0,
|
||||||
|
stride0,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let format = match Fourcc::try_from(format) {
|
||||||
|
Ok(format) => format,
|
||||||
|
Err(_) => {
|
||||||
|
id.as_ref().post_error(wl_drm::Error::InvalidFormat.to_raw(), String::from("Format not advertised by wl_drm"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if width < 1 || height < 1 {
|
||||||
|
id.as_ref().post_error(wl_drm::Error::InvalidFormat.to_raw(), String::from("width or height not positive"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut dma = Dmabuf::builder((width, height), format, DmabufFlags::empty());
|
||||||
|
dma.add_plane(name, 0, offset0 as u32, stride0 as u32, Modifier::Invalid);
|
||||||
|
id.as_ref().user_data().set_threadsafe(|| dma.build().unwrap());
|
||||||
|
id.quick_assign(|_, _, _| {});
|
||||||
|
slog_scope::trace!("Created a new validated dma wl_buffer via wl_drm.");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
drm.device(device_path.to_string_lossy().into_owned());
|
||||||
|
if version >= 2 {
|
||||||
|
drm.capabilities(wl_drm::Capability::Prime.to_raw());
|
||||||
|
}
|
||||||
|
for format in &formats {
|
||||||
|
if let Some(converted) = wl_drm::Format::from_raw(format.code as u32) {
|
||||||
|
drm.format(converted.to_raw());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
display.create_global_with_filter(2, global, client_filter)
|
||||||
|
}
|
||||||
2
src/wayland/mod.rs
Normal file
2
src/wayland/mod.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
pub mod drm;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue