mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-22 06:47:12 -04:00
Add wlr_box to crop buffer for DRM output
This commit is contained in:
parent
21fecd6015
commit
bdc3358922
3 changed files with 44 additions and 7 deletions
|
|
@ -131,7 +131,7 @@ static void plane_disable(struct atomic *atom, struct wlr_drm_plane *plane) {
|
||||||
atomic_add(atom, id, props->crtc_id, 0);
|
atomic_add(atom, id, props->crtc_id, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_plane_props(struct atomic *atom, struct wlr_drm_backend *drm,
|
static void set_plane_props(struct atomic *atom, struct wlr_box source_box,
|
||||||
struct wlr_drm_plane *plane, uint32_t crtc_id, int32_t x, int32_t y) {
|
struct wlr_drm_plane *plane, uint32_t crtc_id, int32_t x, int32_t y) {
|
||||||
uint32_t id = plane->id;
|
uint32_t id = plane->id;
|
||||||
const union wlr_drm_plane_props *props = &plane->props;
|
const union wlr_drm_plane_props *props = &plane->props;
|
||||||
|
|
@ -141,12 +141,14 @@ static void set_plane_props(struct atomic *atom, struct wlr_drm_backend *drm,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t width = fb->wlr_buf->width;
|
uint32_t width = source_box.width ? (uint32_t)source_box.width :
|
||||||
uint32_t height = fb->wlr_buf->height;
|
fb->wlr_buf->width;
|
||||||
|
uint32_t height = source_box.height ? (uint32_t)source_box.height :
|
||||||
|
fb->wlr_buf->height;
|
||||||
|
|
||||||
// The src_* properties are in 16.16 fixed point
|
// The src_* properties are in 16.16 fixed point
|
||||||
atomic_add(atom, id, props->src_x, 0);
|
atomic_add(atom, id, props->src_x, (uint64_t)source_box.x << 16);
|
||||||
atomic_add(atom, id, props->src_y, 0);
|
atomic_add(atom, id, props->src_y, (uint64_t)source_box.y << 16);
|
||||||
atomic_add(atom, id, props->src_w, (uint64_t)width << 16);
|
atomic_add(atom, id, props->src_w, (uint64_t)width << 16);
|
||||||
atomic_add(atom, id, props->src_h, (uint64_t)height << 16);
|
atomic_add(atom, id, props->src_h, (uint64_t)height << 16);
|
||||||
atomic_add(atom, id, props->crtc_w, width);
|
atomic_add(atom, id, props->crtc_w, width);
|
||||||
|
|
@ -239,20 +241,36 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
||||||
atomic_add(&atom, crtc->id, crtc->props.mode_id, mode_id);
|
atomic_add(&atom, crtc->id, crtc->props.mode_id, mode_id);
|
||||||
atomic_add(&atom, crtc->id, crtc->props.active, active);
|
atomic_add(&atom, crtc->id, crtc->props.active, active);
|
||||||
if (active) {
|
if (active) {
|
||||||
|
struct wlr_box source_box;
|
||||||
|
if (state->committed & WLR_OUTPUT_STATE_SOURCE_BOX) {
|
||||||
|
/**
|
||||||
|
* Grab source box from output in order to crop the
|
||||||
|
* buffer.
|
||||||
|
*/
|
||||||
|
source_box = state->source_box;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Use dummy source box
|
||||||
|
source_box.x = source_box.y = source_box.width =
|
||||||
|
source_box.height = 0;
|
||||||
|
}
|
||||||
if (crtc->props.gamma_lut != 0) {
|
if (crtc->props.gamma_lut != 0) {
|
||||||
atomic_add(&atom, crtc->id, crtc->props.gamma_lut, gamma_lut);
|
atomic_add(&atom, crtc->id, crtc->props.gamma_lut, gamma_lut);
|
||||||
}
|
}
|
||||||
if (crtc->props.vrr_enabled != 0) {
|
if (crtc->props.vrr_enabled != 0) {
|
||||||
atomic_add(&atom, crtc->id, crtc->props.vrr_enabled, vrr_enabled);
|
atomic_add(&atom, crtc->id, crtc->props.vrr_enabled, vrr_enabled);
|
||||||
}
|
}
|
||||||
set_plane_props(&atom, drm, crtc->primary, crtc->id, 0, 0);
|
set_plane_props(&atom, source_box, crtc->primary, crtc->id, 0, 0);
|
||||||
if (crtc->primary->props.fb_damage_clips != 0) {
|
if (crtc->primary->props.fb_damage_clips != 0) {
|
||||||
atomic_add(&atom, crtc->primary->id,
|
atomic_add(&atom, crtc->primary->id,
|
||||||
crtc->primary->props.fb_damage_clips, fb_damage_clips);
|
crtc->primary->props.fb_damage_clips, fb_damage_clips);
|
||||||
}
|
}
|
||||||
if (crtc->cursor) {
|
if (crtc->cursor) {
|
||||||
if (drm_connector_is_cursor_visible(conn)) {
|
if (drm_connector_is_cursor_visible(conn)) {
|
||||||
set_plane_props(&atom, drm, crtc->cursor, crtc->id,
|
// Ensure source_box is unset for cursor plane
|
||||||
|
source_box.x = source_box.y = source_box.width =
|
||||||
|
source_box.height = 0;
|
||||||
|
set_plane_props(&atom, source_box, crtc->cursor, crtc->id,
|
||||||
conn->cursor_x, conn->cursor_y);
|
conn->cursor_x, conn->cursor_y);
|
||||||
} else {
|
} else {
|
||||||
plane_disable(&atom, crtc->cursor);
|
plane_disable(&atom, crtc->cursor);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include <wayland-util.h>
|
#include <wayland-util.h>
|
||||||
#include <wlr/types/wlr_buffer.h>
|
#include <wlr/types/wlr_buffer.h>
|
||||||
#include <wlr/util/addon.h>
|
#include <wlr/util/addon.h>
|
||||||
|
#include <wlr/types/wlr_box.h>
|
||||||
|
|
||||||
struct wlr_output_mode {
|
struct wlr_output_mode {
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
|
|
@ -72,6 +73,7 @@ enum wlr_output_state_field {
|
||||||
WLR_OUTPUT_STATE_TRANSFORM = 1 << 5,
|
WLR_OUTPUT_STATE_TRANSFORM = 1 << 5,
|
||||||
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED = 1 << 6,
|
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED = 1 << 6,
|
||||||
WLR_OUTPUT_STATE_GAMMA_LUT = 1 << 7,
|
WLR_OUTPUT_STATE_GAMMA_LUT = 1 << 7,
|
||||||
|
WLR_OUTPUT_STATE_SOURCE_BOX = 1 << 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum wlr_output_state_mode_type {
|
enum wlr_output_state_mode_type {
|
||||||
|
|
@ -89,6 +91,9 @@ struct wlr_output_state {
|
||||||
float scale;
|
float scale;
|
||||||
enum wl_output_transform transform;
|
enum wl_output_transform transform;
|
||||||
bool adaptive_sync_enabled;
|
bool adaptive_sync_enabled;
|
||||||
|
/* allow partial buffer scanout for tiling displays
|
||||||
|
* only valid if WLR_OUTPUT_STATE_SOURCE_BOX */
|
||||||
|
struct wlr_box source_box; // source box for respective output
|
||||||
|
|
||||||
// only valid if WLR_OUTPUT_STATE_BUFFER
|
// only valid if WLR_OUTPUT_STATE_BUFFER
|
||||||
struct wlr_buffer *buffer;
|
struct wlr_buffer *buffer;
|
||||||
|
|
@ -372,6 +377,14 @@ uint32_t wlr_output_preferred_read_format(struct wlr_output *output);
|
||||||
*/
|
*/
|
||||||
void wlr_output_set_damage(struct wlr_output *output,
|
void wlr_output_set_damage(struct wlr_output *output,
|
||||||
pixman_region32_t *damage);
|
pixman_region32_t *damage);
|
||||||
|
/**
|
||||||
|
* This can be used in case the output buffer is larger than the buffer that
|
||||||
|
* is supposed to be presented on the actual screen attached to the DRM
|
||||||
|
* connector. Current use case are hi-res tiling displays which use multiple
|
||||||
|
* DRM connectors to make up the full monitor.
|
||||||
|
*/
|
||||||
|
void wlr_output_set_source_box(struct wlr_output *output,
|
||||||
|
struct wlr_box source_box);
|
||||||
/**
|
/**
|
||||||
* Test whether the pending output state would be accepted by the backend. If
|
* Test whether the pending output state would be accepted by the backend. If
|
||||||
* this function returns true, `wlr_output_commit` can only fail due to a
|
* this function returns true, `wlr_output_commit` can only fail due to a
|
||||||
|
|
|
||||||
|
|
@ -714,6 +714,12 @@ void wlr_output_attach_buffer(struct wlr_output *output,
|
||||||
output->pending.buffer = wlr_buffer_lock(buffer);
|
output->pending.buffer = wlr_buffer_lock(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wlr_output_set_source_box(struct wlr_output *output,
|
||||||
|
struct wlr_box source_box) {
|
||||||
|
output->pending.source_box = source_box;
|
||||||
|
output->pending.committed |= WLR_OUTPUT_STATE_SOURCE_BOX;
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_output_send_frame(struct wlr_output *output) {
|
void wlr_output_send_frame(struct wlr_output *output) {
|
||||||
output->frame_pending = false;
|
output->frame_pending = false;
|
||||||
if (output->enabled) {
|
if (output->enabled) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue