Skip to content

Commit 315bd32

Browse files
authored
Merge pull request #1253 from yshui/animation-part2
Animation: part 2
2 parents 02a7c71 + 91ffbb4 commit 315bd32

31 files changed

+2706
-700
lines changed

src/backend/backend.h

+5
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ struct backend_blit_args {
125125
/// will be normalized so that the maximum brightness is
126126
/// this value.
127127
double max_brightness;
128+
/// Scale factor for the horizontal and vertical direction (X for horizontal,
129+
/// Y for vertical).
130+
vec2 scale;
128131
/// Corner radius of the source image. The corners of
129132
/// the source image will be rounded.
130133
double corner_radius;
@@ -139,6 +142,8 @@ struct backend_blit_args {
139142
bool color_inverted;
140143
};
141144

145+
static const vec2 SCALE_IDENTITY = {1.0, 1.0};
146+
142147
enum backend_image_format {
143148
/// A format that can be used for normal rendering, and binding
144149
/// X pixmaps.

src/backend/gl/blur.c

+11-11
Original file line numberDiff line numberDiff line change
@@ -344,18 +344,18 @@ bool gl_blur(struct backend_base *base, ivec2 origin, image_handle target_,
344344
}
345345

346346
// Original region for the final compositing step from blur result to target.
347-
auto coord = ccalloc(nrects * 16, GLint);
347+
auto coord = ccalloc(nrects * 16, GLfloat);
348348
auto indices = ccalloc(nrects * 6, GLuint);
349-
gl_mask_rects_to_coords(origin, nrects, rects, coord, indices);
349+
gl_mask_rects_to_coords(origin, nrects, rects, SCALE_IDENTITY, coord, indices);
350350
if (!target->y_inverted) {
351351
gl_y_flip_target(nrects, coord, target->height);
352352
}
353353

354354
// Resize region for sampling from source texture, and for blur passes
355-
auto coord_resized = ccalloc(nrects_resized * 16, GLint);
355+
auto coord_resized = ccalloc(nrects_resized * 16, GLfloat);
356356
auto indices_resized = ccalloc(nrects_resized * 6, GLuint);
357-
gl_mask_rects_to_coords(origin, nrects_resized, rects_resized, coord_resized,
358-
indices_resized);
357+
gl_mask_rects_to_coords(origin, nrects_resized, rects_resized, SCALE_IDENTITY,
358+
coord_resized, indices_resized);
359359
pixman_region32_fini(&reg_blur_resized);
360360
// FIXME(yshui) In theory we should handle blurring a non-y-inverted source, but
361361
// we never actually use that capability anywhere.
@@ -375,9 +375,9 @@ bool gl_blur(struct backend_base *base, ivec2 origin, image_handle target_,
375375
indices, GL_STREAM_DRAW);
376376
glEnableVertexAttribArray(vert_coord_loc);
377377
glEnableVertexAttribArray(vert_in_texcoord_loc);
378-
glVertexAttribPointer(vert_coord_loc, 2, GL_INT, GL_FALSE, sizeof(GLint) * 4, NULL);
379-
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_INT, GL_FALSE,
380-
sizeof(GLint) * 4, (void *)(sizeof(GLint) * 2));
378+
glVertexAttribPointer(vert_coord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, NULL);
379+
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_FLOAT, GL_FALSE,
380+
sizeof(GLfloat) * 4, (void *)(sizeof(GLfloat) * 2));
381381

382382
glBindVertexArray(vao[1]);
383383
glBindBuffer(GL_ARRAY_BUFFER, bo[2]);
@@ -389,9 +389,9 @@ bool gl_blur(struct backend_base *base, ivec2 origin, image_handle target_,
389389
GL_STREAM_DRAW);
390390
glEnableVertexAttribArray(vert_coord_loc);
391391
glEnableVertexAttribArray(vert_in_texcoord_loc);
392-
glVertexAttribPointer(vert_coord_loc, 2, GL_INT, GL_FALSE, sizeof(GLint) * 4, NULL);
393-
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_INT, GL_FALSE,
394-
sizeof(GLint) * 4, (void *)(sizeof(GLint) * 2));
392+
glVertexAttribPointer(vert_coord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, NULL);
393+
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_FLOAT, GL_FALSE,
394+
sizeof(GLfloat) * 4, (void *)(sizeof(GLfloat) * 2));
395395

396396
int vao_nelems[2] = {nrects * 6, nrects_resized * 6};
397397

src/backend/gl/gl_common.c

+53-41
Original file line numberDiff line numberDiff line change
@@ -366,10 +366,10 @@ struct gl_vertex_attribs_definition {
366366
};
367367

368368
static const struct gl_vertex_attribs_definition gl_blit_vertex_attribs = {
369-
.stride = sizeof(GLint) * 4,
369+
.stride = sizeof(GLfloat) * 4,
370370
.count = 2,
371-
.attribs = {{GL_INT, vert_coord_loc, NULL},
372-
{GL_INT, vert_in_texcoord_loc, ((GLint *)NULL) + 2}},
371+
.attribs = {{GL_FLOAT, vert_coord_loc, NULL},
372+
{GL_FLOAT, vert_in_texcoord_loc, ((GLfloat *)NULL) + 2}},
373373
};
374374

375375
/**
@@ -384,7 +384,7 @@ static const struct gl_vertex_attribs_definition gl_blit_vertex_attribs = {
384384
* @param nuniforms number of uniforms for `shader`
385385
* @param uniforms uniforms for `shader`
386386
*/
387-
static void gl_blit_inner(GLuint target_fbo, int nrects, GLint *coord, GLuint *indices,
387+
static void gl_blit_inner(GLuint target_fbo, int nrects, GLfloat *coord, GLuint *indices,
388388
const struct gl_vertex_attribs_definition *vert_attribs,
389389
const struct gl_shader *shader, int nuniforms,
390390
struct gl_uniform_value *uniforms) {
@@ -475,26 +475,29 @@ static void gl_blit_inner(GLuint target_fbo, int nrects, GLint *coord, GLuint *i
475475
gl_check_err();
476476
}
477477

478-
void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, GLint *coord,
479-
GLuint *indices) {
478+
void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, vec2 scale,
479+
GLfloat *coord, GLuint *indices) {
480480
for (ptrdiff_t i = 0; i < nrects; i++) {
481481
// Rectangle in source image coordinates
482482
rect_t rect_src = region_translate_rect(rects[i], ivec2_neg(origin));
483483
// Rectangle in target image coordinates
484484
rect_t rect_dst = rects[i];
485485

486+
// clang-format off
486487
memcpy(&coord[i * 16],
487-
((GLint[][2]){
488-
{rect_dst.x1, rect_dst.y1}, // Vertex, bottom-left
489-
{rect_src.x1, rect_src.y1}, // Texture
490-
{rect_dst.x2, rect_dst.y1}, // Vertex, bottom-right
491-
{rect_src.x2, rect_src.y1}, // Texture
492-
{rect_dst.x2, rect_dst.y2}, // Vertex, top-right
493-
{rect_src.x2, rect_src.y2}, // Texture
494-
{rect_dst.x1, rect_dst.y2}, // Vertex, top-left
495-
{rect_src.x1, rect_src.y2}, // Texture
488+
((GLfloat[][2]){
489+
// Interleaved vertex and texture coordinates, starting with vertex.
490+
{(GLfloat)rect_dst.x1, (GLfloat)rect_dst.y1}, // bottom-left
491+
{(GLfloat)(rect_src.x1 / scale.x), (GLfloat)(rect_src.y1 / scale.y)},
492+
{(GLfloat)rect_dst.x2, (GLfloat)rect_dst.y1}, // bottom-right
493+
{(GLfloat)(rect_src.x2 / scale.x), (GLfloat)(rect_src.y1 / scale.y)},
494+
{(GLfloat)rect_dst.x2, (GLfloat)rect_dst.y2}, // top-right
495+
{(GLfloat)(rect_src.x2 / scale.x), (GLfloat)(rect_src.y2 / scale.y)},
496+
{(GLfloat)rect_dst.x1, (GLfloat)rect_dst.y2}, // top-left
497+
{(GLfloat)(rect_src.x1 / scale.x), (GLfloat)(rect_src.y2 / scale.y)},
496498
}),
497499
sizeof(GLint[2]) * 8);
500+
// clang-format on
498501

499502
GLuint u = (GLuint)(i * 4);
500503
memcpy(&indices[i * 6],
@@ -509,13 +512,13 @@ void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, GLin
509512
/// @param[in] nrects number of rectangles
510513
/// @param[in] coord OpenGL vertex coordinates
511514
/// @param[in] texture_height height of the source image
512-
static inline void gl_y_flip_texture(int nrects, GLint *coord, GLint texture_height) {
515+
static inline void gl_y_flip_texture(int nrects, GLfloat *coord, GLint texture_height) {
513516
for (ptrdiff_t i = 0; i < nrects; i++) {
514517
auto current_rect = &coord[i * 16]; // 16 numbers per rectangle
515518
for (ptrdiff_t j = 0; j < 4; j++) {
516519
// 4 numbers per vertex, texture coordinates are the last two
517520
auto current_vertex = &current_rect[j * 4 + 2];
518-
current_vertex[1] = texture_height - current_vertex[1];
521+
current_vertex[1] = (GLfloat)texture_height - current_vertex[1];
519522
}
520523
}
521524
}
@@ -524,7 +527,7 @@ static inline void gl_y_flip_texture(int nrects, GLint *coord, GLint texture_hei
524527
/// shader, and uniforms.
525528
static int
526529
gl_lower_blit_args(struct gl_data *gd, ivec2 origin, const struct backend_blit_args *args,
527-
GLint **coord, GLuint **indices, struct gl_shader **shader,
530+
GLfloat **coord, GLuint **indices, struct gl_shader **shader,
528531
struct gl_uniform_value *uniforms) {
529532
auto img = (struct gl_texture *)args->source_image;
530533
int nrects;
@@ -534,9 +537,9 @@ gl_lower_blit_args(struct gl_data *gd, ivec2 origin, const struct backend_blit_a
534537
// Nothing to paint
535538
return 0;
536539
}
537-
*coord = ccalloc(nrects * 16, GLint);
540+
*coord = ccalloc(nrects * 16, GLfloat);
538541
*indices = ccalloc(nrects * 6, GLuint);
539-
gl_mask_rects_to_coords(origin, nrects, rects, *coord, *indices);
542+
gl_mask_rects_to_coords(origin, nrects, rects, args->scale, *coord, *indices);
540543
if (!img->y_inverted) {
541544
gl_y_flip_texture(nrects, *coord, img->height);
542545
}
@@ -558,11 +561,13 @@ gl_lower_blit_args(struct gl_data *gd, ivec2 origin, const struct backend_blit_a
558561
border_width = 0;
559562
}
560563
// clang-format off
564+
auto tex_sampler = vec2_eq(args->scale, SCALE_IDENTITY) ?
565+
gd->samplers[GL_SAMPLER_REPEAT] : gd->samplers[GL_SAMPLER_REPEAT_SCALE];
561566
struct gl_uniform_value from_uniforms[] = {
562567
[UNIFORM_OPACITY_LOC] = {.type = GL_FLOAT, .f = (float)args->opacity},
563568
[UNIFORM_INVERT_COLOR_LOC] = {.type = GL_INT, .i = args->color_inverted},
564569
[UNIFORM_TEX_LOC] = {.type = GL_TEXTURE_2D,
565-
.tu = {img->texture, gd->samplers[GL_SAMPLER_REPEAT]}},
570+
.tu = {img->texture, tex_sampler}},
566571
[UNIFORM_EFFECTIVE_SIZE_LOC] = {.type = GL_FLOAT_VEC2,
567572
.f2 = {(float)args->effective_size.width,
568573
(float)args->effective_size.height}},
@@ -613,7 +618,7 @@ bool gl_blit(backend_t *base, ivec2 origin, image_handle target_,
613618
return false;
614619
}
615620

616-
GLint *coord;
621+
GLfloat *coord;
617622
GLuint *indices;
618623
struct gl_shader *shader;
619624
struct gl_uniform_value uniforms[NUMBER_OF_UNIFORMS] = {};
@@ -678,9 +683,9 @@ static bool gl_copy_area_draw(struct gl_data *gd, ivec2 origin,
678683
return true;
679684
}
680685

681-
auto coord = ccalloc(16 * nrects, GLint);
686+
auto coord = ccalloc(16 * nrects, GLfloat);
682687
auto indices = ccalloc(6 * nrects, GLuint);
683-
gl_mask_rects_to_coords(origin, nrects, rects, coord, indices);
688+
gl_mask_rects_to_coords(origin, nrects, rects, SCALE_IDENTITY, coord, indices);
684689
if (!target->y_inverted) {
685690
gl_y_flip_target(nrects, coord, target->height);
686691
}
@@ -856,6 +861,17 @@ uint64_t gl_get_shader_attributes(backend_t *backend_data attr_unused, void *sha
856861
return ret;
857862
}
858863

864+
static const struct {
865+
GLint filter;
866+
GLint wrap;
867+
} gl_sampler_params[] = {
868+
[GL_SAMPLER_REPEAT] = {GL_NEAREST, GL_REPEAT},
869+
[GL_SAMPLER_REPEAT_SCALE] = {GL_LINEAR, GL_REPEAT},
870+
[GL_SAMPLER_BLUR] = {GL_LINEAR, GL_CLAMP_TO_EDGE},
871+
[GL_SAMPLER_EDGE] = {GL_NEAREST, GL_CLAMP_TO_EDGE},
872+
[GL_SAMPLER_BORDER] = {GL_NEAREST, GL_CLAMP_TO_BORDER},
873+
};
874+
859875
bool gl_init(struct gl_data *gd, session_t *ps) {
860876
if (!epoxy_has_gl_extension("GL_ARB_explicit_uniform_location")) {
861877
log_error("GL_ARB_explicit_uniform_location support is required but "
@@ -965,20 +981,16 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
965981
gd->back_image.height = ps->root_height;
966982

967983
glGenSamplers(GL_MAX_SAMPLERS, gd->samplers);
968-
for (int i = 0; i < GL_MAX_SAMPLERS; i++) {
969-
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
970-
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
971-
}
972-
glSamplerParameterf(gd->samplers[GL_SAMPLER_EDGE], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
973-
glSamplerParameterf(gd->samplers[GL_SAMPLER_EDGE], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
974-
glSamplerParameterf(gd->samplers[GL_SAMPLER_BLUR], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
975-
glSamplerParameterf(gd->samplers[GL_SAMPLER_BLUR], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
976-
glSamplerParameterf(gd->samplers[GL_SAMPLER_BLUR], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
977-
glSamplerParameterf(gd->samplers[GL_SAMPLER_BLUR], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
978-
glSamplerParameterf(gd->samplers[GL_SAMPLER_BORDER], GL_TEXTURE_WRAP_S,
979-
GL_CLAMP_TO_BORDER);
980-
glSamplerParameterf(gd->samplers[GL_SAMPLER_BORDER], GL_TEXTURE_WRAP_T,
981-
GL_CLAMP_TO_BORDER);
984+
for (size_t i = 0; i < ARR_SIZE(gl_sampler_params); i++) {
985+
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_MIN_FILTER,
986+
gl_sampler_params[i].filter);
987+
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_MAG_FILTER,
988+
gl_sampler_params[i].filter);
989+
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_WRAP_S,
990+
gl_sampler_params[i].wrap);
991+
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_WRAP_T,
992+
gl_sampler_params[i].wrap);
993+
}
982994

983995
gd->logger = gl_string_marker_logger_new();
984996
if (gd->logger) {
@@ -1100,9 +1112,9 @@ image_handle gl_new_image(backend_t *backend_data attr_unused,
11001112
bool gl_apply_alpha(backend_t *base, image_handle target, double alpha, const region_t *reg_op) {
11011113
auto gd = (struct gl_data *)base;
11021114
static const struct gl_vertex_attribs_definition vertex_attribs = {
1103-
.stride = sizeof(GLint) * 4,
1115+
.stride = sizeof(GLfloat) * 4,
11041116
.count = 1,
1105-
.attribs = {{GL_INT, vert_coord_loc, NULL}},
1117+
.attribs = {{GL_FLOAT, vert_coord_loc, NULL}},
11061118
};
11071119
if (alpha == 1.0 || !pixman_region32_not_empty(reg_op)) {
11081120
return true;
@@ -1115,7 +1127,7 @@ bool gl_apply_alpha(backend_t *base, image_handle target, double alpha, const re
11151127
int nrects;
11161128
const rect_t *rect = pixman_region32_rectangles(reg_op, &nrects);
11171129

1118-
auto coord = ccalloc(nrects * 16, GLint);
1130+
auto coord = ccalloc(nrects * 16, GLfloat);
11191131
auto indices = ccalloc(nrects * 6, GLuint);
11201132

11211133
struct gl_uniform_value uniforms[] = {

src/backend/gl/gl_common.h

+11-8
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ struct gl_texture {
6666
};
6767

6868
enum gl_sampler {
69+
/// A sampler that repeats the texture, with nearest filtering.
6970
GL_SAMPLER_REPEAT = 0,
71+
/// A sampler that repeats the texture, with linear filtering.
72+
GL_SAMPLER_REPEAT_SCALE,
7073
/// Clamp to edge
7174
GL_SAMPLER_EDGE,
7275
/// Clamp to border, border color will be (0, 0, 0, 0)
@@ -126,13 +129,13 @@ void gl_prepare(backend_t *base, const region_t *reg);
126129
/// @param[in] rects mask rectangles, in mask coordinates
127130
/// @param[out] coord OpenGL vertex coordinates, suitable for creating VAO/VBO
128131
/// @param[out] indices OpenGL vertex indices, suitable for creating VAO/VBO
129-
void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, GLint *coord,
130-
GLuint *indices);
131-
/// Like `gl_mask_rects_to_coords`, but with `origin` and `mask_origin` set to 0. i.e. all
132-
/// coordinates are in the same space.
132+
void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, vec2 scale,
133+
GLfloat *coord, GLuint *indices);
134+
/// Like `gl_mask_rects_to_coords`, but with `origin` is (0, 0).
133135
static inline void gl_mask_rects_to_coords_simple(int nrects, const rect_t *rects,
134-
GLint *coord, GLuint *indices) {
135-
return gl_mask_rects_to_coords((ivec2){0, 0}, nrects, rects, coord, indices);
136+
GLfloat *coord, GLuint *indices) {
137+
return gl_mask_rects_to_coords((ivec2){0, 0}, nrects, rects, SCALE_IDENTITY,
138+
coord, indices);
136139
}
137140

138141
GLuint gl_create_shader(GLenum shader_type, const char *shader_str);
@@ -210,13 +213,13 @@ static inline GLuint gl_bind_image_to_fbo(struct gl_data *gd, image_handle image
210213
/// @param[in] nrects number of rectangles
211214
/// @param[in] coord OpenGL vertex coordinates
212215
/// @param[in] target_height height of the target image
213-
static inline void gl_y_flip_target(int nrects, GLint *coord, GLint target_height) {
216+
static inline void gl_y_flip_target(int nrects, GLfloat *coord, GLint target_height) {
214217
for (ptrdiff_t i = 0; i < nrects; i++) {
215218
auto current_rect = &coord[i * 16]; // 16 numbers per rectangle
216219
for (ptrdiff_t j = 0; j < 4; j++) {
217220
// 4 numbers per vertex, target coordinates are the first two
218221
auto current_vertex = &current_rect[j * 4];
219-
current_vertex[1] = target_height - current_vertex[1];
222+
current_vertex[1] = (GLfloat)target_height - current_vertex[1];
220223
}
221224
}
222225
}

src/backend/xrender/xrender.c

+17
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ struct xrender_rounded_rectangle_cache {
103103
int radius;
104104
};
105105

106+
static void
107+
set_picture_scale(struct x_connection *c, xcb_render_picture_t picture, vec2 scale) {
108+
xcb_render_transform_t transform = {
109+
.matrix11 = DOUBLE_TO_XFIXED(1.0 / scale.x),
110+
.matrix22 = DOUBLE_TO_XFIXED(1.0 / scale.y),
111+
.matrix33 = DOUBLE_TO_XFIXED(1.0),
112+
};
113+
set_cant_fail_cookie(c, xcb_render_set_picture_transform(c->c, picture, transform));
114+
}
115+
106116
/// Make a picture of size width x height, which has a rounded rectangle of corner_radius
107117
/// rendered in it.
108118
struct xrender_rounded_rectangle_cache *
@@ -316,6 +326,9 @@ static bool xrender_blit(struct backend_base *base, ivec2 origin,
316326
inner->size.height, (int)args->corner_radius);
317327
}
318328
}
329+
330+
set_picture_scale(xd->base.c, mask_pict, args->scale);
331+
319332
if (((args->color_inverted || args->dim != 0) && has_alpha) ||
320333
args->corner_radius != 0) {
321334
// Apply image properties using a temporary image, because the source
@@ -384,6 +397,8 @@ static bool xrender_blit(struct backend_base *base, ivec2 origin,
384397
tmp_pict, 0, 0, 0, 0, 0, 0, tmpw, tmph);
385398
}
386399

400+
set_picture_scale(xd->base.c, tmp_pict, args->scale);
401+
387402
xcb_render_composite(xd->base.c->c, XCB_RENDER_PICT_OP_OVER, tmp_pict,
388403
mask_pict, target->pict, 0, 0, mask_pict_dst_x,
389404
mask_pict_dst_y, to_i16_checked(origin.x),
@@ -392,6 +407,8 @@ static bool xrender_blit(struct backend_base *base, ivec2 origin,
392407
} else {
393408
uint8_t op = (has_alpha ? XCB_RENDER_PICT_OP_OVER : XCB_RENDER_PICT_OP_SRC);
394409

410+
set_picture_scale(xd->base.c, inner->pict, args->scale);
411+
395412
xcb_render_composite(xd->base.c->c, op, inner->pict, mask_pict,
396413
target->pict, 0, 0, mask_pict_dst_x, mask_pict_dst_y,
397414
to_i16_checked(origin.x), to_i16_checked(origin.y),

src/common.h

-2
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ typedef struct session {
150150
ev_io xiow;
151151
/// Timeout for delayed unredirection.
152152
ev_timer unredir_timer;
153-
/// Timer for fading
154-
ev_timer fade_timer;
155153
/// Use an ev_timer callback for drawing
156154
ev_timer draw_timer;
157155
/// Called every time we have timeouts or new data on socket,

src/config.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -523,9 +523,10 @@ const char *vblank_scheduler_str[] = {
523523
[LAST_VBLANK_SCHEDULER] = NULL
524524
};
525525
static const struct debug_options_entry debug_options_entries[] = {
526-
{"always_rebind_pixmap", NULL , offsetof(struct debug_options, always_rebind_pixmap)},
527-
{"smart_frame_pacing" , NULL , offsetof(struct debug_options, smart_frame_pacing)},
528-
{"force_vblank_sched" , vblank_scheduler_str, offsetof(struct debug_options, force_vblank_scheduler)},
526+
{"always_rebind_pixmap" , NULL , offsetof(struct debug_options, always_rebind_pixmap)},
527+
{"smart_frame_pacing" , NULL , offsetof(struct debug_options, smart_frame_pacing)},
528+
{"force_vblank_sched" , vblank_scheduler_str, offsetof(struct debug_options, force_vblank_scheduler)},
529+
{"consistent_buffer_age", NULL , offsetof(struct debug_options, consistent_buffer_age)},
529530
};
530531
// clang-format on
531532

0 commit comments

Comments
 (0)