new_backend: New interface
Move more logic out of the backend. The backends are now more agnostic to what happens in compton. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
@@ -5,12 +5,30 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "region.h"
|
||||
#include "compiler.h"
|
||||
#include "kernel.h"
|
||||
#include "region.h"
|
||||
#include "x.h"
|
||||
|
||||
typedef struct session session_t;
|
||||
typedef struct win win;
|
||||
typedef struct backend_info {
|
||||
|
||||
struct backend_operations;
|
||||
|
||||
typedef struct backend_base {
|
||||
struct backend_operations *ops;
|
||||
xcb_connection_t *c;
|
||||
xcb_window_t root;
|
||||
// ...
|
||||
} backend_t;
|
||||
|
||||
enum image_operations {
|
||||
IMAGE_OP_INVERT_COLOR,
|
||||
IMAGE_OP_DIM,
|
||||
IMAGE_OP_APPLY_ALPHA,
|
||||
};
|
||||
|
||||
struct backend_operations {
|
||||
|
||||
// =========== Initialization ===========
|
||||
|
||||
@@ -19,15 +37,14 @@ typedef struct backend_info {
|
||||
/// 1) if ps->overlay is not XCB_NONE, use that
|
||||
/// 2) use ps->root otherwise
|
||||
/// XXX make the target window a parameter
|
||||
void *(*init)(session_t *ps) __attribute__((nonnull(1)));
|
||||
void (*deinit)(void *backend_data, session_t *ps) __attribute__((nonnull(1, 2)));
|
||||
void (*deinit)(backend_t *backend_data) __attribute__((nonnull(1)));
|
||||
|
||||
/// Called when rendering will be stopped for an unknown amount of
|
||||
/// time (e.g. screen is unredirected). Free some resources.
|
||||
void (*pause)(void *backend_data, session_t *ps);
|
||||
void (*pause)(backend_t *backend_data, session_t *ps);
|
||||
|
||||
/// Called before rendering is resumed
|
||||
void (*resume)(void *backend_data, session_t *ps);
|
||||
void (*resume)(backend_t *backend_data, session_t *ps);
|
||||
|
||||
/// Called when root property changed, returns the new
|
||||
/// backend_data. Even if the backend_data changed, all
|
||||
@@ -35,12 +52,7 @@ typedef struct backend_info {
|
||||
/// remain valid.
|
||||
///
|
||||
/// Optional
|
||||
void *(*root_change)(void *backend_data, session_t *ps);
|
||||
|
||||
/// Called when vsync is toggled after initialization. If vsync is enabled when init()
|
||||
/// is called, these function won't be called
|
||||
void (*vsync_start)(void *backend_data, session_t *ps);
|
||||
void (*vsync_stop)(void *backend_data, session_t *ps);
|
||||
void *(*root_change)(backend_t *backend_data, session_t *ps);
|
||||
|
||||
// =========== Rendering ============
|
||||
|
||||
@@ -50,74 +62,55 @@ typedef struct backend_info {
|
||||
/// on the buffer (usually the wallpaper).
|
||||
///
|
||||
/// Optional?
|
||||
void (*prepare)(void *backend_data, session_t *ps, const region_t *reg_paint);
|
||||
void (*prepare)(backend_t *backend_data, const region_t *reg_paint);
|
||||
|
||||
/// Paint the content of the window onto the (possibly buffered)
|
||||
/// Paint the content of an imageonto the (possibly buffered)
|
||||
/// target picture. Always called after render_win(). Maybe called
|
||||
/// multiple times between render_win() and finish_render_win().
|
||||
/// The origin is the top left of the window, exclude the shadow,
|
||||
/// (dst_x, dst_y) refers to where the origin should be in the target
|
||||
/// buffer.
|
||||
void (*compose)(void *backend_data, session_t *ps, win *w, void *win_data,
|
||||
int dst_x, int dst_y, const region_t *reg_paint);
|
||||
void (*compose)(backend_t *backend_data, void *image_data, int dst_x, int dst_y,
|
||||
const region_t *reg_paint);
|
||||
|
||||
/// Blur a given region on of the target.
|
||||
bool (*blur)(void *backend_data, session_t *ps, double opacity, const region_t *)
|
||||
__attribute__((nonnull(1, 2, 4)));
|
||||
bool (*blur)(backend_t *backend_data, double opacity, const region_t *)
|
||||
__attribute__((nonnull(1, 3)));
|
||||
|
||||
/// Present the buffered target picture onto the screen. If target
|
||||
/// is not buffered, this should be NULL. Otherwise, it should always
|
||||
/// be non-NULL.
|
||||
///
|
||||
/// Optional
|
||||
void (*present)(void *backend_data, session_t *ps) __attribute__((nonnull(1, 2)));
|
||||
void (*present)(backend_t *backend_data) __attribute__((nonnull(1)));
|
||||
|
||||
/**
|
||||
* Render the content of a window into an opaque
|
||||
* data structure. Dimming, shadow and color inversion is handled
|
||||
* here.
|
||||
* Bind a X pixmap to the backend's internal image data structure.
|
||||
*
|
||||
* This function is allowed to allocate additional resource needed
|
||||
* for rendering.
|
||||
*
|
||||
* Params:
|
||||
* reg_paint = the paint region, meaning painting should only
|
||||
* be happening within that region. It's in global
|
||||
* coordinates. If NULL, the region of paint is the
|
||||
* whole screen.
|
||||
* @param backend_data backend data
|
||||
* @param pixmap X pixmap to bind
|
||||
* @param fmt information of the pixmap's visual
|
||||
* @param owned whether the ownership of the pixmap is transfered to the backend
|
||||
* @return backend internal data structure bound with this pixmap
|
||||
*/
|
||||
void (*render_win)(void *backend_data, session_t *ps, win *w, void *win_data,
|
||||
const region_t *reg_paint);
|
||||
void *(*bind_pixmap)(backend_t *backend_data, xcb_pixmap_t pixmap,
|
||||
struct xvisual_info fmt, bool owned);
|
||||
|
||||
/// Free resource allocated for rendering. After this function is
|
||||
/// called, compose() won't be called before render_win is called
|
||||
/// another time.
|
||||
///
|
||||
/// Optional
|
||||
void (*finish_render_win)(void *backend_data, session_t *ps, win *w, void *win_data);
|
||||
/// Create a shadow image based on the parameters
|
||||
void *(*render_shadow)(backend_t *backend_data, int width, int height,
|
||||
const conv *kernel, double r, double g, double b);
|
||||
|
||||
// ============ Resource management ===========
|
||||
|
||||
// XXX Thoughts: calling release_win and prepare_win for every config notify
|
||||
// XXX Thoughts: calling release_image and render_* for every config notify
|
||||
// is wasteful, since there can be multiple such notifies per drawing.
|
||||
// But if we don't, it can mean there will be a state where is window is
|
||||
// mapped and visible, but there is no win_data attached to it. We don't
|
||||
// want to break that assumption as for now. We need to reconsider this.
|
||||
|
||||
/// Create a structure to stored additional data needed for rendering a
|
||||
/// window, later used for render() and compose().
|
||||
///
|
||||
/// Backend can assume this function will only be called with visible
|
||||
/// InputOutput windows, and only be called when screen is redirected.
|
||||
///
|
||||
/// Backend can assume size, shape and visual of the window won't change between
|
||||
/// prepare_win() and release_win().
|
||||
void *(*prepare_win)(void *backend_data, session_t *ps, win *w)
|
||||
__attribute__((nonnull(1, 2, 3)));
|
||||
|
||||
/// Free resources allocated by prepare_win()
|
||||
void (*release_win)(void *backend_data, session_t *ps, win *w, void *win_data)
|
||||
__attribute__((nonnull(1, 2, 3)));
|
||||
/// Free resources associated with an image data structure
|
||||
void (*release_image)(backend_t *backend_data, void *img_data)
|
||||
__attribute__((nonnull(1, 2)));
|
||||
|
||||
// =========== Query ===========
|
||||
|
||||
@@ -127,32 +120,44 @@ typedef struct backend_info {
|
||||
/// 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 we only now
|
||||
/// the transparency after the window is rendered
|
||||
bool (*is_win_transparent)(void *backend_data, win *w, void *win_data)
|
||||
__attribute__((nonnull(1, 2)));
|
||||
|
||||
/// Return if the frame window has transparent content. Guaranteed to
|
||||
/// only be called after render_win is called.
|
||||
///
|
||||
/// Same logic as is_win_transparent applies here.
|
||||
bool (*is_frame_transparent)(void *backend_data, win *w, void *win_data)
|
||||
bool (*is_image_transparent)(backend_t *backend_data, void *image_data)
|
||||
__attribute__((nonnull(1, 2)));
|
||||
|
||||
/// Get the age of the buffer content we are currently rendering ontop
|
||||
/// of. The buffer that has just been `present`ed has a buffer age of 1.
|
||||
/// Everytime `present` is called, buffers get older. Return -1 if the
|
||||
/// buffer is empty.
|
||||
int (*buffer_age)(void *backend_data, session_t *);
|
||||
int (*buffer_age)(backend_t *backend_data);
|
||||
|
||||
/// The maximum number buffer_age might return.
|
||||
int max_buffer_age;
|
||||
|
||||
// =========== Post-processing ============
|
||||
/**
|
||||
* Manipulate an image
|
||||
*
|
||||
* @param backend_data backend data
|
||||
* @param op the operation to perform
|
||||
* @param image_data an image data structure returned by the backend
|
||||
* @param reg_paint the clip region, limit the region of the image to be
|
||||
* manipulated
|
||||
* @param args extra arguments, specific to each operation
|
||||
* @return a new image data structure contains the same image as `image_data`
|
||||
*/
|
||||
void (*image_op)(backend_t *backend_data, enum image_operations op,
|
||||
void *image_data, const region_t *reg_paint, void *args);
|
||||
|
||||
void *(*copy)(backend_t *base, const void *image_data, const region_t *reg_copy);
|
||||
|
||||
// =========== Hooks ============
|
||||
/// Let the backend hook into the event handling queue
|
||||
} backend_info_t;
|
||||
};
|
||||
|
||||
extern backend_info_t xrender_backend;
|
||||
extern backend_info_t glx_backend;
|
||||
extern backend_info_t *backend_list[];
|
||||
typedef backend_t *(*backend_init_fn)(session_t *ps) __attribute__((nonnull(1)));
|
||||
|
||||
extern backend_t *backend_xrender_init(session_t *ps);
|
||||
extern backend_t *backend_glx_init(session_t *ps);
|
||||
extern backend_init_fn backend_list[];
|
||||
|
||||
bool default_is_win_transparent(void *, win *, void *);
|
||||
bool default_is_frame_transparent(void *, win *, void *);
|
||||
|
||||
Reference in New Issue
Block a user