xwm: Use empty opaque region for windows with alpha
Window contents cannot be assumed to be fully opaque for windows drawn with a RGBA visual. The optimization of setting a full opaque region is limited to windows with a color depth != 32.
This commit is contained in:
@@ -116,6 +116,7 @@ struct weston_wm_window {
|
|||||||
int decorate;
|
int decorate;
|
||||||
int override_redirect;
|
int override_redirect;
|
||||||
int fullscreen;
|
int fullscreen;
|
||||||
|
int has_alpha;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct weston_wm_window *
|
static struct weston_wm_window *
|
||||||
@@ -901,6 +902,9 @@ weston_wm_window_draw_decoration(void *data)
|
|||||||
|
|
||||||
if (window->surface) {
|
if (window->surface) {
|
||||||
pixman_region32_fini(&window->surface->pending.opaque);
|
pixman_region32_fini(&window->surface->pending.opaque);
|
||||||
|
if(window->has_alpha) {
|
||||||
|
pixman_region32_init(&window->surface->pending.opaque);
|
||||||
|
} else {
|
||||||
/* We leave an extra pixel around the X window area to
|
/* We leave an extra pixel around the X window area to
|
||||||
* make sure we don't sample from the undefined alpha
|
* make sure we don't sample from the undefined alpha
|
||||||
* channel when filtering. */
|
* channel when filtering. */
|
||||||
@@ -908,6 +912,7 @@ weston_wm_window_draw_decoration(void *data)
|
|||||||
x - 1, y - 1,
|
x - 1, y - 1,
|
||||||
window->width + 2,
|
window->width + 2,
|
||||||
window->height + 2);
|
window->height + 2);
|
||||||
|
}
|
||||||
weston_surface_geometry_dirty(window->surface);
|
weston_surface_geometry_dirty(window->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -930,8 +935,12 @@ weston_wm_window_schedule_repaint(struct weston_wm_window *window)
|
|||||||
if (window->surface != NULL) {
|
if (window->surface != NULL) {
|
||||||
weston_wm_window_get_frame_size(window, &width, &height);
|
weston_wm_window_get_frame_size(window, &width, &height);
|
||||||
pixman_region32_fini(&window->surface->pending.opaque);
|
pixman_region32_fini(&window->surface->pending.opaque);
|
||||||
|
if(window->has_alpha) {
|
||||||
|
pixman_region32_init(&window->surface->pending.opaque);
|
||||||
|
} else {
|
||||||
pixman_region32_init_rect(&window->surface->pending.opaque, 0, 0,
|
pixman_region32_init_rect(&window->surface->pending.opaque, 0, 0,
|
||||||
width, height);
|
width, height);
|
||||||
|
}
|
||||||
weston_surface_geometry_dirty(window->surface);
|
weston_surface_geometry_dirty(window->surface);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -977,6 +986,8 @@ weston_wm_window_create(struct weston_wm *wm,
|
|||||||
{
|
{
|
||||||
struct weston_wm_window *window;
|
struct weston_wm_window *window;
|
||||||
uint32_t values[1];
|
uint32_t values[1];
|
||||||
|
xcb_get_geometry_cookie_t geometry_cookie;
|
||||||
|
xcb_get_geometry_reply_t *geometry_reply;
|
||||||
|
|
||||||
window = malloc(sizeof *window);
|
window = malloc(sizeof *window);
|
||||||
if (window == NULL) {
|
if (window == NULL) {
|
||||||
@@ -984,6 +995,8 @@ weston_wm_window_create(struct weston_wm *wm,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geometry_cookie = xcb_get_geometry(wm->conn, id);
|
||||||
|
|
||||||
values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
|
values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||||
xcb_change_window_attributes(wm->conn, id, XCB_CW_EVENT_MASK, values);
|
xcb_change_window_attributes(wm->conn, id, XCB_CW_EVENT_MASK, values);
|
||||||
|
|
||||||
@@ -995,6 +1008,13 @@ weston_wm_window_create(struct weston_wm *wm,
|
|||||||
window->width = width;
|
window->width = width;
|
||||||
window->height = height;
|
window->height = height;
|
||||||
|
|
||||||
|
geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, NULL);
|
||||||
|
/* technically we should use XRender and check the visual format's
|
||||||
|
alpha_mask, but checking depth is simpler and works in all known cases */
|
||||||
|
if(geometry_reply != NULL)
|
||||||
|
window->has_alpha = geometry_reply->depth == 32;
|
||||||
|
free(geometry_reply);
|
||||||
|
|
||||||
hash_table_insert(wm->window_hash, id, window);
|
hash_table_insert(wm->window_hash, id, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user