Compare commits

...

11 Commits

Author SHA1 Message Date
Morgoth 3bad7a00c6
Merge 20aac430a5 into 2052bc70c3 2024-05-01 15:52:17 +02:00
Maxim Solovyov 2052bc70c3
Merge pull request #1245 from absolutelynothelix/stderr-logger
inspect: don't create and add an stderr logger in inspect_main
2024-04-29 17:31:11 +03:00
Maxim Solovyov 7680091c51
inspect: don't create and add an stderr logger in inspect_main
it's already created and added in the PICOM_MAIN function.

this fixes some messages being printed twice when using picom-inspect.
2024-04-29 17:26:28 +03:00
Maxim Solovyov af27c384ad
Merge pull request #1246 from absolutelynothelix/opengl-max-depth
common: remove OPENGL_MAX_DEPTH and it's uses
2024-04-29 17:23:13 +03:00
Maxim Solovyov fa42eac7a5
common: remove OPENGL_MAX_DEPTH and it's uses
scientists haven't proven the existence of depths greater than 32 yet.
2024-04-29 17:17:59 +03:00
Yuxuan Shui d6e3335cfd
string_utils: strtod_simple should not succeed if no number is parsed
So things like "+.", ".", "+", etc. will no longer parse successfully.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2024-04-28 18:24:07 +01:00
Yuxuan Shui c5e58da1ba
unittest: use test.h setup hook to setup logging
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2024-04-28 18:23:41 +01:00
Yuxuan Shui e5e618fb50
renderer: fix handling of root pixmap changes
I thought to myself, "I will add this later", then proceeded to forget
about this...

The `root_damaged` flag in `struct session` I added in anticipation for
this is actually not enough. Imagine this:

frame 0 -> frame 1 -> frame 2 (root changed) -> frame 3

frame 2 will be rendered with the `root_damaged` flag set, all good.
But `frame 3` wouldn't, and if it has buffer age 2, i.e. it's rendered
on top of the base of `frame 1`, then the result will be wrong because
frame 1 and 3 has different root background. So instead I added a
`root_image_generation` that is incremented every time the root image
changes.

Fixes #1247

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2024-04-28 13:17:12 +01:00
Yuxuan Shui 09b58035f4
renderer/layout: remove unused code
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2024-04-28 13:02:15 +01:00
Yuxuan Shui 4aa283df98
renderer: move monitor repaint init to its own function
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2024-04-28 12:48:26 +01:00
Marcin Kurek 20aac430a5 For some reason NVIDIA drivers do not re-enable vsync once it's disabled on my system 2019-06-01 11:41:34 +02:00
12 changed files with 62 additions and 71 deletions

View File

@ -371,12 +371,6 @@ static image_handle
glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt) {
GLXPixmap *glxpixmap = NULL;
auto gd = (struct _glx_data *)base;
// Retrieve pixmap parameters, if they aren't provided
if (fmt.visual_depth > OPENGL_MAX_DEPTH) {
log_error("Requested depth %d higher than max possible depth %d.",
fmt.visual_depth, OPENGL_MAX_DEPTH);
return NULL;
}
if (fmt.visual_depth < 0) {
log_error("Pixmap %#010x with invalid depth %d", pixmap, fmt.visual_depth);

View File

@ -416,9 +416,6 @@ c2_lptr_t *c2_parse(c2_lptr_t **pcondlst, const char *pattern, void *data) {
}
TEST_CASE(c2_parse) {
log_init_tls();
// log_add_target_tls(stderr_logger_new());
char str[1024];
c2_lptr_t *cond = c2_parse(NULL, "name = \"xterm\"", NULL);
struct atom *atoms = init_mock_atoms();

View File

@ -70,9 +70,6 @@
#define US_PER_SEC 1000000L
#define MS_PER_SEC 1000
/// @brief Maximum OpenGL FBConfig depth.
#define OPENGL_MAX_DEPTH 32
/// @brief Maximum OpenGL buffer age.
#define CGLX_MAX_BUFFER_AGE 5
@ -199,6 +196,9 @@ typedef struct session {
paint_t root_tile_paint;
/// The backend data the root pixmap bound to
image_handle root_image;
/// The root pixmap generation, incremented everytime
/// the root pixmap changes
uint64_t root_image_generation;
/// A region of the size of the screen.
region_t screen_reg;
/// Picture of root window. Destination of painting in no-DBE painting
@ -271,8 +271,6 @@ typedef struct session {
/// Render command builder
struct command_builder *command_builder;
struct renderer *renderer;
/// Whether the root image has been changed since last render
bool root_damaged;
/// Whether all windows are currently redirected.
bool redirected;
/// Pre-generated alpha pictures.

View File

@ -161,11 +161,6 @@ bool c2_match_once_and_log(const c2_lptr_t *cond, void *data) {
#define BOLD(str) "\033[1m" str "\033[0m"
int inspect_main(int argc, char **argv, const char *config_file) {
auto stderr_logger = stderr_logger_new();
if (stderr_logger) {
log_add_target_tls(stderr_logger);
}
Display *dpy = XOpenDisplay(NULL);
if (!dpy) {
log_fatal("Can't open display");

View File

@ -746,11 +746,6 @@ bool glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap,
log_error("Failed to query info of pixmap %#010x.", pixmap);
return false;
}
if (r->depth > OPENGL_MAX_DEPTH) {
log_error("Requested depth %d higher than %d.", depth,
OPENGL_MAX_DEPTH);
return false;
}
depth = r->depth;
width = r->width;
height = r->height;

View File

@ -1189,12 +1189,12 @@ void root_damaged(session_t *ps) {
ps->root_image = ps->backend_data->ops->v2.bind_pixmap(
ps->backend_data, pixmap, x_get_visual_info(&ps->c, visual));
ps->root_image_generation += 1;
if (!ps->root_image) {
err:
log_error("Failed to bind root back pixmap");
}
}
ps->root_damaged = true;
}
// Mark screen damaged
@ -1846,7 +1846,7 @@ static void draw_callback_impl(EV_P_ session_t *ps, int revents attr_unused) {
auto render_start_us =
(uint64_t)now.tv_sec * 1000000UL + (uint64_t)now.tv_nsec / 1000;
layout_manager_append_layout(
ps->layout_manager, ps->wm,
ps->layout_manager, ps->wm, ps->root_image_generation,
(struct geometry){.width = ps->root_width,
.height = ps->root_height});
bool succeeded = renderer_render(
@ -2888,3 +2888,11 @@ int PICOM_MAIN(int argc, char **argv) {
return ret_code;
}
#ifdef UNIT_TEST
static void unittest_setup(void) {
log_init_tls();
// log_add_target_tls(stderr_logger_new());
}
void (*test_h_unittest_setup)(void) = unittest_setup;
#endif

View File

@ -147,9 +147,8 @@ void layout_manager_damage(struct layout_manager *lm, unsigned buffer_age,
pixman_region32_init(&scratch_region);
pixman_region32_clear(damage);
if (past_layout->size.width != curr_layout->size.width ||
past_layout->size.height != curr_layout->size.height) {
// We might be able to do better for blur size change, but currently we
// don't even support changing that.
past_layout->size.height != curr_layout->size.height ||
past_layout->root_image_generation != curr_layout->root_image_generation) {
pixman_region32_union_rect(damage, damage, 0, 0,
(unsigned)curr_layout->size.width,
(unsigned)curr_layout->size.height);

View File

@ -26,9 +26,6 @@ struct layout_manager {
unsigned current;
/// Mapping from window to its index in the current layout.
struct layer_index *layer_indices;
/// Output render plan.
struct render_plan *plan;
unsigned plan_capacity;
struct list_node free_indices;
// internal
@ -110,8 +107,6 @@ struct layout_manager *layout_manager_new(unsigned max_buffer_age) {
planner->max_buffer_age = max_buffer_age + 1;
planner->current = 0;
planner->layer_indices = NULL;
planner->plan_capacity = 0;
planner->plan = NULL;
list_init_head(&planner->free_indices);
pixman_region32_init(&planner->scratch_region);
for (unsigned i = 0; i <= max_buffer_age; i++) {
@ -133,11 +128,7 @@ void layout_manager_free(struct layout_manager *lm) {
list_remove(&i->free_list);
free(i);
}
for (unsigned i = 0; i < lm->plan_capacity; i++) {
pixman_region32_fini(&lm->plan[i].render);
}
pixman_region32_fini(&lm->scratch_region);
free(lm->plan);
free(lm);
}
@ -152,11 +143,13 @@ void layout_manager_free(struct layout_manager *lm) {
// above.
void layout_manager_append_layout(struct layout_manager *lm, struct wm *wm,
struct geometry size) {
uint64_t root_pixmap_generation, struct geometry size) {
auto prev_layout = &lm->layouts[lm->current];
lm->current = (lm->current + 1) % lm->max_buffer_age;
auto layout = &lm->layouts[lm->current];
command_builder_command_list_free(layout->commands);
layout->root_image_generation = root_pixmap_generation;
unsigned nlayers = wm_stack_num_managed_windows(wm);
if (nlayers > layout->capacity) {
struct layer *new_layers =

View File

@ -71,6 +71,8 @@ struct layer {
/// Layout of windows at a specific frame
struct layout {
struct geometry size;
/// The root image generation, see `struct session::root_image_generation`
uint64_t root_image_generation;
/// Number of layers in `layers`
unsigned len;
/// Capacity of `layers`
@ -88,11 +90,6 @@ struct layout {
struct backend_command *commands;
};
struct render_plan {
region_t render;
const struct layer *layer;
};
struct wm;
struct layout_manager;
@ -101,7 +98,7 @@ struct layout_manager;
/// layouts, with its size chosen at creation time. Calling this will push at new layout
/// at the end of the ring buffer, and remove the oldest layout if the buffer is full.
void layout_manager_append_layout(struct layout_manager *lm, struct wm *wm,
struct geometry size);
uint64_t root_image_generation, struct geometry size);
/// Get the layout `age` frames into the past. Age `0` is the most recently appended
/// layout.
struct layout *layout_manager_layout(struct layout_manager *lm, unsigned age);

View File

@ -421,6 +421,32 @@ static bool renderer_prepare_commands(struct renderer *r, struct backend_base *b
return true;
}
void renderer_ensure_monitor_repaint_ready(struct renderer *r, struct backend_base *backend) {
if (!r->monitor_repaint_pixel) {
r->monitor_repaint_pixel = backend->ops->v2.new_image(
backend, BACKEND_IMAGE_FORMAT_PIXMAP, (struct geometry){1, 1});
BUG_ON(!r->monitor_repaint_pixel);
backend->ops->v2.clear(backend, r->monitor_repaint_pixel,
(struct color){.alpha = 0.5, .red = 0.5});
}
if (!r->monitor_repaint_copy) {
r->monitor_repaint_copy = ccalloc(r->max_buffer_age, image_handle);
for (int i = 0; i < r->max_buffer_age; i++) {
r->monitor_repaint_copy[i] = backend->ops->v2.new_image(
backend, BACKEND_IMAGE_FORMAT_PIXMAP,
(struct geometry){.width = r->canvas_size.width,
.height = r->canvas_size.height});
BUG_ON(!r->monitor_repaint_copy[i]);
}
}
if (!r->monitor_repaint_region) {
r->monitor_repaint_region = ccalloc(r->max_buffer_age, region_t);
for (int i = 0; i < r->max_buffer_age; i++) {
pixman_region32_init(&r->monitor_repaint_region[i]);
}
}
}
/// @return true if a frame is rendered, false if this frame is skipped.
bool renderer_render(struct renderer *r, struct backend_base *backend,
image_handle root_image, struct layout_manager *lm,
@ -448,29 +474,7 @@ bool renderer_render(struct renderer *r, struct backend_base *backend,
}
if (monitor_repaint) {
if (!r->monitor_repaint_pixel) {
r->monitor_repaint_pixel = backend->ops->v2.new_image(
backend, BACKEND_IMAGE_FORMAT_PIXMAP, (struct geometry){1, 1});
BUG_ON(!r->monitor_repaint_pixel);
backend->ops->v2.clear(backend, r->monitor_repaint_pixel,
(struct color){.alpha = 0.5, .red = 0.5});
}
if (!r->monitor_repaint_copy) {
r->monitor_repaint_copy = ccalloc(r->max_buffer_age, image_handle);
for (int i = 0; i < r->max_buffer_age; i++) {
r->monitor_repaint_copy[i] = backend->ops->v2.new_image(
backend, BACKEND_IMAGE_FORMAT_PIXMAP,
(struct geometry){.width = r->canvas_size.width,
.height = r->canvas_size.height});
BUG_ON(!r->monitor_repaint_copy[i]);
}
}
if (!r->monitor_repaint_region) {
r->monitor_repaint_region = ccalloc(r->max_buffer_age, region_t);
for (int i = 0; i < r->max_buffer_age; i++) {
pixman_region32_init(&r->monitor_repaint_region[i]);
}
}
renderer_ensure_monitor_repaint_ready(r, backend);
}
command_builder_build(cb, layout, force_blend, blur_frame, inactive_dim_fixed,

View File

@ -85,6 +85,8 @@ TEST_CASE(mstrextend) {
/// Parse a floating point number of form (+|-)?[0-9]*(\.[0-9]*)
double strtod_simple(const char *src, const char **end) {
double neg = 1;
bool succeeded = false;
*end = src;
if (*src == '-') {
neg = -1;
src++;
@ -95,6 +97,7 @@ double strtod_simple(const char *src, const char **end) {
double ret = 0;
while (*src >= '0' && *src <= '9') {
ret = ret * 10 + (*src - '0');
succeeded = true;
src++;
}
@ -104,13 +107,17 @@ double strtod_simple(const char *src, const char **end) {
while (*src >= '0' && *src <= '9') {
frac += mult * (*src - '0');
mult *= 0.1;
succeeded = true;
src++;
}
ret += frac;
}
*end = src;
return ret * neg;
if (succeeded) {
*end = src;
return ret * neg;
}
return NAN;
}
TEST_CASE(strtod_simple) {
@ -126,6 +133,10 @@ TEST_CASE(strtod_simple) {
result = strtod_simple("+.5", &end);
TEST_EQUAL(result, 0.5);
TEST_EQUAL(*end, '\0');
result = strtod_simple("+.", &end);
TEST_TRUE(safe_isnan(result));
TEST_EQUAL(*end, '+');
}
const char *trim_both(const char *src, size_t *length) {

View File

@ -155,7 +155,7 @@ static int vsync_opengl_oml_wait(session_t *ps) {
*/
bool vsync_init(session_t *ps) {
#ifdef CONFIG_OPENGL
if (bkend_use_glx(ps)) {
if (bkend_use_glx(ps) && !(ps->drivers & DRIVER_NVIDIA)) {
// Mesa turns on swap control by default, undo that
vsync_opengl_swc_swap_interval(ps, 0);
}