mirror of
https://github.com/yshui/picom.git
synced 2024-10-27 05:24:17 -04:00
backend: give images a type
It's quite confusing what should be passed into what because too many things are `void *`. So give images a type to make things a bit clearer. Because of C's limited type system, we lose the ability to annotate them as nonnull or const, well you win some you lose some. Also while doing this I noticed error handling around this is a bit lacking. Co-authored-by: Maxim Solovyov <msolovyov@protonmail.com> Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
7f3f8b37b5
commit
2d98518b7d
12 changed files with 177 additions and 146 deletions
|
@ -115,6 +115,10 @@ struct dual_kawase_blur_args {
|
||||||
int strength;
|
int strength;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// Intentionally left blank
|
||||||
|
} *image_handle;
|
||||||
|
|
||||||
struct backend_operations {
|
struct backend_operations {
|
||||||
// =========== Initialization ===========
|
// =========== Initialization ===========
|
||||||
|
|
||||||
|
@ -167,26 +171,27 @@ struct backend_operations {
|
||||||
* Paint the content of an image onto the rendering buffer.
|
* Paint the content of an image onto the rendering buffer.
|
||||||
*
|
*
|
||||||
* @param backend_data the backend data
|
* @param backend_data the backend data
|
||||||
* @param image_data the image to paint
|
* @param image the image to paint, cannot be NULL
|
||||||
* @param dst_x, dst_y the top left corner of the image in the target
|
* @param dst_x, dst_y the top left corner of the image in the target
|
||||||
* @param mask the mask image, the top left of the mask is aligned with
|
* @param mask the mask image, the top left of the mask is aligned with
|
||||||
* the top left of the image
|
* the top left of the image. Optional, can be
|
||||||
|
* NULL.
|
||||||
* @param reg_paint the clip region, in target coordinates
|
* @param reg_paint the clip region, in target coordinates
|
||||||
* @param reg_visible the visible region, in target coordinates
|
* @param reg_visible the visible region, in target coordinates
|
||||||
*/
|
*/
|
||||||
void (*compose)(backend_t *backend_data, void *image_data, coord_t image_dst,
|
void (*compose)(backend_t *backend_data, image_handle image, coord_t image_dst,
|
||||||
void *mask, coord_t mask_dst, const region_t *reg_paint,
|
image_handle mask, coord_t mask_dst, const region_t *reg_paint,
|
||||||
const region_t *reg_visible);
|
const region_t *reg_visible) attr_nonnull(1, 2, 6, 7);
|
||||||
|
|
||||||
/// Fill rectangle of the rendering buffer, mostly for debug purposes, optional.
|
/// Fill rectangle of the rendering buffer, mostly for debug purposes, optional.
|
||||||
void (*fill)(backend_t *backend_data, struct color, const region_t *clip);
|
void (*fill)(backend_t *backend_data, struct color, const region_t *clip);
|
||||||
|
|
||||||
/// Blur a given region of the rendering buffer.
|
/// Blur a given region of the rendering buffer.
|
||||||
///
|
///
|
||||||
/// The blur is limited by `mask`. `mask_dst` specifies the top left corner of the
|
/// The blur can be limited by `mask`. `mask_dst` specifies the top left corner of
|
||||||
/// mask is.
|
/// the mask. `mask` can be NULL.
|
||||||
bool (*blur)(backend_t *backend_data, double opacity, void *blur_ctx, void *mask,
|
bool (*blur)(backend_t *backend_data, double opacity, void *blur_ctx,
|
||||||
coord_t mask_dst, const region_t *reg_blur,
|
image_handle mask, coord_t mask_dst, const region_t *reg_blur,
|
||||||
const region_t *reg_visible) attr_nonnull(1, 3, 6, 7);
|
const region_t *reg_visible) attr_nonnull(1, 3, 6, 7);
|
||||||
|
|
||||||
/// Update part of the back buffer with the rendering buffer, then present the
|
/// Update part of the back buffer with the rendering buffer, then present the
|
||||||
|
@ -204,10 +209,12 @@ struct backend_operations {
|
||||||
* @param backend_data backend data
|
* @param backend_data backend data
|
||||||
* @param pixmap X pixmap to bind
|
* @param pixmap X pixmap to bind
|
||||||
* @param fmt information of the pixmap's visual
|
* @param fmt information of the pixmap's visual
|
||||||
* @param owned whether the ownership of the pixmap is transferred to the backend
|
* @param owned whether the ownership of the pixmap is transferred to the
|
||||||
* @return backend internal data structure bound with this pixmap
|
* backend.
|
||||||
|
* @return backend specific image handle for the pixmap. May be
|
||||||
|
* NULL.
|
||||||
*/
|
*/
|
||||||
void *(*bind_pixmap)(backend_t *backend_data, xcb_pixmap_t pixmap,
|
image_handle (*bind_pixmap)(backend_t *backend_data, xcb_pixmap_t pixmap,
|
||||||
struct xvisual_info fmt, bool owned);
|
struct xvisual_info fmt, bool owned);
|
||||||
|
|
||||||
/// Create a shadow context for rendering shadows with radius `radius`.
|
/// Create a shadow context for rendering shadows with radius `radius`.
|
||||||
|
@ -224,17 +231,23 @@ struct backend_operations {
|
||||||
/// shadow context is created.
|
/// shadow context is created.
|
||||||
/// Default implementation: default_render_shadow
|
/// Default implementation: default_render_shadow
|
||||||
///
|
///
|
||||||
|
/// @return the shadow image, may be NULL.
|
||||||
|
///
|
||||||
/// Required.
|
/// Required.
|
||||||
void *(*render_shadow)(backend_t *backend_data, int width, int height,
|
image_handle (*render_shadow)(backend_t *backend_data, int width, int height,
|
||||||
struct backend_shadow_context *ctx, struct color color);
|
struct backend_shadow_context *ctx, struct color color);
|
||||||
|
|
||||||
/// Create a shadow by blurring a mask. `size` is the size of the blur. The
|
/// Create a shadow by blurring a mask. `size` is the size of the blur. The
|
||||||
/// backend can use whichever blur method is the fastest. The shadow produced
|
/// backend can use whichever blur method is the fastest. The shadow produced
|
||||||
/// shoule be consistent with `render_shadow`.
|
/// shoule be consistent with `render_shadow`.
|
||||||
///
|
///
|
||||||
|
/// @param mask the input mask, must not be NULL.
|
||||||
|
/// @return the shadow image, may be NULL.
|
||||||
|
///
|
||||||
/// Optional.
|
/// Optional.
|
||||||
void *(*shadow_from_mask)(backend_t *backend_data, void *mask,
|
image_handle (*shadow_from_mask)(backend_t *backend_data, image_handle mask,
|
||||||
struct backend_shadow_context *ctx, struct color color);
|
struct backend_shadow_context *ctx,
|
||||||
|
struct color color);
|
||||||
|
|
||||||
/// Create a mask image from region `reg`. This region can be used to create
|
/// Create a mask image from region `reg`. This region can be used to create
|
||||||
/// shadow, or used as a mask for composing. When used as a mask, it should mask
|
/// shadow, or used as a mask for composing. When used as a mask, it should mask
|
||||||
|
@ -245,13 +258,18 @@ struct backend_operations {
|
||||||
/// and outside of the mask. Corner radius should exclude the corners from the
|
/// and outside of the mask. Corner radius should exclude the corners from the
|
||||||
/// mask. Corner radius should be applied before the inversion.
|
/// mask. Corner radius should be applied before the inversion.
|
||||||
///
|
///
|
||||||
|
/// @return the mask image, may be NULL.
|
||||||
|
///
|
||||||
/// Required.
|
/// Required.
|
||||||
void *(*make_mask)(backend_t *backend_data, geometry_t size, const region_t *reg);
|
image_handle (*make_mask)(backend_t *backend_data, geometry_t size,
|
||||||
|
const region_t *reg);
|
||||||
|
|
||||||
// ============ Resource management ===========
|
// ============ Resource management ===========
|
||||||
|
|
||||||
/// Free resources associated with an image data structure
|
/// Free resources associated with an image data structure
|
||||||
void (*release_image)(backend_t *backend_data, void *img_data) attr_nonnull(1, 2);
|
///
|
||||||
|
/// @param image the image to be released, cannot be NULL.
|
||||||
|
void (*release_image)(backend_t *backend_data, image_handle image) attr_nonnull(1, 2);
|
||||||
|
|
||||||
/// Create a shader object from a shader source.
|
/// Create a shader object from a shader source.
|
||||||
///
|
///
|
||||||
|
@ -276,7 +294,9 @@ struct backend_operations {
|
||||||
/// This function is needed because some backend might change the content of the
|
/// This function is needed because some backend might change the content of the
|
||||||
/// window (e.g. when using a custom shader with the glx backend), so only the
|
/// window (e.g. when using a custom shader with the glx backend), so only the
|
||||||
/// backend knows if an image is transparent.
|
/// backend knows if an image is transparent.
|
||||||
bool (*is_image_transparent)(backend_t *backend_data, void *image_data)
|
///
|
||||||
|
/// @param image the image to be checked, must not be NULL.
|
||||||
|
bool (*is_image_transparent)(backend_t *backend_data, image_handle image)
|
||||||
attr_nonnull(1, 2);
|
attr_nonnull(1, 2);
|
||||||
|
|
||||||
/// Get the age of the buffer content we are currently rendering on top
|
/// Get the age of the buffer content we are currently rendering on top
|
||||||
|
@ -311,19 +331,19 @@ struct backend_operations {
|
||||||
*
|
*
|
||||||
* @param backend_data backend data
|
* @param backend_data backend data
|
||||||
* @param prop the property to change
|
* @param prop the property to change
|
||||||
* @param image_data an image data structure returned by the backend
|
* @param image an image handle, cannot be NULL.
|
||||||
* @param args property value
|
* @param args property value
|
||||||
* @return whether the operation is successful
|
* @return whether the operation is successful
|
||||||
*/
|
*/
|
||||||
bool (*set_image_property)(backend_t *backend_data, enum image_properties prop,
|
bool (*set_image_property)(backend_t *backend_data, enum image_properties prop,
|
||||||
void *image_data, void *args);
|
image_handle image, void *args) attr_nonnull(1, 3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manipulate an image. Image properties are untouched.
|
* Manipulate an image. Image properties are untouched.
|
||||||
*
|
*
|
||||||
* @param backend_data backend data
|
* @param backend_data backend data
|
||||||
* @param op the operation to perform
|
* @param op the operation to perform
|
||||||
* @param image_data an image data structure returned by the backend
|
* @param image an image handle, cannot be NULL.
|
||||||
* @param reg_op the clip region, define the part of the image to be
|
* @param reg_op the clip region, define the part of the image to be
|
||||||
* operated on.
|
* operated on.
|
||||||
* @param reg_visible define the part of the image that will eventually
|
* @param reg_visible define the part of the image that will eventually
|
||||||
|
@ -332,15 +352,18 @@ struct backend_operations {
|
||||||
* @param args extra arguments, operation specific
|
* @param args extra arguments, operation specific
|
||||||
* @return whether the operation is successful
|
* @return whether the operation is successful
|
||||||
*/
|
*/
|
||||||
bool (*image_op)(backend_t *backend_data, enum image_operations op, void *image_data,
|
bool (*image_op)(backend_t *backend_data, enum image_operations op,
|
||||||
const region_t *reg_op, const region_t *reg_visible, void *args);
|
image_handle image, const region_t *reg_op,
|
||||||
|
const region_t *reg_visible, void *args) attr_nonnull(1, 3, 4, 5);
|
||||||
|
|
||||||
/// Create another instance of the `image_data`. The newly created image
|
/// Create another instance of the `image`. The newly created image
|
||||||
/// inherits its content and all image properties from the image being
|
/// inherits its content and all image properties from the image being
|
||||||
/// cloned. All `image_op` and `set_image_property` calls on the
|
/// cloned. All `image_op` and `set_image_property` calls on the
|
||||||
/// returned image should not affect the original image.
|
/// returned image should not affect the original image.
|
||||||
void *(*clone_image)(backend_t *base, const void *image_data,
|
///
|
||||||
const region_t *reg_visible);
|
/// @param image the image to be cloned, must not be NULL.
|
||||||
|
image_handle (*clone_image)(backend_t *base, image_handle image,
|
||||||
|
const region_t *reg_visible) attr_nonnull_all;
|
||||||
|
|
||||||
/// Create a blur context that can be used to call `blur`
|
/// Create a blur context that can be used to call `blur`
|
||||||
void *(*create_blur_context)(backend_t *base, enum blur_method, void *args);
|
void *(*create_blur_context)(backend_t *base, enum blur_method, void *args);
|
||||||
|
|
|
@ -293,7 +293,7 @@ shadow_picture_err:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *default_render_shadow(backend_t *backend_data, int width, int height,
|
image_handle default_render_shadow(backend_t *backend_data, int width, int height,
|
||||||
struct backend_shadow_context *sctx, struct color color) {
|
struct backend_shadow_context *sctx, struct color color) {
|
||||||
const conv *kernel = (void *)sctx;
|
const conv *kernel = (void *)sctx;
|
||||||
xcb_render_picture_t shadow_pixel =
|
xcb_render_picture_t shadow_pixel =
|
||||||
|
@ -308,7 +308,7 @@ void *default_render_shadow(backend_t *backend_data, int width, int height,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto visual = x_get_visual_for_standard(backend_data->c, XCB_PICT_STANDARD_ARGB_32);
|
auto visual = x_get_visual_for_standard(backend_data->c, XCB_PICT_STANDARD_ARGB_32);
|
||||||
void *ret = backend_data->ops->bind_pixmap(
|
auto ret = backend_data->ops->bind_pixmap(
|
||||||
backend_data, shadow, x_get_visual_info(backend_data->c, visual), true);
|
backend_data, shadow, x_get_visual_info(backend_data->c, visual), true);
|
||||||
x_free_picture(backend_data->c, pict);
|
x_free_picture(backend_data->c, pict);
|
||||||
x_free_picture(backend_data->c, shadow_pixel);
|
x_free_picture(backend_data->c, shadow_pixel);
|
||||||
|
@ -316,16 +316,16 @@ void *default_render_shadow(backend_t *backend_data, int width, int height,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implement render_shadow with shadow_from_mask
|
/// Implement render_shadow with shadow_from_mask
|
||||||
void *
|
image_handle
|
||||||
backend_render_shadow_from_mask(backend_t *backend_data, int width, int height,
|
backend_render_shadow_from_mask(backend_t *backend_data, int width, int height,
|
||||||
struct backend_shadow_context *sctx, struct color color) {
|
struct backend_shadow_context *sctx, struct color color) {
|
||||||
region_t reg;
|
region_t reg;
|
||||||
pixman_region32_init_rect(®, 0, 0, (unsigned int)width, (unsigned int)height);
|
pixman_region32_init_rect(®, 0, 0, (unsigned int)width, (unsigned int)height);
|
||||||
void *mask = backend_data->ops->make_mask(
|
auto mask = backend_data->ops->make_mask(
|
||||||
backend_data, (geometry_t){.width = width, .height = height}, ®);
|
backend_data, (geometry_t){.width = width, .height = height}, ®);
|
||||||
pixman_region32_fini(®);
|
pixman_region32_fini(®);
|
||||||
|
|
||||||
void *shadow = backend_data->ops->shadow_from_mask(backend_data, mask, sctx, color);
|
auto shadow = backend_data->ops->shadow_from_mask(backend_data, mask, sctx, color);
|
||||||
backend_data->ops->release_image(backend_data, mask);
|
backend_data->ops->release_image(backend_data, mask);
|
||||||
return shadow;
|
return shadow;
|
||||||
}
|
}
|
||||||
|
@ -458,17 +458,17 @@ struct dual_kawase_params *generate_dual_kawase_params(void *args) {
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *default_clone_image(backend_t *base attr_unused, const void *image_data,
|
image_handle default_clone_image(backend_t *base attr_unused, image_handle image,
|
||||||
const region_t *reg_visible attr_unused) {
|
const region_t *reg_visible attr_unused) {
|
||||||
auto new_img = ccalloc(1, struct backend_image);
|
auto new_img = ccalloc(1, struct backend_image);
|
||||||
*new_img = *(struct backend_image *)image_data;
|
*new_img = *(struct backend_image *)image;
|
||||||
new_img->inner->refcount++;
|
new_img->inner->refcount++;
|
||||||
return new_img;
|
return (image_handle)new_img;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool default_set_image_property(backend_t *base attr_unused, enum image_properties op,
|
bool default_set_image_property(backend_t *base attr_unused, enum image_properties op,
|
||||||
void *image_data, void *arg) {
|
image_handle image, void *arg) {
|
||||||
struct backend_image *tex = image_data;
|
auto tex = (struct backend_image *)image;
|
||||||
int *iargs = arg;
|
int *iargs = arg;
|
||||||
bool *bargs = arg;
|
bool *bargs = arg;
|
||||||
double *dargs = arg;
|
double *dargs = arg;
|
||||||
|
@ -490,8 +490,8 @@ bool default_set_image_property(backend_t *base attr_unused, enum image_properti
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool default_is_image_transparent(backend_t *base attr_unused, void *image_data) {
|
bool default_is_image_transparent(backend_t *base attr_unused, image_handle image) {
|
||||||
struct backend_image *img = image_data;
|
auto img = (struct backend_image *)image;
|
||||||
return img->opacity < 1 || img->inner->has_alpha;
|
return img->opacity < 1 || img->inner->has_alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,11 +54,11 @@ solid_picture(struct x_connection *, bool argb, double a, double r, double g, do
|
||||||
xcb_image_t *make_shadow(struct x_connection *c, const conv *kernel, double opacity,
|
xcb_image_t *make_shadow(struct x_connection *c, const conv *kernel, double opacity,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
|
|
||||||
void *default_render_shadow(backend_t *backend_data, int width, int height,
|
image_handle default_render_shadow(backend_t *backend_data, int width, int height,
|
||||||
struct backend_shadow_context *sctx, struct color color);
|
struct backend_shadow_context *sctx, struct color color);
|
||||||
|
|
||||||
/// Implement `render_shadow` with `shadow_from_mask`.
|
/// Implement `render_shadow` with `shadow_from_mask`.
|
||||||
void *
|
image_handle
|
||||||
backend_render_shadow_from_mask(backend_t *backend_data, int width, int height,
|
backend_render_shadow_from_mask(backend_t *backend_data, int width, int height,
|
||||||
struct backend_shadow_context *sctx, struct color color);
|
struct backend_shadow_context *sctx, struct color color);
|
||||||
struct backend_shadow_context *
|
struct backend_shadow_context *
|
||||||
|
@ -72,8 +72,8 @@ void init_backend_base(struct backend_base *base, session_t *ps);
|
||||||
struct conv **generate_blur_kernel(enum blur_method method, void *args, int *kernel_count);
|
struct conv **generate_blur_kernel(enum blur_method method, void *args, int *kernel_count);
|
||||||
struct dual_kawase_params *generate_dual_kawase_params(void *args);
|
struct dual_kawase_params *generate_dual_kawase_params(void *args);
|
||||||
|
|
||||||
void *default_clone_image(backend_t *base, const void *image_data, const region_t *reg);
|
image_handle default_clone_image(backend_t *base, image_handle image, const region_t *reg);
|
||||||
bool default_is_image_transparent(backend_t *base attr_unused, void *image_data);
|
bool default_is_image_transparent(backend_t *base attr_unused, image_handle image);
|
||||||
bool default_set_image_property(backend_t *base attr_unused, enum image_properties op,
|
bool default_set_image_property(backend_t *base attr_unused, enum image_properties op,
|
||||||
void *image_data, void *arg);
|
image_handle image, void *arg);
|
||||||
struct backend_image *default_new_backend_image(int w, int h);
|
struct backend_image *default_new_backend_image(int w, int h);
|
||||||
|
|
|
@ -50,8 +50,9 @@ void dummy_deinit(struct backend_base *data) {
|
||||||
free(dummy);
|
free(dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dummy_check_image(struct backend_base *base, const struct dummy_image *img) {
|
static void dummy_check_image(struct backend_base *base, image_handle image) {
|
||||||
auto dummy = (struct dummy_data *)base;
|
auto dummy = (struct dummy_data *)base;
|
||||||
|
auto img = (struct dummy_image *)image;
|
||||||
if (img == (struct dummy_image *)&dummy->mask) {
|
if (img == (struct dummy_image *)&dummy->mask) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -64,13 +65,13 @@ static void dummy_check_image(struct backend_base *base, const struct dummy_imag
|
||||||
assert(*tmp->refcount > 0);
|
assert(*tmp->refcount > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dummy_compose(struct backend_base *base, void *image, coord_t dst attr_unused,
|
void dummy_compose(struct backend_base *base, image_handle image, coord_t dst attr_unused,
|
||||||
void *mask attr_unused, coord_t mask_dst attr_unused,
|
image_handle mask attr_unused, coord_t mask_dst attr_unused,
|
||||||
const region_t *reg_paint attr_unused,
|
const region_t *reg_paint attr_unused,
|
||||||
const region_t *reg_visible attr_unused) {
|
const region_t *reg_visible attr_unused) {
|
||||||
auto dummy attr_unused = (struct dummy_data *)base;
|
auto dummy attr_unused = (struct dummy_data *)base;
|
||||||
dummy_check_image(base, image);
|
dummy_check_image(base, image);
|
||||||
assert(mask == NULL || mask == &dummy->mask);
|
assert(mask == NULL || (struct backend_image *)mask == &dummy->mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dummy_fill(struct backend_base *backend_data attr_unused, struct color c attr_unused,
|
void dummy_fill(struct backend_base *backend_data attr_unused, struct color c attr_unused,
|
||||||
|
@ -78,20 +79,20 @@ void dummy_fill(struct backend_base *backend_data attr_unused, struct color c at
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dummy_blur(struct backend_base *backend_data attr_unused, double opacity attr_unused,
|
bool dummy_blur(struct backend_base *backend_data attr_unused, double opacity attr_unused,
|
||||||
void *blur_ctx attr_unused, void *mask attr_unused,
|
void *blur_ctx attr_unused, image_handle mask attr_unused,
|
||||||
coord_t mask_dst attr_unused, const region_t *reg_blur attr_unused,
|
coord_t mask_dst attr_unused, const region_t *reg_blur attr_unused,
|
||||||
const region_t *reg_visible attr_unused) {
|
const region_t *reg_visible attr_unused) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dummy_bind_pixmap(struct backend_base *base, xcb_pixmap_t pixmap,
|
image_handle dummy_bind_pixmap(struct backend_base *base, xcb_pixmap_t pixmap,
|
||||||
struct xvisual_info fmt, bool owned) {
|
struct xvisual_info fmt, bool owned) {
|
||||||
auto dummy = (struct dummy_data *)base;
|
auto dummy = (struct dummy_data *)base;
|
||||||
struct dummy_image *img = NULL;
|
struct dummy_image *img = NULL;
|
||||||
HASH_FIND_INT(dummy->images, &pixmap, img);
|
HASH_FIND_INT(dummy->images, &pixmap, img);
|
||||||
if (img) {
|
if (img) {
|
||||||
(*img->refcount)++;
|
(*img->refcount)++;
|
||||||
return img;
|
return (image_handle)img;
|
||||||
}
|
}
|
||||||
|
|
||||||
img = ccalloc(1, struct dummy_image);
|
img = ccalloc(1, struct dummy_image);
|
||||||
|
@ -102,12 +103,12 @@ void *dummy_bind_pixmap(struct backend_base *base, xcb_pixmap_t pixmap,
|
||||||
img->owned = owned;
|
img->owned = owned;
|
||||||
|
|
||||||
HASH_ADD_INT(dummy->images, pixmap, img);
|
HASH_ADD_INT(dummy->images, pixmap, img);
|
||||||
return (void *)img;
|
return (image_handle)img;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dummy_release_image(backend_t *base, void *image) {
|
void dummy_release_image(backend_t *base, image_handle image) {
|
||||||
auto dummy = (struct dummy_data *)base;
|
auto dummy = (struct dummy_data *)base;
|
||||||
if (image == &dummy->mask) {
|
if ((struct backend_image *)image == &dummy->mask) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto img = (struct dummy_image *)image;
|
auto img = (struct dummy_image *)image;
|
||||||
|
@ -123,10 +124,9 @@ void dummy_release_image(backend_t *base, void *image) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dummy_is_image_transparent(struct backend_base *base, void *image) {
|
bool dummy_is_image_transparent(struct backend_base *base, image_handle image) {
|
||||||
auto img = (struct dummy_image *)image;
|
dummy_check_image(base, image);
|
||||||
dummy_check_image(base, img);
|
return ((struct dummy_image *)image)->transparent;
|
||||||
return img->transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int dummy_buffer_age(struct backend_base *base attr_unused) {
|
int dummy_buffer_age(struct backend_base *base attr_unused) {
|
||||||
|
@ -134,29 +134,31 @@ int dummy_buffer_age(struct backend_base *base attr_unused) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dummy_image_op(struct backend_base *base, enum image_operations op attr_unused,
|
bool dummy_image_op(struct backend_base *base, enum image_operations op attr_unused,
|
||||||
void *image, const region_t *reg_op attr_unused,
|
image_handle image, const region_t *reg_op attr_unused,
|
||||||
const region_t *reg_visible attr_unused, void *args attr_unused) {
|
const region_t *reg_visible attr_unused, void *args attr_unused) {
|
||||||
dummy_check_image(base, image);
|
dummy_check_image(base, image);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dummy_make_mask(struct backend_base *base, geometry_t size attr_unused,
|
image_handle dummy_make_mask(struct backend_base *base, geometry_t size attr_unused,
|
||||||
const region_t *reg attr_unused) {
|
const region_t *reg attr_unused) {
|
||||||
return &(((struct dummy_data *)base)->mask);
|
auto dummy = (struct dummy_data *)base;
|
||||||
|
auto mask = &dummy->mask;
|
||||||
|
return (image_handle)mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dummy_set_image_property(struct backend_base *base, enum image_properties prop attr_unused,
|
bool dummy_set_image_property(struct backend_base *base, enum image_properties prop attr_unused,
|
||||||
void *image, void *arg attr_unused) {
|
image_handle image, void *arg attr_unused) {
|
||||||
dummy_check_image(base, image);
|
dummy_check_image(base, image);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dummy_clone_image(struct backend_base *base, const void *image,
|
image_handle dummy_clone_image(struct backend_base *base, image_handle image,
|
||||||
const region_t *reg_visible attr_unused) {
|
const region_t *reg_visible attr_unused) {
|
||||||
auto img = (const struct dummy_image *)image;
|
dummy_check_image(base, image);
|
||||||
dummy_check_image(base, img);
|
auto image_impl = (struct dummy_image *)image;
|
||||||
(*img->refcount)++;
|
(*image_impl->refcount)++;
|
||||||
return (void *)img;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *dummy_create_blur_context(struct backend_base *base attr_unused,
|
void *dummy_create_blur_context(struct backend_base *base attr_unused,
|
||||||
|
|
|
@ -256,10 +256,11 @@ bool gl_dual_kawase_blur(double opacity, struct gl_blur_context *bctx, const rec
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gl_blur_impl(double opacity, struct gl_blur_context *bctx, void *mask, coord_t mask_dst,
|
bool gl_blur_impl(double opacity, struct gl_blur_context *bctx,
|
||||||
const region_t *reg_blur, const region_t *reg_visible attr_unused,
|
struct backend_image *mask, coord_t mask_dst, const region_t *reg_blur,
|
||||||
GLuint source_texture, geometry_t source_size, GLuint target_fbo,
|
const region_t *reg_visible attr_unused, GLuint source_texture,
|
||||||
GLuint default_mask, bool high_precision) {
|
geometry_t source_size, GLuint target_fbo, GLuint default_mask,
|
||||||
|
bool high_precision) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (source_size.width != bctx->fb_width || source_size.height != bctx->fb_height) {
|
if (source_size.width != bctx->fb_width || source_size.height != bctx->fb_height) {
|
||||||
|
@ -400,12 +401,12 @@ bool gl_blur_impl(double opacity, struct gl_blur_context *bctx, void *mask, coor
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gl_blur(backend_t *base, double opacity, void *ctx, void *mask, coord_t mask_dst,
|
bool gl_blur(backend_t *base, double opacity, void *ctx, image_handle mask, coord_t mask_dst,
|
||||||
const region_t *reg_blur, const region_t *reg_visible attr_unused) {
|
const region_t *reg_blur, const region_t *reg_visible attr_unused) {
|
||||||
auto gd = (struct gl_data *)base;
|
auto gd = (struct gl_data *)base;
|
||||||
auto bctx = (struct gl_blur_context *)ctx;
|
auto bctx = (struct gl_blur_context *)ctx;
|
||||||
return gl_blur_impl(opacity, bctx, mask, mask_dst, reg_blur, reg_visible,
|
return gl_blur_impl(opacity, bctx, (struct backend_image *)mask, mask_dst,
|
||||||
gd->back_texture,
|
reg_blur, reg_visible, gd->back_texture,
|
||||||
(geometry_t){.width = gd->width, .height = gd->height},
|
(geometry_t){.width = gd->width, .height = gd->height},
|
||||||
gd->back_fbo, gd->default_mask_texture, gd->dithered_present);
|
gd->back_fbo, gd->default_mask_texture, gd->dithered_present);
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@ end:
|
||||||
return &gd->gl.base;
|
return &gd->gl.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static image_handle
|
||||||
egl_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, bool owned) {
|
egl_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, bool owned) {
|
||||||
struct egl_data *gd = (void *)base;
|
struct egl_data *gd = (void *)base;
|
||||||
struct egl_pixmap *eglpixmap = NULL;
|
struct egl_pixmap *eglpixmap = NULL;
|
||||||
|
@ -301,7 +301,7 @@ egl_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
gl_check_err();
|
gl_check_err();
|
||||||
return wd;
|
return (image_handle)wd;
|
||||||
err:
|
err:
|
||||||
if (eglpixmap && eglpixmap->image) {
|
if (eglpixmap && eglpixmap->image) {
|
||||||
eglDestroyImage(gd->display, eglpixmap->image);
|
eglDestroyImage(gd->display, eglpixmap->image);
|
||||||
|
|
|
@ -551,11 +551,12 @@ void x_rect_to_coords(int nrects, const rect_t *rects, coord_t image_dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(yshui) make use of reg_visible
|
// TODO(yshui) make use of reg_visible
|
||||||
void gl_compose(backend_t *base, void *image_data, coord_t image_dst, void *mask,
|
void gl_compose(backend_t *base, image_handle image, coord_t image_dst,
|
||||||
coord_t mask_dst, const region_t *reg_tgt,
|
image_handle mask_, coord_t mask_dst, const region_t *reg_tgt,
|
||||||
const region_t *reg_visible attr_unused) {
|
const region_t *reg_visible attr_unused) {
|
||||||
auto gd = (struct gl_data *)base;
|
auto gd = (struct gl_data *)base;
|
||||||
struct backend_image *img = image_data;
|
auto img = (struct backend_image *)image;
|
||||||
|
auto mask = (struct backend_image *)mask_;
|
||||||
auto inner = (struct gl_texture *)img->inner;
|
auto inner = (struct gl_texture *)img->inner;
|
||||||
|
|
||||||
// Painting
|
// Painting
|
||||||
|
@ -709,7 +710,7 @@ void gl_fill(backend_t *base, struct color c, const region_t *clip) {
|
||||||
return _gl_fill(base, c, clip, gd->back_fbo, gd->height, true);
|
return _gl_fill(base, c, clip, gd->back_fbo, gd->height, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *gl_make_mask(backend_t *base, geometry_t size, const region_t *reg) {
|
image_handle gl_make_mask(backend_t *base, geometry_t size, const region_t *reg) {
|
||||||
auto tex = ccalloc(1, struct gl_texture);
|
auto tex = ccalloc(1, struct gl_texture);
|
||||||
auto img = default_new_backend_image(size.width, size.height);
|
auto img = default_new_backend_image(size.width, size.height);
|
||||||
tex->width = size.width;
|
tex->width = size.width;
|
||||||
|
@ -740,7 +741,7 @@ void *gl_make_mask(backend_t *base, geometry_t size, const region_t *reg) {
|
||||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glDeleteFramebuffers(1, &fbo);
|
glDeleteFramebuffers(1, &fbo);
|
||||||
return img;
|
return (image_handle)img;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gl_release_image_inner(backend_t *base, struct gl_texture *inner) {
|
static void gl_release_image_inner(backend_t *base, struct gl_texture *inner) {
|
||||||
|
@ -756,8 +757,8 @@ static void gl_release_image_inner(backend_t *base, struct gl_texture *inner) {
|
||||||
gl_check_err();
|
gl_check_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl_release_image(backend_t *base, void *image_data) {
|
void gl_release_image(backend_t *base, image_handle image) {
|
||||||
struct backend_image *wd = image_data;
|
auto wd = (struct backend_image *)image;
|
||||||
auto inner = (struct gl_texture *)wd->inner;
|
auto inner = (struct gl_texture *)wd->inner;
|
||||||
inner->refcount--;
|
inner->refcount--;
|
||||||
assert(inner->refcount >= 0);
|
assert(inner->refcount >= 0);
|
||||||
|
@ -1221,9 +1222,9 @@ bool gl_last_render_time(backend_t *base, struct timespec *ts) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gl_image_op(backend_t *base, enum image_operations op, void *image_data,
|
bool gl_image_op(backend_t *base, enum image_operations op, image_handle image,
|
||||||
const region_t *reg_op, const region_t *reg_visible attr_unused, void *arg) {
|
const region_t *reg_op, const region_t *reg_visible attr_unused, void *arg) {
|
||||||
struct backend_image *tex = image_data;
|
auto tex = (struct backend_image *)image;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case IMAGE_OP_APPLY_ALPHA:
|
case IMAGE_OP_APPLY_ALPHA:
|
||||||
gl_image_decouple(base, tex);
|
gl_image_decouple(base, tex);
|
||||||
|
@ -1236,12 +1237,12 @@ bool gl_image_op(backend_t *base, enum image_operations op, void *image_data,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gl_set_image_property(backend_t *backend_data, enum image_properties prop,
|
bool gl_set_image_property(backend_t *backend_data, enum image_properties prop,
|
||||||
void *image_data, void *args) {
|
image_handle image, void *args) {
|
||||||
if (prop != IMAGE_PROPERTY_CUSTOM_SHADER) {
|
if (prop != IMAGE_PROPERTY_CUSTOM_SHADER) {
|
||||||
return default_set_image_property(backend_data, prop, image_data, args);
|
return default_set_image_property(backend_data, prop, image, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct backend_image *img = image_data;
|
auto img = (struct backend_image *)image;
|
||||||
auto inner = (struct gl_texture *)img->inner;
|
auto inner = (struct gl_texture *)img->inner;
|
||||||
inner->shader = args;
|
inner->shader = args;
|
||||||
return true;
|
return true;
|
||||||
|
@ -1280,12 +1281,12 @@ void gl_destroy_shadow_context(backend_t *base attr_unused, struct backend_shado
|
||||||
free(ctx_);
|
free(ctx_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *gl_shadow_from_mask(backend_t *base, void *mask,
|
image_handle gl_shadow_from_mask(backend_t *base, image_handle mask_,
|
||||||
struct backend_shadow_context *sctx, struct color color) {
|
struct backend_shadow_context *sctx, struct color color) {
|
||||||
log_debug("Create shadow from mask");
|
log_debug("Create shadow from mask");
|
||||||
auto gd = (struct gl_data *)base;
|
auto gd = (struct gl_data *)base;
|
||||||
auto img = (struct backend_image *)mask;
|
auto mask = (struct backend_image *)mask_;
|
||||||
auto inner = (struct gl_texture *)img->inner;
|
auto inner = (struct gl_texture *)mask->inner;
|
||||||
auto gsctx = (struct gl_shadow_context *)sctx;
|
auto gsctx = (struct gl_shadow_context *)sctx;
|
||||||
int radius = (int)gsctx->radius;
|
int radius = (int)gsctx->radius;
|
||||||
|
|
||||||
|
@ -1315,7 +1316,7 @@ void *gl_shadow_from_mask(backend_t *base, void *mask,
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||||
source_texture, 0);
|
source_texture, 0);
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
if (img->color_inverted) {
|
if (mask->color_inverted) {
|
||||||
// If the mask is inverted, clear the source_texture to white, so the
|
// If the mask is inverted, clear the source_texture to white, so the
|
||||||
// "outside" of the mask would be correct
|
// "outside" of the mask would be correct
|
||||||
glClearColor(1, 1, 1, 1);
|
glClearColor(1, 1, 1, 1);
|
||||||
|
@ -1424,7 +1425,7 @@ void *gl_shadow_from_mask(backend_t *base, void *mask,
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glDeleteFramebuffers(1, &fbo);
|
glDeleteFramebuffers(1, &fbo);
|
||||||
gl_check_err();
|
gl_check_err();
|
||||||
return new_img;
|
return (image_handle)new_img;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum device_status gl_device_status(backend_t *base) {
|
enum device_status gl_device_status(backend_t *base) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "backend/backend.h"
|
#include "backend/backend.h"
|
||||||
|
#include "backend/backend_common.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
|
|
||||||
|
@ -143,13 +144,13 @@ void *gl_create_window_shader(backend_t *backend_data, const char *source);
|
||||||
void gl_destroy_window_shader(backend_t *backend_data, void *shader);
|
void gl_destroy_window_shader(backend_t *backend_data, void *shader);
|
||||||
uint64_t gl_get_shader_attributes(backend_t *backend_data, void *shader);
|
uint64_t gl_get_shader_attributes(backend_t *backend_data, void *shader);
|
||||||
bool gl_set_image_property(backend_t *backend_data, enum image_properties prop,
|
bool gl_set_image_property(backend_t *backend_data, enum image_properties prop,
|
||||||
void *image_data, void *args);
|
image_handle image, void *args);
|
||||||
bool gl_last_render_time(backend_t *backend_data, struct timespec *time);
|
bool gl_last_render_time(backend_t *backend_data, struct timespec *time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Render a region with texture data.
|
* @brief Render a region with texture data.
|
||||||
*/
|
*/
|
||||||
void gl_compose(backend_t *, void *image_data, coord_t image_dst, void *mask,
|
void gl_compose(backend_t *, image_handle image, coord_t image_dst, image_handle mask,
|
||||||
coord_t mask_dst, const region_t *reg_tgt, const region_t *reg_visible);
|
coord_t mask_dst, const region_t *reg_tgt, const region_t *reg_visible);
|
||||||
|
|
||||||
void gl_resize(struct gl_data *, int width, int height);
|
void gl_resize(struct gl_data *, int width, int height);
|
||||||
|
@ -159,32 +160,32 @@ void gl_deinit(struct gl_data *gd);
|
||||||
|
|
||||||
GLuint gl_new_texture(GLenum target);
|
GLuint gl_new_texture(GLenum target);
|
||||||
|
|
||||||
bool gl_image_op(backend_t *base, enum image_operations op, void *image_data,
|
bool gl_image_op(backend_t *base, enum image_operations op, image_handle image,
|
||||||
const region_t *reg_op, const region_t *reg_visible, void *arg);
|
const region_t *reg_op, const region_t *reg_visible, void *arg);
|
||||||
|
|
||||||
void gl_release_image(backend_t *base, void *image_data);
|
void gl_release_image(backend_t *base, image_handle image);
|
||||||
void *gl_make_mask(backend_t *base, geometry_t size, const region_t *reg);
|
image_handle gl_make_mask(backend_t *base, geometry_t size, const region_t *reg);
|
||||||
|
|
||||||
void *gl_clone(backend_t *base, const void *image_data, const region_t *reg_visible);
|
image_handle gl_clone(backend_t *base, image_handle image, const region_t *reg_visible);
|
||||||
|
|
||||||
bool gl_blur(backend_t *base, double opacity, void *ctx, void *mask, coord_t mask_dst,
|
bool gl_blur(backend_t *base, double opacity, void *ctx, image_handle mask,
|
||||||
const region_t *reg_blur, const region_t *reg_visible);
|
coord_t mask_dst, const region_t *reg_blur, const region_t *reg_visible);
|
||||||
bool gl_blur_impl(double opacity, struct gl_blur_context *bctx, void *mask, coord_t mask_dst,
|
bool gl_blur_impl(double opacity, struct gl_blur_context *bctx,
|
||||||
const region_t *reg_blur, const region_t *reg_visible attr_unused,
|
struct backend_image *mask, coord_t mask_dst, const region_t *reg_blur,
|
||||||
GLuint source_texture, geometry_t source_size, GLuint target_fbo,
|
const region_t *reg_visible attr_unused, GLuint source_texture,
|
||||||
GLuint default_mask, bool high_precision);
|
geometry_t source_size, GLuint target_fbo, GLuint default_mask,
|
||||||
|
bool high_precision);
|
||||||
void *gl_create_blur_context(backend_t *base, enum blur_method, void *args);
|
void *gl_create_blur_context(backend_t *base, enum blur_method, void *args);
|
||||||
void gl_destroy_blur_context(backend_t *base, void *ctx);
|
void gl_destroy_blur_context(backend_t *base, void *ctx);
|
||||||
struct backend_shadow_context *gl_create_shadow_context(backend_t *base, double radius);
|
struct backend_shadow_context *gl_create_shadow_context(backend_t *base, double radius);
|
||||||
void gl_destroy_shadow_context(backend_t *base attr_unused, struct backend_shadow_context *ctx);
|
void gl_destroy_shadow_context(backend_t *base attr_unused, struct backend_shadow_context *ctx);
|
||||||
void *gl_shadow_from_mask(backend_t *base, void *mask,
|
image_handle gl_shadow_from_mask(backend_t *base, image_handle mask,
|
||||||
struct backend_shadow_context *sctx, struct color color);
|
struct backend_shadow_context *sctx, struct color color);
|
||||||
void gl_get_blur_size(void *blur_context, int *width, int *height);
|
void gl_get_blur_size(void *blur_context, int *width, int *height);
|
||||||
|
|
||||||
void gl_fill(backend_t *base, struct color, const region_t *clip);
|
void gl_fill(backend_t *base, struct color, const region_t *clip);
|
||||||
|
|
||||||
void gl_present(backend_t *base, const region_t *);
|
void gl_present(backend_t *base, const region_t *);
|
||||||
bool gl_read_pixel(backend_t *base, void *image_data, int x, int y, struct color *output);
|
|
||||||
enum device_status gl_device_status(backend_t *base);
|
enum device_status gl_device_status(backend_t *base);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -380,7 +380,7 @@ end:
|
||||||
return &gd->gl.base;
|
return &gd->gl.base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static image_handle
|
||||||
glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, bool owned) {
|
glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, bool owned) {
|
||||||
struct _glx_pixmap *glxpixmap = NULL;
|
struct _glx_pixmap *glxpixmap = NULL;
|
||||||
auto gd = (struct _glx_data *)base;
|
auto gd = (struct _glx_data *)base;
|
||||||
|
@ -475,7 +475,7 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
gl_check_err();
|
gl_check_err();
|
||||||
return wd;
|
return (image_handle)wd;
|
||||||
err:
|
err:
|
||||||
if (glxpixmap && glxpixmap->glpixmap) {
|
if (glxpixmap && glxpixmap->glpixmap) {
|
||||||
glXDestroyPixmap(base->c->dpy, glxpixmap->glpixmap);
|
glXDestroyPixmap(base->c->dpy, glxpixmap->glpixmap);
|
||||||
|
|
|
@ -359,10 +359,12 @@ compose_impl(struct _xrender_data *xd, struct xrender_image *xrimg, coord_t dst,
|
||||||
pixman_region32_fini(®);
|
pixman_region32_fini(®);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void compose(backend_t *base, void *img_data, coord_t dst, void *mask, coord_t mask_dst,
|
static void compose(backend_t *base, image_handle image_, coord_t dst, image_handle mask_,
|
||||||
const region_t *reg_paint, const region_t *reg_visible) {
|
coord_t mask_dst, const region_t *reg_paint, const region_t *reg_visible) {
|
||||||
struct _xrender_data *xd = (void *)base;
|
struct _xrender_data *xd = (void *)base;
|
||||||
return compose_impl(xd, img_data, dst, mask, mask_dst, reg_paint, reg_visible,
|
auto image = (struct xrender_image *)image_;
|
||||||
|
auto mask = (struct xrender_image *)mask_;
|
||||||
|
return compose_impl(xd, image, dst, mask, mask_dst, reg_paint, reg_visible,
|
||||||
xd->back[2]);
|
xd->back[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,9 +386,10 @@ static void fill(backend_t *base, struct color c, const region_t *clip) {
|
||||||
.height = to_u16_checked(extent->y2 - extent->y1)}});
|
.height = to_u16_checked(extent->y2 - extent->y1)}});
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool blur(backend_t *backend_data, double opacity, void *ctx_, void *mask,
|
static bool blur(backend_t *backend_data, double opacity, void *ctx_, image_handle mask_,
|
||||||
coord_t mask_dst, const region_t *reg_blur, const region_t *reg_visible) {
|
coord_t mask_dst, const region_t *reg_blur, const region_t *reg_visible) {
|
||||||
struct _xrender_blur_context *bctx = ctx_;
|
auto bctx = (struct _xrender_blur_context *)ctx_;
|
||||||
|
auto mask = (struct xrender_image *)mask_;
|
||||||
if (bctx->method == BLUR_METHOD_NONE) {
|
if (bctx->method == BLUR_METHOD_NONE) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -517,7 +520,7 @@ static bool blur(backend_t *backend_data, double opacity, void *ctx_, void *mask
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static image_handle
|
||||||
bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, bool owned) {
|
bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, bool owned) {
|
||||||
xcb_generic_error_t *e;
|
xcb_generic_error_t *e;
|
||||||
auto r = xcb_get_geometry_reply(base->c->c, xcb_get_geometry(base->c->c, pixmap), &e);
|
auto r = xcb_get_geometry_reply(base->c->c, xcb_get_geometry(base->c->c, pixmap), &e);
|
||||||
|
@ -552,7 +555,7 @@ bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, bool
|
||||||
free(img);
|
free(img);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return img;
|
return (image_handle)img;
|
||||||
}
|
}
|
||||||
static void release_image_inner(backend_t *base, struct _xrender_image_data_inner *inner) {
|
static void release_image_inner(backend_t *base, struct _xrender_image_data_inner *inner) {
|
||||||
x_free_picture(base->c, inner->pict);
|
x_free_picture(base->c, inner->pict);
|
||||||
|
@ -576,13 +579,13 @@ release_rounded_corner_cache(backend_t *base, struct xrender_rounded_rectangle_c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_image(backend_t *base, void *image) {
|
static void release_image(backend_t *base, image_handle image) {
|
||||||
struct xrender_image *img = image;
|
auto img = (struct xrender_image *)image;
|
||||||
release_rounded_corner_cache(base, img->rounded_rectangle);
|
release_rounded_corner_cache(base, img->rounded_rectangle);
|
||||||
img->rounded_rectangle = NULL;
|
img->rounded_rectangle = NULL;
|
||||||
img->base.inner->refcount -= 1;
|
img->base.inner->refcount -= 1;
|
||||||
if (img->base.inner->refcount == 0) {
|
if (img->base.inner->refcount == 0) {
|
||||||
release_image_inner(base, (void *)img->base.inner);
|
release_image_inner(base, (struct _xrender_image_data_inner *)img->base.inner);
|
||||||
}
|
}
|
||||||
free(img);
|
free(img);
|
||||||
}
|
}
|
||||||
|
@ -711,7 +714,7 @@ new_inner(backend_t *base, int w, int h, xcb_visualid_t visual, uint8_t depth) {
|
||||||
return new_inner;
|
return new_inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *make_mask(backend_t *base, geometry_t size, const region_t *reg) {
|
static image_handle make_mask(backend_t *base, geometry_t size, const region_t *reg) {
|
||||||
struct _xrender_data *xd = (void *)base;
|
struct _xrender_data *xd = (void *)base;
|
||||||
// Give the mask a 1 pixel wide border to emulate the clamp to border behavior of
|
// Give the mask a 1 pixel wide border to emulate the clamp to border behavior of
|
||||||
// OpenGL textures.
|
// OpenGL textures.
|
||||||
|
@ -754,7 +757,7 @@ static void *make_mask(backend_t *base, geometry_t size, const region_t *reg) {
|
||||||
img->base.dim = 0;
|
img->base.dim = 0;
|
||||||
img->base.inner = (struct backend_image_inner_base *)inner;
|
img->base.inner = (struct backend_image_inner_base *)inner;
|
||||||
img->rounded_rectangle = NULL;
|
img->rounded_rectangle = NULL;
|
||||||
return img;
|
return (image_handle)img;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool decouple_image(backend_t *base, struct backend_image *img, const region_t *reg) {
|
static bool decouple_image(backend_t *base, struct backend_image *img, const region_t *reg) {
|
||||||
|
@ -782,10 +785,10 @@ static bool decouple_image(backend_t *base, struct backend_image *img, const reg
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool image_op(backend_t *base, enum image_operations op, void *image,
|
static bool image_op(backend_t *base, enum image_operations op, image_handle image,
|
||||||
const region_t *reg_op, const region_t *reg_visible, void *arg) {
|
const region_t *reg_op, const region_t *reg_visible, void *arg) {
|
||||||
struct _xrender_data *xd = (void *)base;
|
struct _xrender_data *xd = (void *)base;
|
||||||
struct backend_image *img = image;
|
auto img = (struct backend_image *)image;
|
||||||
region_t reg;
|
region_t reg;
|
||||||
double *dargs = arg;
|
double *dargs = arg;
|
||||||
|
|
||||||
|
@ -964,19 +967,19 @@ err:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *clone_image(backend_t *base attr_unused, const void *image_data,
|
image_handle clone_image(backend_t *base attr_unused, image_handle image,
|
||||||
const region_t *reg_visible attr_unused) {
|
const region_t *reg_visible attr_unused) {
|
||||||
auto new_img = ccalloc(1, struct xrender_image);
|
auto new_img = ccalloc(1, struct xrender_image);
|
||||||
*new_img = *(struct xrender_image *)image_data;
|
*new_img = *(struct xrender_image *)image;
|
||||||
new_img->base.inner->refcount++;
|
new_img->base.inner->refcount++;
|
||||||
if (new_img->rounded_rectangle) {
|
if (new_img->rounded_rectangle) {
|
||||||
new_img->rounded_rectangle->refcount++;
|
new_img->rounded_rectangle->refcount++;
|
||||||
}
|
}
|
||||||
return new_img;
|
return (image_handle)new_img;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool set_image_property(backend_t *base, enum image_properties op,
|
||||||
set_image_property(backend_t *base, enum image_properties op, void *image, void *args) {
|
image_handle image, void *args) {
|
||||||
auto xrimg = (struct xrender_image *)image;
|
auto xrimg = (struct xrender_image *)image;
|
||||||
if (op == IMAGE_PROPERTY_CORNER_RADIUS &&
|
if (op == IMAGE_PROPERTY_CORNER_RADIUS &&
|
||||||
((double *)args)[0] != xrimg->base.corner_radius) {
|
((double *)args)[0] != xrimg->base.corner_radius) {
|
||||||
|
|
|
@ -186,7 +186,7 @@ typedef struct session {
|
||||||
/// Picture of the root window background.
|
/// Picture of the root window background.
|
||||||
paint_t root_tile_paint;
|
paint_t root_tile_paint;
|
||||||
/// The backend data the root pixmap bound to
|
/// The backend data the root pixmap bound to
|
||||||
void *root_image;
|
image_handle root_image;
|
||||||
/// A region of the size of the screen.
|
/// A region of the size of the screen.
|
||||||
region_t screen_reg;
|
region_t screen_reg;
|
||||||
/// Picture of root window. Destination of painting in no-DBE painting
|
/// Picture of root window. Destination of painting in no-DBE painting
|
||||||
|
|
|
@ -100,9 +100,9 @@ struct managed_win {
|
||||||
struct win base;
|
struct win base;
|
||||||
/// backend data attached to this window. Only available when
|
/// backend data attached to this window. Only available when
|
||||||
/// `state` is not UNMAPPED
|
/// `state` is not UNMAPPED
|
||||||
void *win_image;
|
image_handle win_image;
|
||||||
void *shadow_image;
|
image_handle shadow_image;
|
||||||
void *mask_image;
|
image_handle mask_image;
|
||||||
/// Pointer to the next higher window to paint.
|
/// Pointer to the next higher window to paint.
|
||||||
struct managed_win *prev_trans;
|
struct managed_win *prev_trans;
|
||||||
/// Number of windows above this window
|
/// Number of windows above this window
|
||||||
|
|
Loading…
Reference in a new issue