summaryrefslogtreecommitdiffstats
path: root/compton.h
diff options
context:
space:
mode:
authorRichard Grenville <[email protected]>2013-03-15 23:16:23 +0800
committerRichard Grenville <[email protected]>2013-03-15 23:16:23 +0800
commitf9f1e1f228ec21be08833f6aa86fe6ea2c64b625 (patch)
treeaab94bd7d31bc3464e4ddcdee9ee792156231738 /compton.h
parent690589bb343f25eec4727748a990b0b60972ed8d (diff)
downloadtdebase-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.h137
1 files changed, 84 insertions, 53 deletions
diff --git a/compton.h b/compton.h
index f0af56482..0479b3d0a 100644
--- a/compton.h
+++ b/compton.h
@@ -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);