Merge 'Drop redundant manual popup compositing' from origin/master
This commit is contained in:
commit
a86a21d76e
1 changed files with 5 additions and 77 deletions
|
|
@ -151,7 +151,6 @@ struct tabbed_host {
|
||||||
GLuint gl_program;
|
GLuint gl_program;
|
||||||
GLint gl_pos_loc, gl_uv_loc, gl_tex_loc;
|
GLint gl_pos_loc, gl_uv_loc, gl_tex_loc;
|
||||||
GLuint import_tex;
|
GLuint import_tex;
|
||||||
GLuint popup_tex;
|
|
||||||
/* Present gating: at most one buffer aimed at the host compositor at a
|
/* Present gating: at most one buffer aimed at the host compositor at a
|
||||||
time, paced by the host surface's wl_callback. */
|
time, paced by the host surface's wl_callback. */
|
||||||
struct wl_callback *frame_cb;
|
struct wl_callback *frame_cb;
|
||||||
|
|
@ -442,14 +441,6 @@ static bool gl_setup(void) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
glGenTextures(1, &host.popup_tex);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, host.popup_tex);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -907,17 +898,11 @@ static int app_index(struct tabbed_app *app) {
|
||||||
struct tabbed_popup {
|
struct tabbed_popup {
|
||||||
struct wlr_xdg_surface *xdg_surface;
|
struct wlr_xdg_surface *xdg_surface;
|
||||||
struct wlr_scene_tree *scene;
|
struct wlr_scene_tree *scene;
|
||||||
struct wl_list link;
|
|
||||||
struct wl_listener commit;
|
struct wl_listener commit;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener reposition;
|
struct wl_listener reposition;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Popups are also drawn by us (host-side) for the presented frame, because
|
|
||||||
wlroots' own premultiplied-alpha rendering of these ARGB menus produces
|
|
||||||
nothing in this nested EGL pipeline. This list tracks the live ones. */
|
|
||||||
static struct wl_list popups = { &popups, &popups };
|
|
||||||
|
|
||||||
/* Enough of the host window for popups to be positioned within; open menus
|
/* Enough of the host window for popups to be positioned within; open menus
|
||||||
may exceed the toplevel but we keep them inside the visible area. */
|
may exceed the toplevel but we keep them inside the visible area. */
|
||||||
static void popup_usable_box(struct wlr_box *box) {
|
static void popup_usable_box(struct wlr_box *box) {
|
||||||
|
|
@ -932,10 +917,11 @@ static void popup_usable_box(struct wlr_box *box) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Menu popups (e.g. galculator's) submit ARGB buffers that wlroots renders
|
/* Popups (menus, tooltips) are regular wlr_scene_xdg_surface nodes under
|
||||||
with premultiplied-alpha blending, which produces nothing in this nested
|
their parent's tree, so wlroots' scene renderer composites them into the
|
||||||
EGL pipeline. We therefore draw them ourselves into the presented frame
|
output buffer like any other surface. We only need to make sure the client
|
||||||
(see composite_popups in blit_scene_buffer). */
|
gets its initial configure (unconstrain from the output box) and to place
|
||||||
|
each popup under its parent's tree. */
|
||||||
static void popup_handle_commit(struct wl_listener *listener, void *data) {
|
static void popup_handle_commit(struct wl_listener *listener, void *data) {
|
||||||
(void)data;
|
(void)data;
|
||||||
struct tabbed_popup *tp = wl_container_of(listener, tp, commit);
|
struct tabbed_popup *tp = wl_container_of(listener, tp, commit);
|
||||||
|
|
@ -964,7 +950,6 @@ static void popup_handle_reposition(struct wl_listener *listener, void *data) {
|
||||||
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
static void popup_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
(void)data;
|
(void)data;
|
||||||
struct tabbed_popup *tp = wl_container_of(listener, tp, destroy);
|
struct tabbed_popup *tp = wl_container_of(listener, tp, destroy);
|
||||||
wl_list_remove(&tp->link);
|
|
||||||
wl_list_remove(&tp->commit.link);
|
wl_list_remove(&tp->commit.link);
|
||||||
wl_list_remove(&tp->destroy.link);
|
wl_list_remove(&tp->destroy.link);
|
||||||
wl_list_remove(&tp->reposition.link);
|
wl_list_remove(&tp->reposition.link);
|
||||||
|
|
@ -978,7 +963,6 @@ static void create_popup(struct wlr_xdg_popup *popup,
|
||||||
if (!tp) return;
|
if (!tp) return;
|
||||||
tp->xdg_surface = xdg_surface;
|
tp->xdg_surface = xdg_surface;
|
||||||
tp->scene = wlr_scene_xdg_surface_create(parent_tree, xdg_surface);
|
tp->scene = wlr_scene_xdg_surface_create(parent_tree, xdg_surface);
|
||||||
wl_list_insert(&popups, &tp->link);
|
|
||||||
/* wlr_scene_xdg_surface_create destroys the node when the surface is
|
/* wlr_scene_xdg_surface_create destroys the node when the surface is
|
||||||
destroyed, so we only track positioning/reposition listeners here. */
|
destroyed, so we only track positioning/reposition listeners here. */
|
||||||
tp->commit.notify = popup_handle_commit;
|
tp->commit.notify = popup_handle_commit;
|
||||||
|
|
@ -2533,60 +2517,6 @@ static bool import_scene_buffer(struct wlr_buffer *buf, GLuint tex) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw one popup surface buffer into the presented window at its on-screen
|
|
||||||
position. This bypasses wlroots' scene rendering for popups, whose
|
|
||||||
premultiplied-alpha blend paints nothing in our nested EGL pipeline.
|
|
||||||
|
|
||||||
Each popup surface is composited exactly once per frame. A sub-menu is a
|
|
||||||
popup nested under its parent menu's scene tree, so it is reachable both
|
|
||||||
from its own tree and from the parent menu's tree; the surfaces-drawn array
|
|
||||||
prevents it being drawn twice. Position uses wlr_scene_node_coords (the
|
|
||||||
true absolute offset, including every ancestor), because the iterator's
|
|
||||||
sx/sy only sums offsets from its own tree root and would place a nested
|
|
||||||
popup too high/left by the missing ancestor offsets. */
|
|
||||||
struct popup_draw_ctx {
|
|
||||||
int win_w, win_h;
|
|
||||||
struct wlr_surface **drawn;
|
|
||||||
int ndrawn;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void popup_draw_cb(struct wlr_scene_buffer *buffer,
|
|
||||||
int sx, int sy, void *user_data) {
|
|
||||||
struct popup_draw_ctx *ctx = user_data;
|
|
||||||
if (!buffer->buffer) return;
|
|
||||||
struct wlr_scene_surface *ss = wlr_scene_surface_try_from_buffer(buffer);
|
|
||||||
if (!ss) return;
|
|
||||||
for (int i = 0; i < ctx->ndrawn; i++) {
|
|
||||||
if (ctx->drawn[i] == ss->surface) return;
|
|
||||||
}
|
|
||||||
ctx->drawn[ctx->ndrawn++] = ss->surface;
|
|
||||||
(void)sx; (void)sy;
|
|
||||||
int lx = 0, ly = 0;
|
|
||||||
wlr_scene_node_coords(&buffer->node, &lx, &ly);
|
|
||||||
if (!import_scene_buffer(buffer->buffer, host.popup_tex)) return;
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
draw_texture_rect(host.popup_tex, buffer->buffer->width,
|
|
||||||
buffer->buffer->height,
|
|
||||||
0, 0, buffer->buffer->width, buffer->buffer->height,
|
|
||||||
lx, ly, ctx->win_w, ctx->win_h);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void composite_popups(void) {
|
|
||||||
struct wlr_surface *drawn[64];
|
|
||||||
struct popup_draw_ctx ctx = {
|
|
||||||
.win_w = host.width,
|
|
||||||
.win_h = host.height,
|
|
||||||
.drawn = drawn,
|
|
||||||
.ndrawn = 0,
|
|
||||||
};
|
|
||||||
struct tabbed_popup *tp;
|
|
||||||
wl_list_for_each(tp, &popups, link)
|
|
||||||
wlr_scene_node_for_each_buffer(&tp->scene->node,
|
|
||||||
popup_draw_cb, &ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pace presents to the host compositor: this fires after the host has shown
|
/* Pace presents to the host compositor: this fires after the host has shown
|
||||||
the buffer we queued, so we know we may queue the next one. Any frame drawn
|
the buffer we queued, so we know we may queue the next one. Any frame drawn
|
||||||
while a present is still pending is coalesced into the back buffer and
|
while a present is still pending is coalesced into the back buffer and
|
||||||
|
|
@ -2658,8 +2588,6 @@ static void blit_scene_buffer(struct wlr_buffer *buf) {
|
||||||
0, 0, buf->width, buf->height, 0, 0, w, h);
|
0, 0, buf->width, buf->height, 0, 0, w, h);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
composite_popups();
|
|
||||||
|
|
||||||
if (dump_host_req) {
|
if (dump_host_req) {
|
||||||
dump_host_req = false;
|
dump_host_req = false;
|
||||||
dump_host_back();
|
dump_host_back();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue