diff options
author | Richard Grenville <[email protected]> | 2013-03-15 23:16:23 +0800 |
---|---|---|
committer | Richard Grenville <[email protected]> | 2013-03-15 23:16:23 +0800 |
commit | f9f1e1f228ec21be08833f6aa86fe6ea2c64b625 (patch) | |
tree | aab94bd7d31bc3464e4ddcdee9ee792156231738 /compton.h | |
parent | 690589bb343f25eec4727748a990b0b60972ed8d (diff) | |
download | tdebase-f9f1e1f228ec21be08833f6aa86fe6ea2c64b625.tar.gz tdebase-f9f1e1f228ec21be08833f6aa86fe6ea2c64b625.zip |
Feature: OpenGL backend
- Add experimental OpenGL backend (--opengl). --blur-background is
currently not possible with this backend, because I'm still trying to
find a proper way to do blur with OpenGL. Flipping backend on-the-fly
is really hard, so it isn't supported right now. No configuration file
option exists to enable this, because it isn't stable enough.
- Add `opengl-swc` VSync method that uses SGI_swap_control to control
buffer swap, with OpenGL backend. (#7)
- Fix a potential read-from-freed-memory issue in paint_all().
- Correctly reattach GLX context after fork.
- Dump error text in error(). Add GLX error code handling.
- Code clean-up.
- Known issues: Region operations take a lot of time in glx_render().
I'm hesitating about what to do.
Diffstat (limited to 'compton.h')
-rw-r--r-- | compton.h | 137 |
1 files changed, 84 insertions, 53 deletions
@@ -9,7 +9,6 @@ #include "common.h" -#include <ctype.h> #include <math.h> #include <sys/select.h> #include <limits.h> @@ -53,14 +52,6 @@ static int should_ignore(session_t *ps, unsigned long sequence); /** - * Return the painting target window. - */ -static inline Window -get_tgt_window(session_t *ps) { - return ps->o.paint_on_overlay ? ps->overlay: ps->root; -} - -/** * Reset filter on a <code>Picture</code>. */ static inline void @@ -119,16 +110,6 @@ array_wid_exists(const Window *arr, int count, Window wid) { return false; } -/** - * Destroy a <code>XserverRegion</code>. - */ -inline static void -free_region(session_t *ps, XserverRegion *p) { - if (*p) { - XFixesDestroyRegion(ps->dpy, *p); - *p = None; - } -} /** * Destroy a <code>Picture</code>. @@ -177,15 +158,57 @@ free_wincondlst(c2_lptr_t **pcondlst) { #endif /** + * Check whether a paint_t contains enough data. + */ +static inline bool +paint_isvalid(session_t *ps, const paint_t *ppaint) { + if (!ppaint || !ppaint->pixmap) + return false; + + if (BKEND_XRENDER == ps->o.backend && !ppaint->pict) + return false; + +#ifdef CONFIG_VSYNC_OPENGL + if (BKEND_GLX == ps->o.backend && !glx_tex_binded(ppaint->ptex)) + return false; +#endif + + return true; +} +/** + * Bind texture in paint_t if we are using OpenGL backend. + */ +static inline bool +paint_bind_tex(session_t *ps, paint_t *ppaint, int wid, int hei, int depth) { +#ifdef CONFIG_VSYNC_OPENGL + // TODO: Make sure we have the same Pixmap binded? + if (BKEND_GLX == ps->o.backend && !glx_tex_binded(ppaint->ptex)) { + return glx_bind_pixmap(ps, &ppaint->ptex, ppaint->pixmap, wid, hei, depth); + } +#endif + + return true; +} + +/** + * Free paint_t. + */ +static inline void +free_paint(session_t *ps, paint_t *ppaint) { + free_texture(ps, &ppaint->ptex); + free_picture(ps, &ppaint->pict); + free_pixmap(ps, &ppaint->pixmap); +} + +/** * Destroy all resources in a <code>struct _win</code>. */ -inline static void +static inline void free_win_res(session_t *ps, win *w) { free_region(ps, &w->extents); - free_pixmap(ps, &w->pixmap); - free_picture(ps, &w->picture); + free_paint(ps, &w->paint); free_region(ps, &w->border_size); - free_picture(ps, &w->shadow_pict); + free_paint(ps, &w->shadow_paint); free_damage(ps, &w->damage); free_region(ps, &w->reg_ignore); free(w->name); @@ -195,6 +218,19 @@ free_win_res(session_t *ps, win *w) { } /** + * Free root tile related things. + */ +static inline void +free_root_tile(session_t *ps) { + free_picture(ps, &ps->root_tile_paint.pict); + free_texture(ps, &ps->root_tile_paint.ptex); + if (ps->root_tile_fill) + free_pixmap(ps, &ps->root_tile_paint.pixmap); + ps->root_tile_paint.pixmap = None; + ps->root_tile_fill = false; +} + +/** * Get current system clock in milliseconds. */ static inline time_ms_t @@ -274,8 +310,8 @@ presum_gaussian(session_t *ps, conv *map); static XImage * make_shadow(session_t *ps, double opacity, int width, int height); -static Picture -shadow_picture(session_t *ps, double opacity, int width, int height); +static bool +win_build_shadow(session_t *ps, win *w, double opacity); static Picture solid_picture(session_t *ps, bool argb, double a, @@ -463,11 +499,11 @@ group_is_focused(session_t *ps, Window leader) { static win * recheck_focus(session_t *ps); -static Picture -root_tile_f(session_t *ps); +static bool +get_root_tile(session_t *ps); static void -paint_root(session_t *ps, Picture tgt_buffer); +paint_root(session_t *ps, XserverRegion reg_paint); static XserverRegion win_get_region(session_t *ps, win *w, bool use_offset); @@ -491,6 +527,22 @@ static win * paint_preprocess(session_t *ps, win *list); static void +render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei, + double opacity, bool argb, bool neg, + Picture pict, glx_texture_t *ptex, XserverRegion reg_paint); + +static inline void +win_render(session_t *ps, win *w, int x, int y, int wid, int hei, double opacity, XserverRegion reg_paint, Picture pict) { + const int dx = (w ? w->a.x: 0) + x; + const int dy = (w ? w->a.y: 0) + y; + const bool argb = (w && w->mode == WMODE_ARGB); + const bool neg = (w && w->invert_color); + + render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, + pict, (w ? w->paint.ptex: ps->root_tile_paint.ptex), reg_paint); +} + +static void paint_all(session_t *ps, XserverRegion region, win *t); static void @@ -887,39 +939,15 @@ swopti_init(session_t *ps); static void swopti_handle_timeout(session_t *ps, struct timeval *ptv); -static bool -opengl_init(session_t *ps, bool need_render); - -static void -opengl_destroy(session_t *ps); - #ifdef CONFIG_VSYNC_OPENGL /** - * Check if a GLX extension exists. - */ -static inline bool -opengl_hasext(session_t *ps, const char *ext) { - const char *glx_exts = glXQueryExtensionsString(ps->dpy, ps->scr); - const char *pos = strstr(glx_exts, ext); - // Make sure the extension string is matched as a whole word - if (!pos - || ((pos - glx_exts) && !isspace(*(pos - 1))) - || (strlen(pos) > strlen(ext) && !isspace(pos[strlen(ext)]))) { - printf_errf("(): Missing OpenGL extension %s.", ext); - return false; - } - - return true; -} - -/** * Ensure we have a GLX context. */ static inline bool ensure_glx_context(session_t *ps) { // Create GLX context if (!ps->glx_context) - opengl_init(ps, false); + glx_init(ps, false); return ps->glx_context; } @@ -939,6 +967,9 @@ vsync_opengl_init(session_t *ps); static bool vsync_opengl_oml_init(session_t *ps); +static bool +vsync_opengl_swc_init(session_t *ps); + #ifdef CONFIG_VSYNC_OPENGL static int vsync_opengl_wait(session_t *ps); |