Add docs and comments
This commit is contained in:
parent
0365b587f0
commit
c6aab6f56c
|
@ -5,6 +5,11 @@
|
||||||
#include <pixman.h>
|
#include <pixman.h>
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Damage tracking requires to keep track of previous frames' damage. To allow
|
||||||
|
* damage tracking to work with triple buffering, an history of two frames is
|
||||||
|
* required.
|
||||||
|
*/
|
||||||
#define ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN 2
|
#define ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN 2
|
||||||
|
|
||||||
struct roots_desktop;
|
struct roots_desktop;
|
||||||
|
@ -20,6 +25,7 @@ struct roots_output {
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
bool frame_pending;
|
bool frame_pending;
|
||||||
|
|
||||||
|
// circular queue for previous damage
|
||||||
pixman_region32_t previous_damage[ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN];
|
pixman_region32_t previous_damage[ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN];
|
||||||
size_t previous_damage_idx;
|
size_t previous_damage_idx;
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,6 @@ struct wlr_output_cursor {
|
||||||
struct wl_listener surface_destroy;
|
struct wl_listener surface_destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WLR_OUTPUT_PREVIOUS_DAMAGE_COUNT 2
|
|
||||||
|
|
||||||
struct wlr_output_impl;
|
struct wlr_output_impl;
|
||||||
|
|
||||||
struct wlr_output {
|
struct wlr_output {
|
||||||
|
@ -51,21 +49,21 @@ struct wlr_output {
|
||||||
char serial[16];
|
char serial[16];
|
||||||
int32_t phys_width, phys_height; // mm
|
int32_t phys_width, phys_height; // mm
|
||||||
|
|
||||||
|
// Note: some backends may have zero modes
|
||||||
|
struct wl_list modes;
|
||||||
|
struct wlr_output_mode *current_mode;
|
||||||
|
int32_t width, height;
|
||||||
|
int32_t refresh; // mHz, may be zero
|
||||||
|
|
||||||
bool enabled;
|
bool enabled;
|
||||||
float scale;
|
float scale;
|
||||||
enum wl_output_subpixel subpixel;
|
enum wl_output_subpixel subpixel;
|
||||||
enum wl_output_transform transform;
|
enum wl_output_transform transform;
|
||||||
|
|
||||||
bool needs_swap;
|
bool needs_swap;
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage; // damage for cursors and fullscreen surface
|
||||||
float transform_matrix[16];
|
float transform_matrix[16];
|
||||||
|
|
||||||
// Note: some backends may have zero modes
|
|
||||||
struct wl_list modes;
|
|
||||||
struct wlr_output_mode *current_mode;
|
|
||||||
int32_t width, height;
|
|
||||||
int32_t refresh; // mHz
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct wl_signal frame;
|
struct wl_signal frame;
|
||||||
struct wl_signal needs_swap;
|
struct wl_signal needs_swap;
|
||||||
|
@ -107,16 +105,18 @@ void wlr_output_destroy(struct wlr_output *output);
|
||||||
void wlr_output_effective_resolution(struct wlr_output *output,
|
void wlr_output_effective_resolution(struct wlr_output *output,
|
||||||
int *width, int *height);
|
int *width, int *height);
|
||||||
/**
|
/**
|
||||||
* Makes the output GL context current.
|
* Makes the output rendering context current.
|
||||||
*
|
*
|
||||||
* `buffer_age` is set to the drawing buffer age in number of frames or -1 if
|
* `buffer_age` is set to the drawing buffer age in number of frames or -1 if
|
||||||
* unknown.
|
* unknown. This is useful for damage tracking.
|
||||||
*/
|
*/
|
||||||
bool wlr_output_make_current(struct wlr_output *output, int *buffer_age);
|
bool wlr_output_make_current(struct wlr_output *output, int *buffer_age);
|
||||||
/**
|
/**
|
||||||
* Swaps the output buffers. If the time of the frame isn't known, set `when` to
|
* Swaps the output buffers. If the time of the frame isn't known, set `when` to
|
||||||
* NULL. If the compositor doesn't support damage tracking, set `damage` to
|
* NULL. If the compositor doesn't support damage tracking, set `damage` to
|
||||||
* NULL.
|
* NULL.
|
||||||
|
*
|
||||||
|
* Swapping buffers schedules a `frame` event.
|
||||||
*/
|
*/
|
||||||
bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
|
bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
|
||||||
pixman_region32_t *damage);
|
pixman_region32_t *damage);
|
||||||
|
@ -126,6 +126,7 @@ uint32_t wlr_output_get_gamma_size(struct wlr_output *output);
|
||||||
void wlr_output_set_fullscreen_surface(struct wlr_output *output,
|
void wlr_output_set_fullscreen_surface(struct wlr_output *output,
|
||||||
struct wlr_surface *surface);
|
struct wlr_surface *surface);
|
||||||
|
|
||||||
|
|
||||||
struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output);
|
struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output);
|
||||||
/**
|
/**
|
||||||
* Sets the cursor image. The image must be already scaled for the output.
|
* Sets the cursor image. The image must be already scaled for the output.
|
||||||
|
|
|
@ -31,6 +31,10 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a surface at (lx, ly) intersects an output. Sets `box` to the
|
||||||
|
* surface box in the output, in output-local coordinates.
|
||||||
|
*/
|
||||||
static bool surface_intersect_output(struct wlr_surface *surface,
|
static bool surface_intersect_output(struct wlr_surface *surface,
|
||||||
struct wlr_output_layout *output_layout, struct wlr_output *wlr_output,
|
struct wlr_output_layout *output_layout, struct wlr_output *wlr_output,
|
||||||
double lx, double ly, struct wlr_box *box) {
|
double lx, double ly, struct wlr_box *box) {
|
||||||
|
@ -138,10 +142,8 @@ render_subsurfaces:;
|
||||||
struct wlr_surface_state *state = subsurface->surface->current;
|
struct wlr_surface_state *state = subsurface->surface->current;
|
||||||
double sx = state->subsurface_position.x;
|
double sx = state->subsurface_position.x;
|
||||||
double sy = state->subsurface_position.y;
|
double sy = state->subsurface_position.y;
|
||||||
double sw = state->buffer_width / state->scale;
|
rotate_child_position(&sx, &sy, state->width, state->height,
|
||||||
double sh = state->buffer_height / state->scale;
|
surface->current->width, surface->current->height, rotation);
|
||||||
rotate_child_position(&sx, &sy, sw, sh, surface->current->width,
|
|
||||||
surface->current->height, rotation);
|
|
||||||
|
|
||||||
render_surface(subsurface->surface, output, when, damage,
|
render_surface(subsurface->surface, output, when, damage,
|
||||||
lx + sx, ly + sy, rotation);
|
lx + sx, ly + sy, rotation);
|
||||||
|
@ -297,6 +299,7 @@ static void render_output(struct roots_output *output) {
|
||||||
int buffer_age = -1;
|
int buffer_age = -1;
|
||||||
wlr_output_make_current(wlr_output, &buffer_age);
|
wlr_output_make_current(wlr_output, &buffer_age);
|
||||||
|
|
||||||
|
// Check if we can use damage tracking
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
pixman_region32_init(&damage);
|
pixman_region32_init(&damage);
|
||||||
if (buffer_age <= 0 || buffer_age - 1 > ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN) {
|
if (buffer_age <= 0 || buffer_age - 1 > ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN) {
|
||||||
|
@ -306,8 +309,9 @@ static void render_output(struct roots_output *output) {
|
||||||
} else {
|
} else {
|
||||||
pixman_region32_copy(&damage, &output->damage);
|
pixman_region32_copy(&damage, &output->damage);
|
||||||
|
|
||||||
|
// Accumulate damage from old buffers
|
||||||
size_t idx = output->previous_damage_idx;
|
size_t idx = output->previous_damage_idx;
|
||||||
for (int i = 0; i < buffer_age - 1; i++) {
|
for (int i = 0; i < buffer_age - 1; ++i) {
|
||||||
int j = (idx + i) % ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN;
|
int j = (idx + i) % ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN;
|
||||||
pixman_region32_union(&damage, &damage, &output->previous_damage[j]);
|
pixman_region32_union(&damage, &damage, &output->previous_damage[j]);
|
||||||
}
|
}
|
||||||
|
@ -362,11 +366,13 @@ static void render_output(struct roots_output *output) {
|
||||||
goto renderer_end;
|
goto renderer_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render all views
|
||||||
struct roots_view *view;
|
struct roots_view *view;
|
||||||
wl_list_for_each_reverse(view, &desktop->views, link) {
|
wl_list_for_each_reverse(view, &desktop->views, link) {
|
||||||
render_view(view, output, &now, &damage);
|
render_view(view, output, &now, &damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render drag icons
|
||||||
struct wlr_drag_icon *drag_icon = NULL;
|
struct wlr_drag_icon *drag_icon = NULL;
|
||||||
struct roots_seat *seat = NULL;
|
struct roots_seat *seat = NULL;
|
||||||
wl_list_for_each(seat, &server->input->seats, link) {
|
wl_list_for_each(seat, &server->input->seats, link) {
|
||||||
|
@ -398,6 +404,7 @@ renderer_end:
|
||||||
wlr_renderer_end(server->renderer);
|
wlr_renderer_end(server->renderer);
|
||||||
wlr_output_swap_buffers(wlr_output, &now, &damage);
|
wlr_output_swap_buffers(wlr_output, &now, &damage);
|
||||||
output->frame_pending = true;
|
output->frame_pending = true;
|
||||||
|
// same as decrementing, but works on unsigned integers
|
||||||
output->previous_damage_idx += ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN - 1;
|
output->previous_damage_idx += ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN - 1;
|
||||||
output->previous_damage_idx %= ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN;
|
output->previous_damage_idx %= ROOTS_OUTPUT_PREVIOUS_DAMAGE_LEN;
|
||||||
pixman_region32_copy(&output->previous_damage[output->previous_damage_idx],
|
pixman_region32_copy(&output->previous_damage[output->previous_damage_idx],
|
||||||
|
@ -421,6 +428,7 @@ static void handle_idle_render(void *data) {
|
||||||
|
|
||||||
static void schedule_render(struct roots_output *output) {
|
static void schedule_render(struct roots_output *output) {
|
||||||
if (!output->frame_pending) {
|
if (!output->frame_pending) {
|
||||||
|
// TODO: ask the backend to send a frame event when appropriate instead
|
||||||
struct wl_event_loop *ev =
|
struct wl_event_loop *ev =
|
||||||
wl_display_get_event_loop(output->desktop->server->wl_display);
|
wl_display_get_event_loop(output->desktop->server->wl_display);
|
||||||
wl_event_loop_add_idle(ev, handle_idle_render, output);
|
wl_event_loop_add_idle(ev, handle_idle_render, output);
|
||||||
|
@ -480,6 +488,7 @@ static void output_damage_from_surface(struct roots_output *output,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: output scale, output transform support
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
pixman_region32_init(&damage);
|
pixman_region32_init(&damage);
|
||||||
pixman_region32_copy(&damage, &surface->current->surface_damage);
|
pixman_region32_copy(&damage, &surface->current->surface_damage);
|
||||||
|
|
Loading…
Reference in New Issue