Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • keshto/wlroots
  • markbolhuis/wlroots
  • joanbrugueram/wlroots
  • ammen99/wlroots
  • mfk530/wlroots
  • lovesegfault/wlroots
  • Programmerino/wlroots
  • wlroots/wlroots
  • mstoeckl/wlroots
  • emersion/wlroots
  • tadeokondrak/wlroots
  • MisterDA/wlroots
  • vyivel/wlroots
  • agx/wlroots
  • bl4ckb0ne/wlroots
  • ifreund/wlroots
  • Beryesa/wlroots
  • colemickens/wlroots
  • frog/wlroots
  • raphaelr/wlroots
  • etom/wlroots
  • Emantor/wlroots
  • romangg/wlroots
  • DemiMarie/wlroots
  • lilydjwg/wlroots
  • ashafer/wlroots
  • ericonr/wlroots
  • jlindgren90/wlroots
  • hurrdurr/wlroots
  • quantum/wlroots
  • alex-courtis/wlroots
  • zagursky/wlroots
  • zavorka/wlroots
  • nowrep/wlroots
  • StacyHarper/wlroots
  • valpackett/wlroots
  • nyorain/wlroots
  • kimhoai.nguyen123/wlroots
  • Nefsen402/wlroots
  • duncanm/wlroots
  • tchebb/wlroots
  • kennylevinsen/wlroots
  • demansanaa/wlroots
  • sjnewbury/wlroots
  • illiliti/wlroots
  • martinetd/wlroots
  • keithbowes/wlroots
  • 5l8yj2lv/wlroots
  • andri/wlroots
  • JoseExposito/wlroots
  • held-m/wlroots
  • dos/wlroots
  • OctopusET/wlroots
  • jide/wlroots
  • David96/wlroots
  • sammko/wlroots
  • wingdeans/wlroots
  • lostmythread/wlroots
  • sevz/wlroots
  • yrlf/wlroots
  • tmlind/wlroots
  • nagy/wlroots
  • brocellous/wlroots
  • kchibisov/wlroots
  • caseorum/wlroots
  • zsugabubus/wlroots
  • ptrcnull/wlroots
  • sktt/wlroots
  • yiqiang/wlroots
  • dzmien/wlroots
  • vaxerski/wlroots
  • Consolatis/wlroots
  • paraworker/wlroots
  • maccraft/wlroots
  • johanmalm/wlroots
  • bi4k8/wlroots
  • fakeczg/wlroots
  • stshine/wlroots
  • puckipedia/wlroots
  • vanfanel/wlroots
  • laxyy/wlroots
  • gabcoh/wlroots
  • lack/wlroots
  • shua/wlroots
  • xiliuya/wlroots
  • prehonor/wlroots
  • BBaoVanC/wlroots
  • qaqland/wlroots
  • llyyr/wlroots
  • clamps/wlroots
  • Woodpile37/wlroots
  • samuel/wlroots
  • eric/wlroots
  • vvavrychuk/wlroots
  • 9ary/wlroots
  • gvideo434/wlroots
  • alxu/wlroots
  • tobias.predel/wlroots
  • rosefromthedead/wlroots
  • philipp.kaeser/wlroots
  • phnaharris/wlroots
  • Drakulix/wlroots
  • Edgars-Cirulis/wlroots
  • EBADBEEF/wlroots
  • mainiomano/wlroots
  • gilvbp/wlroots
  • Leon-Plickat/wlroots
  • ghishadow/wlroots
  • evyatark2/wlroots
  • craftyguy/wlroots
  • mherrb/wlroots
  • Dudemanguy/wlroots
  • ErikReider/wlroots
  • wineee/wlroots
  • q234rty/wlroots
  • maaarghk/wlroots
  • saihaze/wlroots
  • wingedcutter/wlroots
  • YellowOnion/wlroots
  • jdtatz/wlroots
  • aadi58002/wlroots
  • leoli/wlroots-output-layers
  • MoetaYuko/wlroots
  • SergioGDR/wlroots
  • kelnos/wlroots
  • kode54/wlroots
  • navi_desu/wlroots
  • eerii/wlroots
  • sunzhguy/wlroots
  • zorowk/wlroots
  • dkondor1/wlroots
  • lahavts/wlroots
  • bwhmather/wlroots
  • mcoffin/wlroots
  • praschke/wlroots
  • trofi/wlroots
  • MaxVerevkin/wlroots
  • 6by9/wlroots
  • svalaskevicius/wlroots
  • Rui511/wlroots
  • fpoisot/wlroots
  • danieldg/wlroots
  • grisha128/wlroots
  • serebit/wlrplus
  • david.turner/wlroots
  • pcercuei/wlroots
  • columbarius/wlroots-tmp
  • sleirsgoevy/wlroots
  • HeYong/wlroots
  • Louis_Goyard/wlroots
  • iforbes/wlroots
  • vimproved/wlroots
  • toast/wlroots
  • shadowgamer67890/wlroots-rhpd
  • tomenglund26/wlroots
  • WhyNotHugo/wlroots
  • Groveer/wlroots
  • luyn/wlroots
  • n3rdopolis/wlroots
  • amfcosta13/wlroots
  • BiRD04/wlroots
  • Billli11/wlroots
  • chenyongxing/wlroots
  • sewn/wlroots
  • kkartaltepe/wlroots
  • furball/wlroots
  • carbonXIII/wlroots
  • ali1234/wlroots
  • project-repo/wlroots
  • garlett/wlroots-lease-multiseat
  • C0rn3j/wlroots
  • arun-mani-j/wlroots
  • liup/wlroots
  • qyliss/wlroots
  • tatokis/wlroots
  • masiukiewicz.michal/wlroots
  • asterwyx/wlroots
  • tokyo4j/wlroots
  • tych0/wlroots
  • james.jehiel.ramsey/wlroots
  • zzxyb/wlroots
  • iv.dovg/wlroots
  • atbjyk/wlroots
183 results
Show changes
Commits on Source (4)
......@@ -106,6 +106,10 @@ bool check_drm_features(struct wlr_drm_backend *drm) {
drm->iface = &atomic_iface;
}
if (drm->iface == &legacy_iface) {
drm->supports_tearing_page_flips = drmGetCap(drm->fd, DRM_CAP_ASYNC_PAGE_FLIP, &cap) == 0 && cap == 1;
}
int ret = drmGetCap(drm->fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
drm->clock = (ret == 0 && cap == 1) ? CLOCK_MONOTONIC : CLOCK_REALTIME;
......@@ -650,6 +654,11 @@ static bool drm_connector_test(struct wlr_output *output,
if (!drm_connector_state_update_primary_fb(conn, &pending)) {
goto out;
}
if (pending.base->tearing_page_flip && !conn->backend->supports_tearing_page_flips) {
wlr_log(WLR_ERROR, "Attempted to submit a tearing page flip to an unsupported backend!");
goto out;
}
}
if (state->committed & WLR_OUTPUT_STATE_LAYERS) {
if (!drm_connector_set_pending_layer_fbs(conn, pending.base)) {
......@@ -725,7 +734,7 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn,
// page-flip, either a blocking modeset. When performing a blocking modeset
// we'll wait for all queued page-flips to complete, so we don't need this
// safeguard.
if (conn->pending_page_flip_crtc && !pending.modeset) {
if (conn->pending_page_flip_crtc && !pending.modeset && !pending.base->tearing_page_flip) {
wlr_drm_conn_log(conn, WLR_ERROR, "Failed to page-flip output: "
"a page-flip is already pending");
goto out;
......@@ -748,6 +757,9 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn,
}
uint32_t flags = pending.active ? DRM_MODE_PAGE_FLIP_EVENT : 0;
if (pending.base->tearing_page_flip) {
flags |= DRM_MODE_PAGE_FLIP_ASYNC;
}
ok = drm_crtc_commit(conn, &pending, flags, false);
if (!ok) {
......
......@@ -175,8 +175,13 @@ static bool legacy_crtc_commit(struct wlr_drm_connector *conn,
}
if (flags & DRM_MODE_PAGE_FLIP_EVENT) {
uint32_t page_flags = DRM_MODE_PAGE_FLIP_EVENT;
if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
page_flags |= DRM_MODE_PAGE_FLIP_ASYNC;
}
if (drmModePageFlip(drm->fd, crtc->id, fb_id,
DRM_MODE_PAGE_FLIP_EVENT, drm)) {
page_flags, drm)) {
wlr_drm_conn_log_errno(conn, WLR_ERROR, "drmModePageFlip failed");
return false;
}
......
......@@ -114,6 +114,8 @@ struct wlr_drm_backend {
uint64_t cursor_width, cursor_height;
struct wlr_drm_format_set mgpu_formats;
bool supports_tearing_page_flips;
};
struct wlr_drm_mode {
......
......@@ -89,6 +89,12 @@ struct wlr_output_state {
enum wl_output_subpixel subpixel;
struct wlr_buffer *buffer;
/* Request a tearing page-flip. When enabled, this may cause the output to
* display a part of the previous buffer and a part of the current buffer at
* the same time. The backend may reject the commit if a tearing page-flip
* cannot be performed, in which case the caller should fall back to a
* regular page-flip at the next wlr_output.frame event. */
bool tearing_page_flip;
enum wlr_output_state_mode_type mode_type;
struct wlr_output_mode *mode;
......
......@@ -529,6 +529,9 @@ struct wlr_scene_output_layout *wlr_scene_attach_output_layout(struct wlr_scene
/**
* Add an output to the scene, with its positioning defined by the output layout.
*
* The `wlr_scene_output_layout` takes ownership of the `wlr_scene_output`, which will be destroyed
* when either the `wlr_scene_output_layout` or the `wlr_output_layout_output` is destroyed.
*/
void wlr_scene_output_layout_add_output(struct wlr_scene_output_layout *sol,
struct wlr_output_layout_output *lo, struct wlr_scene_output *so);
......
/*
* This an unstable interface of wlroots. No guarantees are made regarding the
* future consistency of this API.
*/
#ifndef WLR_USE_UNSTABLE
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
#endif
#ifndef WLR_TYPES_WLR_TEARING_CONTROL_MANAGER_V1_H
#define WLR_TYPES_WLR_TEARING_CONTROL_MANAGER_V1_H
#include <stdint.h>
#include <wayland-server-core.h>
#include <wayland-server-protocol.h>
#include <wlr/types/wlr_compositor.h>
#include "tearing-control-v1-protocol.h"
struct wlr_tearing_control_v1 {
uint32_t hint;
struct wl_client *client;
struct wl_list link;
struct wl_resource *resource;
struct {
struct wl_signal set_hint;
struct wl_signal destroy;
} events;
struct wlr_surface *surface;
struct wlr_addon addon;
};
struct wlr_tearing_control_manager_v1 {
struct wl_global *global;
struct wl_list surface_hints; // wlr_tearing_control_v1.link
struct wl_listener display_destroy;
struct {
struct wl_signal new_object; // struct wlr_tearing_control_v1*
struct wl_signal destroy;
} events;
void *data;
};
struct wlr_tearing_control_manager_v1 *wlr_tearing_control_manager_v1_create(
struct wl_display *display, uint32_t version);
/**
* Returns the tearing hint for a given surface
*/
enum wp_tearing_control_v1_presentation_hint
wlr_tearing_control_manager_v1_surface_hint_from_surface(
struct wlr_tearing_control_manager_v1 *manager,
struct wlr_surface *surface);
#endif
......@@ -27,6 +27,7 @@ protocols = {
'single-pixel-buffer-v1': wl_protocol_dir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml',
'xdg-activation-v1': wl_protocol_dir / 'staging/xdg-activation/xdg-activation-v1.xml',
'xwayland-shell-v1': wl_protocol_dir / 'staging/xwayland-shell/xwayland-shell-v1.xml',
'tearing-control-v1': wl_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml',
# Unstable upstream protocols
'fullscreen-shell-unstable-v1': wl_protocol_dir / 'unstable/fullscreen-shell/fullscreen-shell-unstable-v1.xml',
......
......@@ -91,6 +91,7 @@ wlr_files += files(
'wlr_xdg_foreign_v2.c',
'wlr_xdg_foreign_registry.c',
'wlr_xdg_output_v1.c',
'wlr_tearing_control_v1.c',
)
if features.get('drm-backend')
......
......@@ -665,6 +665,9 @@ static bool output_basic_test(struct wlr_output *output,
wlr_log(WLR_DEBUG, "Primary buffer size mismatch");
return false;
}
} else if (state->tearing_page_flip) {
wlr_log(WLR_ERROR, "Trying to commit a tearing page flip without a buffer?");
return false;
}
if (state->committed & WLR_OUTPUT_STATE_RENDER_FORMAT) {
......
......@@ -24,7 +24,7 @@ static void server_decoration_handle_request_mode(struct wl_client *client,
struct wl_resource *resource, uint32_t mode) {
struct wlr_server_decoration *decoration =
decoration_from_resource(resource);
if (decoration->mode == mode) {
if (decoration == NULL || decoration->mode == mode) {
return;
}
decoration->mode = mode;
......
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <stdlib.h>
#include <wayland-server-core.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_tearing_control_v1.h>
#include <wlr/util/log.h>
#include "tearing-control-v1-protocol.h"
#define TEARING_CONTROL_MANAGER_VERSION 1
static const struct wp_tearing_control_manager_v1_interface tearing_impl;
static const struct wp_tearing_control_v1_interface tearing_control_impl;
static struct wlr_tearing_control_manager_v1 *tearing_manager_from_resource(
struct wl_resource *resource) {
assert(wl_resource_instance_of(resource, &wp_tearing_control_manager_v1_interface,
&tearing_impl));
return wl_resource_get_user_data(resource);
}
static struct wlr_tearing_control_v1 *tearing_surface_hint_from_resource(
struct wl_resource *resource) {
assert(wl_resource_instance_of(resource, &wp_tearing_control_v1_interface,
&tearing_control_impl));
return wl_resource_get_user_data(resource);
}
static void destroy_tearing_hint(struct wlr_tearing_control_v1 *hint) {
if (hint == NULL) {
return;
}
wl_signal_emit_mutable(&hint->events.destroy, NULL);
wl_list_remove(&hint->link);
wl_resource_set_user_data(hint->resource, NULL);
wlr_addon_finish(&hint->addon);
free(hint);
}
static void surface_addon_destroy(struct wlr_addon *addon) {
struct wlr_tearing_control_v1 *hint = wl_container_of(addon, hint, addon);
destroy_tearing_hint(hint);
}
static const struct wlr_addon_interface surface_addon_impl = {
.name = "wp_tearing_control_v1",
.destroy = surface_addon_destroy,
};
static void resource_handle_destroy(struct wl_client *client,
struct wl_resource *resource) {
wl_resource_destroy(resource);
}
static void destroy_tearing_resource_impl(struct wl_resource *resource) {
struct wlr_tearing_control_v1 *hint = tearing_surface_hint_from_resource(resource);
destroy_tearing_hint(hint);
}
static void tearing_control_handle_presentation_hint(struct wl_client *client,
struct wl_resource *resource, uint32_t hint) {
struct wlr_tearing_control_v1 *surface_hint =
tearing_surface_hint_from_resource(resource);
surface_hint->hint = hint;
wl_signal_emit_mutable(&surface_hint->events.set_hint, NULL);
}
static const struct wp_tearing_control_v1_interface tearing_control_impl = {
.destroy = resource_handle_destroy,
.set_presentation_hint = tearing_control_handle_presentation_hint
};
static void tearing_control_manager_handle_get_tearing_control(
struct wl_client *client, struct wl_resource *resource, uint32_t id,
struct wl_resource *surface_resource) {
struct wlr_tearing_control_manager_v1 *manager = tearing_manager_from_resource(resource);
struct wlr_surface *surface = wlr_surface_from_resource(surface_resource);
if (wlr_addon_find(&surface->addons, manager, &surface_addon_impl) != NULL) {
wl_resource_post_error(resource,
WP_TEARING_CONTROL_MANAGER_V1_ERROR_TEARING_CONTROL_EXISTS,
"Tearing control object already exists!");
return;
}
struct wlr_tearing_control_v1 *hint = calloc(1, sizeof(struct wlr_tearing_control_v1));
if (!hint) {
wl_client_post_no_memory(client);
return;
}
struct wl_resource *created_resource =
wl_resource_create(client, &wp_tearing_control_v1_interface,
wl_resource_get_version(resource), id);
if (created_resource == NULL) {
wl_resource_post_no_memory(resource);
return;
}
wl_resource_set_implementation(created_resource, &tearing_control_impl,
hint, destroy_tearing_resource_impl);
hint->hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
hint->client = client;
hint->resource = created_resource;
hint->surface = surface;
wlr_addon_init(&hint->addon, &hint->surface->addons, manager, &surface_addon_impl);
wl_signal_init(&hint->events.set_hint);
wl_signal_init(&hint->events.destroy);
wl_list_insert(&manager->surface_hints, &hint->link);
wl_signal_emit_mutable(&manager->events.new_object, hint);
}
static const struct wp_tearing_control_manager_v1_interface tearing_impl = {
.destroy = resource_handle_destroy,
.get_tearing_control = tearing_control_manager_handle_get_tearing_control,
};
static void tearing_bind(struct wl_client *wl_client, void *data,
uint32_t version, uint32_t id) {
struct wlr_tearing_control_manager_v1 *manager = data;
struct wl_resource *wl_resource = wl_resource_create(wl_client,
&wp_tearing_control_manager_v1_interface, version, id);
if (wl_resource == NULL) {
wl_client_post_no_memory(wl_client);
return;
}
wl_resource_set_implementation(wl_resource, &tearing_impl, manager, NULL);
}
static void handle_display_destroy(struct wl_listener *listener, void *data) {
struct wlr_tearing_control_manager_v1 *manager =
wl_container_of(listener, manager, display_destroy);
wl_signal_emit_mutable(&manager->events.destroy, NULL);
struct wlr_tearing_control_v1 *hint;
wl_list_for_each(hint, &manager->surface_hints, link) {
destroy_tearing_hint(hint);
}
wl_list_remove(&manager->display_destroy.link);
wl_global_destroy(manager->global);
free(manager);
}
struct wlr_tearing_control_manager_v1 *wlr_tearing_control_manager_v1_create(
struct wl_display *display, uint32_t version) {
assert(version <= TEARING_CONTROL_MANAGER_VERSION);
struct wlr_tearing_control_manager_v1 *manager =
calloc(1, sizeof(struct wlr_tearing_control_manager_v1));
if (!manager) {
wlr_log_errno(WLR_ERROR, "Allocation failed");
return NULL;
}
wl_signal_init(&manager->events.new_object);
wl_signal_init(&manager->events.destroy);
wl_list_init(&manager->surface_hints);
manager->display_destroy.notify = handle_display_destroy;
wl_display_add_destroy_listener(display, &manager->display_destroy);
manager->global = wl_global_create(display, &wp_tearing_control_manager_v1_interface,
version, manager, tearing_bind);
if (manager->global == NULL) {
wl_list_remove(&manager->display_destroy.link);
free(manager);
return NULL;
}
return manager;
}
enum wp_tearing_control_v1_presentation_hint
wlr_tearing_control_manager_v1_surface_hint_from_surface(struct wlr_tearing_control_manager_v1 *manager,
struct wlr_surface *surface) {
struct wlr_addon *addon =
wlr_addon_find(&surface->addons, manager, &surface_addon_impl);
if (addon == NULL) {
return WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC;
}
struct wlr_tearing_control_v1 *hint = wl_container_of(addon, hint, addon);
return hint->hint;
}