mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
terminal/grdev: provide front and back buffer to renderers
We really want more sophisticated aging than just 64bit integers. So always provide front *and* back buffers to renderers so they can compare arbitrary aging information and decide whether to re-render.
This commit is contained in:
parent
aec3f44651
commit
51cff8bded
@ -343,7 +343,7 @@ void grdev_display_disable(grdev_display *display) {
|
||||
}
|
||||
}
|
||||
|
||||
const grdev_display_target *grdev_display_next_target(grdev_display *display, const grdev_display_target *prev, uint64_t minage) {
|
||||
const grdev_display_target *grdev_display_next_target(grdev_display *display, const grdev_display_target *prev) {
|
||||
grdev_display_cache *cache;
|
||||
size_t idx;
|
||||
|
||||
@ -374,26 +374,19 @@ const grdev_display_target *grdev_display_next_target(grdev_display *display, co
|
||||
if (!pipe->running || !pipe->enabled)
|
||||
continue;
|
||||
|
||||
/* if front-buffer is up-to-date, there's nothing to do */
|
||||
if (minage > 0 && pipe->front && pipe->front->age >= minage)
|
||||
continue;
|
||||
|
||||
/* find suitable back-buffer */
|
||||
if (!(fb = pipe->back)) {
|
||||
if (!pipe->vtable->target || !(fb = pipe->vtable->target(pipe)))
|
||||
if (!pipe->back) {
|
||||
if (!pipe->vtable->target)
|
||||
continue;
|
||||
if (!(fb = pipe->vtable->target(pipe)))
|
||||
continue;
|
||||
|
||||
assert(fb == pipe->back);
|
||||
}
|
||||
|
||||
/* if back-buffer is up-to-date, schedule flip */
|
||||
if (minage > 0 && fb->age >= minage) {
|
||||
grdev_display_flip_target(display, target, fb->age);
|
||||
continue;
|
||||
}
|
||||
target->front = pipe->front;
|
||||
target->back = pipe->back;
|
||||
|
||||
/* we have an out-of-date back-buffer; return for redraw */
|
||||
target->fb = fb;
|
||||
return target;
|
||||
}
|
||||
|
||||
@ -408,7 +401,7 @@ void grdev_display_flip_target(grdev_display *display, const grdev_display_targe
|
||||
assert(!display->modified);
|
||||
assert(display->enabled);
|
||||
assert(target);
|
||||
assert(target->fb);
|
||||
assert(target->back);
|
||||
|
||||
cache = container_of(target, grdev_display_cache, target);
|
||||
|
||||
@ -416,12 +409,12 @@ void grdev_display_flip_target(grdev_display *display, const grdev_display_targe
|
||||
assert(cache->pipe->tile->display == display);
|
||||
|
||||
/* reset age of all FB on overflow */
|
||||
if (age < target->fb->age)
|
||||
if (age < target->back->age)
|
||||
for (i = 0; i < cache->pipe->max_fbs; ++i)
|
||||
if (cache->pipe->fbs[i])
|
||||
cache->pipe->fbs[i]->age = 0;
|
||||
|
||||
((grdev_fb*)target->fb)->age = age;
|
||||
((grdev_fb*)target->back)->age = age;
|
||||
cache->pipe->flip = true;
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,8 @@ struct grdev_display_target {
|
||||
uint32_t height;
|
||||
unsigned int rotate;
|
||||
unsigned int flip;
|
||||
const grdev_fb *fb;
|
||||
const grdev_fb *front;
|
||||
const grdev_fb *back;
|
||||
};
|
||||
|
||||
void grdev_display_set_userdata(grdev_display *display, void *userdata);
|
||||
@ -119,13 +120,13 @@ bool grdev_display_is_enabled(grdev_display *display);
|
||||
void grdev_display_enable(grdev_display *display);
|
||||
void grdev_display_disable(grdev_display *display);
|
||||
|
||||
const grdev_display_target *grdev_display_next_target(grdev_display *display, const grdev_display_target *prev, uint64_t minage);
|
||||
const grdev_display_target *grdev_display_next_target(grdev_display *display, const grdev_display_target *prev);
|
||||
void grdev_display_flip_target(grdev_display *display, const grdev_display_target *target, uint64_t age);
|
||||
|
||||
#define GRDEV_DISPLAY_FOREACH_TARGET(_display, _t, _minage) \
|
||||
for ((_t) = grdev_display_next_target((_display), NULL, (_minage)); \
|
||||
(_t); \
|
||||
(_t) = grdev_display_next_target((_display), (_t), (_minage)))
|
||||
#define GRDEV_DISPLAY_FOREACH_TARGET(_display, _t) \
|
||||
for ((_t) = grdev_display_next_target((_display), NULL); \
|
||||
(_t); \
|
||||
(_t) = grdev_display_next_target((_display), (_t)))
|
||||
|
||||
/*
|
||||
* Events
|
||||
|
@ -234,18 +234,18 @@ static void modeset_draw(Modeset *m, const grdev_display_target *t) {
|
||||
uint32_t j, k, *b;
|
||||
uint8_t *l;
|
||||
|
||||
assert(t->fb->format == DRM_FORMAT_XRGB8888 || t->fb->format == DRM_FORMAT_ARGB8888);
|
||||
assert(t->back->format == DRM_FORMAT_XRGB8888 || t->back->format == DRM_FORMAT_ARGB8888);
|
||||
assert(!t->rotate);
|
||||
assert(!t->flip);
|
||||
|
||||
l = t->fb->maps[0];
|
||||
l = t->back->maps[0];
|
||||
for (j = 0; j < t->height; ++j) {
|
||||
for (k = 0; k < t->width; ++k) {
|
||||
b = (uint32_t*)l;
|
||||
b[k] = (0xff << 24) | (m->r << 16) | (m->g << 8) | m->b;
|
||||
}
|
||||
|
||||
l += t->fb->strides[0];
|
||||
l += t->back->strides[0];
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ static void modeset_render(Modeset *m, grdev_display *d) {
|
||||
m->g = next_color(&m->g_up, m->g, 3);
|
||||
m->b = next_color(&m->b_up, m->b, 2);
|
||||
|
||||
GRDEV_DISPLAY_FOREACH_TARGET(d, t, 0) {
|
||||
GRDEV_DISPLAY_FOREACH_TARGET(d, t) {
|
||||
modeset_draw(m, t);
|
||||
grdev_display_flip_target(d, t, 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user