Improvement: Separate GLX parts from session_t & Attempt to fix #217
- Separate GLX parts from session_t into glx_session_t. - Add --rererdir-on-root-change and --glx-reinit-on-root-change, as possible solutions for #217. Thanks to jlindgren90 for reporting.
This commit is contained in:
parent
4e8ccea252
commit
234e3e8cda
169
src/common.h
169
src/common.h
|
@ -443,7 +443,6 @@ struct _glx_texture {
|
||||||
unsigned depth;
|
unsigned depth;
|
||||||
bool y_inverted;
|
bool y_inverted;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -488,6 +487,7 @@ typedef struct {
|
||||||
.unifm_tex = -1, \
|
.unifm_tex = -1, \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -584,6 +584,10 @@ typedef struct _options_t {
|
||||||
switch_t redirected_force;
|
switch_t redirected_force;
|
||||||
/// Whether to stop painting. Controlled through D-Bus.
|
/// Whether to stop painting. Controlled through D-Bus.
|
||||||
switch_t stoppaint_force;
|
switch_t stoppaint_force;
|
||||||
|
/// Whether to re-redirect screen on root size change.
|
||||||
|
bool reredir_on_root_change;
|
||||||
|
/// Whether to reinitialize GLX on root size change.
|
||||||
|
bool glx_reinit_on_root_change;
|
||||||
/// Whether to enable D-Bus support.
|
/// Whether to enable D-Bus support.
|
||||||
bool dbus;
|
bool dbus;
|
||||||
/// Path to log file.
|
/// Path to log file.
|
||||||
|
@ -721,6 +725,65 @@ typedef struct _options_t {
|
||||||
bool track_leader;
|
bool track_leader;
|
||||||
} options_t;
|
} options_t;
|
||||||
|
|
||||||
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
|
/// Structure containing GLX-dependent data for a compton session.
|
||||||
|
typedef struct {
|
||||||
|
// === OpenGL related ===
|
||||||
|
/// GLX context.
|
||||||
|
GLXContext context;
|
||||||
|
/// Whether we have GL_ARB_texture_non_power_of_two.
|
||||||
|
bool has_texture_non_power_of_two;
|
||||||
|
/// Pointer to glXGetVideoSyncSGI function.
|
||||||
|
f_GetVideoSync glXGetVideoSyncSGI;
|
||||||
|
/// Pointer to glXWaitVideoSyncSGI function.
|
||||||
|
f_WaitVideoSync glXWaitVideoSyncSGI;
|
||||||
|
/// Pointer to glXGetSyncValuesOML function.
|
||||||
|
f_GetSyncValuesOML glXGetSyncValuesOML;
|
||||||
|
/// Pointer to glXWaitForMscOML function.
|
||||||
|
f_WaitForMscOML glXWaitForMscOML;
|
||||||
|
/// Pointer to glXSwapIntervalSGI function.
|
||||||
|
f_SwapIntervalSGI glXSwapIntervalProc;
|
||||||
|
/// Pointer to glXSwapIntervalMESA function.
|
||||||
|
f_SwapIntervalMESA glXSwapIntervalMESAProc;
|
||||||
|
/// Pointer to glXBindTexImageEXT function.
|
||||||
|
f_BindTexImageEXT glXBindTexImageProc;
|
||||||
|
/// Pointer to glXReleaseTexImageEXT function.
|
||||||
|
f_ReleaseTexImageEXT glXReleaseTexImageProc;
|
||||||
|
/// Pointer to glXCopySubBufferMESA function.
|
||||||
|
f_CopySubBuffer glXCopySubBufferProc;
|
||||||
|
#ifdef CONFIG_GLX_SYNC
|
||||||
|
/// Pointer to the glFenceSync() function.
|
||||||
|
f_FenceSync glFenceSyncProc;
|
||||||
|
/// Pointer to the glIsSync() function.
|
||||||
|
f_IsSync glIsSyncProc;
|
||||||
|
/// Pointer to the glDeleteSync() function.
|
||||||
|
f_DeleteSync glDeleteSyncProc;
|
||||||
|
/// Pointer to the glClientWaitSync() function.
|
||||||
|
f_ClientWaitSync glClientWaitSyncProc;
|
||||||
|
/// Pointer to the glWaitSync() function.
|
||||||
|
f_WaitSync glWaitSyncProc;
|
||||||
|
/// Pointer to the glImportSyncEXT() function.
|
||||||
|
f_ImportSyncEXT glImportSyncEXT;
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG_GLX_MARK
|
||||||
|
/// Pointer to StringMarkerGREMEDY function.
|
||||||
|
f_StringMarkerGREMEDY glStringMarkerGREMEDY;
|
||||||
|
/// Pointer to FrameTerminatorGREMEDY function.
|
||||||
|
f_FrameTerminatorGREMEDY glFrameTerminatorGREMEDY;
|
||||||
|
#endif
|
||||||
|
/// Current GLX Z value.
|
||||||
|
int z;
|
||||||
|
/// FBConfig-s for GLX pixmap of different depths.
|
||||||
|
glx_fbconfig_t *fbconfigs[OPENGL_MAX_DEPTH + 1];
|
||||||
|
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
||||||
|
glx_blur_pass_t blur_passes[MAX_BLUR_PASS];
|
||||||
|
#endif
|
||||||
|
} glx_session_t;
|
||||||
|
|
||||||
|
#define CGLX_SESSION_INIT { .context = NULL }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Structure containing all necessary data for a compton session.
|
/// Structure containing all necessary data for a compton session.
|
||||||
typedef struct _session_t {
|
typedef struct _session_t {
|
||||||
// === Display related ===
|
// === Display related ===
|
||||||
|
@ -762,6 +825,10 @@ typedef struct _session_t {
|
||||||
XdbeBackBuffer root_dbe;
|
XdbeBackBuffer root_dbe;
|
||||||
/// Window ID of the window we register as a symbol.
|
/// Window ID of the window we register as a symbol.
|
||||||
Window reg_win;
|
Window reg_win;
|
||||||
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
|
/// Pointer to GLX data.
|
||||||
|
glx_session_t *psglx;
|
||||||
|
#endif
|
||||||
|
|
||||||
// === Operation related ===
|
// === Operation related ===
|
||||||
/// Program options.
|
/// Program options.
|
||||||
|
@ -804,10 +871,6 @@ typedef struct _session_t {
|
||||||
/// Pointer to the <code>next</code> member of tail element of the error
|
/// Pointer to the <code>next</code> member of tail element of the error
|
||||||
/// ignore linked list.
|
/// ignore linked list.
|
||||||
ignore_t **ignore_tail;
|
ignore_t **ignore_tail;
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
|
||||||
/// Current GLX Z value.
|
|
||||||
int glx_z;
|
|
||||||
#endif
|
|
||||||
// Cached blur convolution kernels.
|
// Cached blur convolution kernels.
|
||||||
XFixed *blur_kerns_cache[MAX_BLUR_PASS];
|
XFixed *blur_kerns_cache[MAX_BLUR_PASS];
|
||||||
/// Reset program after next paint.
|
/// Reset program after next paint.
|
||||||
|
@ -867,57 +930,6 @@ typedef struct _session_t {
|
||||||
int drm_fd;
|
int drm_fd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
|
||||||
// === OpenGL related ===
|
|
||||||
/// GLX context.
|
|
||||||
GLXContext glx_context;
|
|
||||||
/// Whether we have GL_ARB_texture_non_power_of_two.
|
|
||||||
bool glx_has_texture_non_power_of_two;
|
|
||||||
/// Pointer to glXGetVideoSyncSGI function.
|
|
||||||
f_GetVideoSync glXGetVideoSyncSGI;
|
|
||||||
/// Pointer to glXWaitVideoSyncSGI function.
|
|
||||||
f_WaitVideoSync glXWaitVideoSyncSGI;
|
|
||||||
/// Pointer to glXGetSyncValuesOML function.
|
|
||||||
f_GetSyncValuesOML glXGetSyncValuesOML;
|
|
||||||
/// Pointer to glXWaitForMscOML function.
|
|
||||||
f_WaitForMscOML glXWaitForMscOML;
|
|
||||||
/// Pointer to glXSwapIntervalSGI function.
|
|
||||||
f_SwapIntervalSGI glXSwapIntervalProc;
|
|
||||||
/// Pointer to glXSwapIntervalMESA function.
|
|
||||||
f_SwapIntervalMESA glXSwapIntervalMESAProc;
|
|
||||||
/// Pointer to glXBindTexImageEXT function.
|
|
||||||
f_BindTexImageEXT glXBindTexImageProc;
|
|
||||||
/// Pointer to glXReleaseTexImageEXT function.
|
|
||||||
f_ReleaseTexImageEXT glXReleaseTexImageProc;
|
|
||||||
/// Pointer to glXCopySubBufferMESA function.
|
|
||||||
f_CopySubBuffer glXCopySubBufferProc;
|
|
||||||
#ifdef CONFIG_GLX_SYNC
|
|
||||||
/// Pointer to the glFenceSync() function.
|
|
||||||
f_FenceSync glFenceSyncProc;
|
|
||||||
/// Pointer to the glIsSync() function.
|
|
||||||
f_IsSync glIsSyncProc;
|
|
||||||
/// Pointer to the glDeleteSync() function.
|
|
||||||
f_DeleteSync glDeleteSyncProc;
|
|
||||||
/// Pointer to the glClientWaitSync() function.
|
|
||||||
f_ClientWaitSync glClientWaitSyncProc;
|
|
||||||
/// Pointer to the glWaitSync() function.
|
|
||||||
f_WaitSync glWaitSyncProc;
|
|
||||||
/// Pointer to the glImportSyncEXT() function.
|
|
||||||
f_ImportSyncEXT glImportSyncEXT;
|
|
||||||
#endif
|
|
||||||
#ifdef DEBUG_GLX_MARK
|
|
||||||
/// Pointer to StringMarkerGREMEDY function.
|
|
||||||
f_StringMarkerGREMEDY glStringMarkerGREMEDY;
|
|
||||||
/// Pointer to FrameTerminatorGREMEDY function.
|
|
||||||
f_FrameTerminatorGREMEDY glFrameTerminatorGREMEDY;
|
|
||||||
#endif
|
|
||||||
/// FBConfig-s for GLX pixmap of different depths.
|
|
||||||
glx_fbconfig_t *glx_fbconfigs[OPENGL_MAX_DEPTH + 1];
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
|
||||||
glx_blur_pass_t glx_blur_passes[MAX_BLUR_PASS];
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// === X extension related ===
|
// === X extension related ===
|
||||||
/// Event base number for X Fixes extension.
|
/// Event base number for X Fixes extension.
|
||||||
int xfixes_event;
|
int xfixes_event;
|
||||||
|
@ -1891,6 +1903,18 @@ bkend_use_glx(session_t *ps) {
|
||||||
|| BKEND_XR_GLX_HYBRID == ps->o.backend;
|
|| BKEND_XR_GLX_HYBRID == ps->o.backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there's a GLX context.
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
glx_has_context(session_t *ps) {
|
||||||
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
|
return ps->psglx && ps->psglx->context;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a window is really focused.
|
* Check if a window is really focused.
|
||||||
*/
|
*/
|
||||||
|
@ -2106,6 +2130,9 @@ glx_init(session_t *ps, bool need_render);
|
||||||
void
|
void
|
||||||
glx_destroy(session_t *ps);
|
glx_destroy(session_t *ps);
|
||||||
|
|
||||||
|
bool
|
||||||
|
glx_reinit(session_t *ps, bool need_render);
|
||||||
|
|
||||||
void
|
void
|
||||||
glx_on_root_change(session_t *ps);
|
glx_on_root_change(session_t *ps);
|
||||||
|
|
||||||
|
@ -2194,7 +2221,7 @@ glx_create_program_from_str(const char *vert_shader_str,
|
||||||
static inline void
|
static inline void
|
||||||
free_texture_r(session_t *ps, GLuint *ptexture) {
|
free_texture_r(session_t *ps, GLuint *ptexture) {
|
||||||
if (*ptexture) {
|
if (*ptexture) {
|
||||||
assert(ps->glx_context);
|
assert(glx_has_context(ps));
|
||||||
glDeleteTextures(1, ptexture);
|
glDeleteTextures(1, ptexture);
|
||||||
*ptexture = 0;
|
*ptexture = 0;
|
||||||
}
|
}
|
||||||
|
@ -2260,20 +2287,40 @@ free_texture(session_t *ps, glx_texture_t **pptex) {
|
||||||
assert(!*pptex);
|
assert(!*pptex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free GLX part of paint_t.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
free_paint_glx(session_t *ps, paint_t *ppaint) {
|
||||||
|
free_texture(ps, &ppaint->ptex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free GLX part of win.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
free_win_res_glx(session_t *ps, win *w) {
|
||||||
|
free_paint_glx(ps, &w->paint);
|
||||||
|
free_paint_glx(ps, &w->shadow_paint);
|
||||||
|
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
||||||
|
free_glx_bc(ps, &w->glx_blur_cache);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a OpenGL debugging marker.
|
* Add a OpenGL debugging marker.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
glx_mark_(session_t *ps, const char *func, XID xid, bool start) {
|
glx_mark_(session_t *ps, const char *func, XID xid, bool start) {
|
||||||
#ifdef DEBUG_GLX_MARK
|
#ifdef DEBUG_GLX_MARK
|
||||||
if (bkend_use_glx(ps) && ps->glStringMarkerGREMEDY) {
|
if (glx_has_context(ps) && ps->psglx->glStringMarkerGREMEDY) {
|
||||||
if (!func) func = "(unknown)";
|
if (!func) func = "(unknown)";
|
||||||
const char *postfix = (start ? " (start)": " (end)");
|
const char *postfix = (start ? " (start)": " (end)");
|
||||||
char *str = malloc((strlen(func) + 12 + 2
|
char *str = malloc((strlen(func) + 12 + 2
|
||||||
+ strlen(postfix) + 5) * sizeof(char));
|
+ strlen(postfix) + 5) * sizeof(char));
|
||||||
strcpy(str, func);
|
strcpy(str, func);
|
||||||
sprintf(str + strlen(str), "(%#010lx)%s", xid, postfix);
|
sprintf(str + strlen(str), "(%#010lx)%s", xid, postfix);
|
||||||
ps->glStringMarkerGREMEDY(strlen(str), str);
|
ps->psglx->glStringMarkerGREMEDY(strlen(str), str);
|
||||||
free(str);
|
free(str);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2287,8 +2334,8 @@ glx_mark_(session_t *ps, const char *func, XID xid, bool start) {
|
||||||
static inline void
|
static inline void
|
||||||
glx_mark_frame(session_t *ps) {
|
glx_mark_frame(session_t *ps) {
|
||||||
#ifdef DEBUG_GLX_MARK
|
#ifdef DEBUG_GLX_MARK
|
||||||
if (bkend_use_glx(ps) && ps->glFrameTerminatorGREMEDY)
|
if (glx_has_context(ps) && ps->psglx->glFrameTerminatorGREMEDY)
|
||||||
ps->glFrameTerminatorGREMEDY();
|
ps->psglx->glFrameTerminatorGREMEDY();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
126
src/compton.c
126
src/compton.c
|
@ -492,14 +492,12 @@ win_build_shadow(session_t *ps, win *w, double opacity) {
|
||||||
// Sync it once and only once
|
// Sync it once and only once
|
||||||
xr_sync(ps, w->shadow_paint.pixmap, NULL);
|
xr_sync(ps, w->shadow_paint.pixmap, NULL);
|
||||||
|
|
||||||
bool success = paint_bind_tex(ps, &w->shadow_paint, shadow_image->width, shadow_image->height, 32, true);
|
|
||||||
|
|
||||||
XFreeGC(ps->dpy, gc);
|
XFreeGC(ps->dpy, gc);
|
||||||
XDestroyImage(shadow_image);
|
XDestroyImage(shadow_image);
|
||||||
XFreePixmap(ps->dpy, shadow_pixmap);
|
XFreePixmap(ps->dpy, shadow_pixmap);
|
||||||
XRenderFreePicture(ps->dpy, shadow_picture);
|
XRenderFreePicture(ps->dpy, shadow_picture);
|
||||||
|
|
||||||
return success;
|
return true;
|
||||||
|
|
||||||
shadow_picture_err:
|
shadow_picture_err:
|
||||||
if (shadow_image)
|
if (shadow_image)
|
||||||
|
@ -1309,6 +1307,9 @@ paint_preprocess(session_t *ps, win *list) {
|
||||||
static inline void
|
static inline void
|
||||||
win_paint_shadow(session_t *ps, win *w,
|
win_paint_shadow(session_t *ps, win *w,
|
||||||
XserverRegion reg_paint, const reg_data_t *pcache_reg) {
|
XserverRegion reg_paint, const reg_data_t *pcache_reg) {
|
||||||
|
// Bind shadow pixmap to GLX texture if needed
|
||||||
|
paint_bind_tex(ps, &w->shadow_paint, 0, 0, 32, false);
|
||||||
|
|
||||||
if (!paint_isvalid(ps, &w->shadow_paint)) {
|
if (!paint_isvalid(ps, &w->shadow_paint)) {
|
||||||
printf_errf("(%#010lx): Missing painting data. This is a bad sign.", w->id);
|
printf_errf("(%#010lx): Missing painting data. This is a bad sign.", w->id);
|
||||||
return;
|
return;
|
||||||
|
@ -1486,7 +1487,7 @@ win_blur_background(session_t *ps, win *w, Picture tgt_buffer,
|
||||||
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
||||||
case BKEND_GLX:
|
case BKEND_GLX:
|
||||||
// TODO: Handle frame opacity
|
// TODO: Handle frame opacity
|
||||||
glx_blur_dst(ps, x, y, wid, hei, ps->glx_z - 0.5, factor_center,
|
glx_blur_dst(ps, x, y, wid, hei, ps->psglx->z - 0.5, factor_center,
|
||||||
reg_paint, pcache_reg, &w->glx_blur_cache);
|
reg_paint, pcache_reg, &w->glx_blur_cache);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1519,8 +1520,8 @@ render_(session_t *ps, int x, int y, int dx, int dy, int wid, int hei,
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
case BKEND_GLX:
|
case BKEND_GLX:
|
||||||
glx_render(ps, ptex, x, y, dx, dy, wid, hei,
|
glx_render(ps, ptex, x, y, dx, dy, wid, hei,
|
||||||
ps->glx_z, opacity, argb, neg, reg_paint, pcache_reg, pprogram);
|
ps->psglx->z, opacity, argb, neg, reg_paint, pcache_reg, pprogram);
|
||||||
ps->glx_z += 1;
|
ps->psglx->z += 1;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -1701,7 +1702,7 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
case BKEND_GLX:
|
case BKEND_GLX:
|
||||||
glx_dim_dst(ps, x, y, wid, hei, ps->glx_z - 0.7, dim_opacity,
|
glx_dim_dst(ps, x, y, wid, hei, ps->psglx->z - 0.7, dim_opacity,
|
||||||
reg_paint, pcache_reg);
|
reg_paint, pcache_reg);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1940,7 +1941,7 @@ paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t
|
||||||
// effect
|
// effect
|
||||||
XSync(ps->dpy, False);
|
XSync(ps->dpy, False);
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
if (ps->glx_context) {
|
if (glx_has_context(ps)) {
|
||||||
if (ps->o.vsync_use_glfinish)
|
if (ps->o.vsync_use_glfinish)
|
||||||
glFinish();
|
glFinish();
|
||||||
else
|
else
|
||||||
|
@ -2017,7 +2018,7 @@ paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t
|
||||||
XFlush(ps->dpy);
|
XFlush(ps->dpy);
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
if (ps->glx_context) {
|
if (glx_has_context(ps)) {
|
||||||
glFlush();
|
glFlush();
|
||||||
glXWaitX();
|
glXWaitX();
|
||||||
}
|
}
|
||||||
|
@ -3050,6 +3051,9 @@ restack_win(session_t *ps, win *w, Window new_above) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
init_filters(session_t *ps);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
configure_win(session_t *ps, XConfigureEvent *ce) {
|
configure_win(session_t *ps, XConfigureEvent *ce) {
|
||||||
// On root window changes
|
// On root window changes
|
||||||
|
@ -3063,11 +3067,28 @@ configure_win(session_t *ps, XConfigureEvent *ce) {
|
||||||
rebuild_shadow_exclude_reg(ps);
|
rebuild_shadow_exclude_reg(ps);
|
||||||
free_all_damage_last(ps);
|
free_all_damage_last(ps);
|
||||||
|
|
||||||
|
// Re-redirect screen if required
|
||||||
|
if (ps->o.reredir_on_root_change && ps->redirected) {
|
||||||
|
redir_stop(ps);
|
||||||
|
redir_start(ps);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
|
// Reinitialize GLX on root change
|
||||||
|
if (ps->o.glx_reinit_on_root_change && ps->psglx) {
|
||||||
|
if (!glx_reinit(ps, bkend_use_glx(ps)))
|
||||||
|
printf_errf("(): Failed to reinitialize GLX, troubles ahead.");
|
||||||
|
if (BKEND_GLX == ps->o.backend && !init_filters(ps))
|
||||||
|
printf_errf("(): Failed to initialize filters.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// GLX root change callback
|
||||||
if (BKEND_GLX == ps->o.backend)
|
if (BKEND_GLX == ps->o.backend)
|
||||||
glx_on_root_change(ps);
|
glx_on_root_change(ps);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
force_repaint(ps);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4807,7 +4828,7 @@ fork_after(session_t *ps) {
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
// GLX context must be released and reattached on fork
|
// GLX context must be released and reattached on fork
|
||||||
if (ps->glx_context && !glXMakeCurrent(ps->dpy, None, NULL)) {
|
if (glx_has_context(ps) && !glXMakeCurrent(ps->dpy, None, NULL)) {
|
||||||
printf_errf("(): Failed to detach GLx context.");
|
printf_errf("(): Failed to detach GLx context.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4825,8 +4846,8 @@ fork_after(session_t *ps) {
|
||||||
setsid();
|
setsid();
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
#ifdef CONFIG_VSYNC_OPENGL
|
||||||
if (ps->glx_context
|
if (glx_has_context(ps)
|
||||||
&& !glXMakeCurrent(ps->dpy, get_tgt_window(ps), ps->glx_context)) {
|
&& !glXMakeCurrent(ps->dpy, get_tgt_window(ps), ps->psglx->context)) {
|
||||||
printf_errf("(): Failed to make GLX context current.");
|
printf_errf("(): Failed to make GLX context current.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5617,6 +5638,8 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
|
||||||
{ "glx-fshader-win", required_argument, NULL, 317 },
|
{ "glx-fshader-win", required_argument, NULL, 317 },
|
||||||
{ "version", no_argument, NULL, 318 },
|
{ "version", no_argument, NULL, 318 },
|
||||||
{ "no-x-selection", no_argument, NULL, 319 },
|
{ "no-x-selection", no_argument, NULL, 319 },
|
||||||
|
{ "reredir-on-root-change", no_argument, NULL, 731 },
|
||||||
|
{ "glx-reinit-on-root-change", no_argument, NULL, 732 },
|
||||||
// Must terminate with a NULL entry
|
// Must terminate with a NULL entry
|
||||||
{ NULL, 0, NULL, 0 },
|
{ NULL, 0, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
@ -5883,6 +5906,8 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
|
||||||
ps->o.glx_fshader_win_str = mstrcpy(optarg);
|
ps->o.glx_fshader_win_str = mstrcpy(optarg);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(319, no_x_selection);
|
P_CASEBOOL(319, no_x_selection);
|
||||||
|
P_CASEBOOL(731, reredir_on_root_change);
|
||||||
|
P_CASEBOOL(732, glx_reinit_on_root_change);
|
||||||
default:
|
default:
|
||||||
usage(1);
|
usage(1);
|
||||||
break;
|
break;
|
||||||
|
@ -6166,13 +6191,13 @@ vsync_opengl_init(session_t *ps) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Get video sync functions
|
// Get video sync functions
|
||||||
if (!ps->glXGetVideoSyncSGI)
|
if (!ps->psglx->glXGetVideoSyncSGI)
|
||||||
ps->glXGetVideoSyncSGI = (f_GetVideoSync)
|
ps->psglx->glXGetVideoSyncSGI = (f_GetVideoSync)
|
||||||
glXGetProcAddress((const GLubyte *) "glXGetVideoSyncSGI");
|
glXGetProcAddress((const GLubyte *) "glXGetVideoSyncSGI");
|
||||||
if (!ps->glXWaitVideoSyncSGI)
|
if (!ps->psglx->glXWaitVideoSyncSGI)
|
||||||
ps->glXWaitVideoSyncSGI = (f_WaitVideoSync)
|
ps->psglx->glXWaitVideoSyncSGI = (f_WaitVideoSync)
|
||||||
glXGetProcAddress((const GLubyte *) "glXWaitVideoSyncSGI");
|
glXGetProcAddress((const GLubyte *) "glXWaitVideoSyncSGI");
|
||||||
if (!ps->glXWaitVideoSyncSGI || !ps->glXGetVideoSyncSGI) {
|
if (!ps->psglx->glXWaitVideoSyncSGI || !ps->psglx->glXGetVideoSyncSGI) {
|
||||||
printf_errf("(): Failed to get glXWait/GetVideoSyncSGI function.");
|
printf_errf("(): Failed to get glXWait/GetVideoSyncSGI function.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6191,13 +6216,13 @@ vsync_opengl_oml_init(session_t *ps) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Get video sync functions
|
// Get video sync functions
|
||||||
if (!ps->glXGetSyncValuesOML)
|
if (!ps->psglx->glXGetSyncValuesOML)
|
||||||
ps->glXGetSyncValuesOML = (f_GetSyncValuesOML)
|
ps->psglx->glXGetSyncValuesOML = (f_GetSyncValuesOML)
|
||||||
glXGetProcAddress ((const GLubyte *) "glXGetSyncValuesOML");
|
glXGetProcAddress ((const GLubyte *) "glXGetSyncValuesOML");
|
||||||
if (!ps->glXWaitForMscOML)
|
if (!ps->psglx->glXWaitForMscOML)
|
||||||
ps->glXWaitForMscOML = (f_WaitForMscOML)
|
ps->psglx->glXWaitForMscOML = (f_WaitForMscOML)
|
||||||
glXGetProcAddress ((const GLubyte *) "glXWaitForMscOML");
|
glXGetProcAddress ((const GLubyte *) "glXWaitForMscOML");
|
||||||
if (!ps->glXGetSyncValuesOML || !ps->glXWaitForMscOML) {
|
if (!ps->psglx->glXGetSyncValuesOML || !ps->psglx->glXWaitForMscOML) {
|
||||||
printf_errf("(): Failed to get OML_sync_control functions.");
|
printf_errf("(): Failed to get OML_sync_control functions.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6221,14 +6246,14 @@ vsync_opengl_swc_init(session_t *ps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get video sync functions
|
// Get video sync functions
|
||||||
if (!ps->glXSwapIntervalProc)
|
if (!ps->psglx->glXSwapIntervalProc)
|
||||||
ps->glXSwapIntervalProc = (f_SwapIntervalSGI)
|
ps->psglx->glXSwapIntervalProc = (f_SwapIntervalSGI)
|
||||||
glXGetProcAddress ((const GLubyte *) "glXSwapIntervalSGI");
|
glXGetProcAddress ((const GLubyte *) "glXSwapIntervalSGI");
|
||||||
if (!ps->glXSwapIntervalProc) {
|
if (!ps->psglx->glXSwapIntervalProc) {
|
||||||
printf_errf("(): Failed to get SGI_swap_control function.");
|
printf_errf("(): Failed to get SGI_swap_control function.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ps->glXSwapIntervalProc(1);
|
ps->psglx->glXSwapIntervalProc(1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
|
@ -6249,14 +6274,14 @@ vsync_opengl_mswc_init(session_t *ps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get video sync functions
|
// Get video sync functions
|
||||||
if (!ps->glXSwapIntervalMESAProc)
|
if (!ps->psglx->glXSwapIntervalMESAProc)
|
||||||
ps->glXSwapIntervalMESAProc = (f_SwapIntervalMESA)
|
ps->psglx->glXSwapIntervalMESAProc = (f_SwapIntervalMESA)
|
||||||
glXGetProcAddress ((const GLubyte *) "glXSwapIntervalMESA");
|
glXGetProcAddress ((const GLubyte *) "glXSwapIntervalMESA");
|
||||||
if (!ps->glXSwapIntervalMESAProc) {
|
if (!ps->psglx->glXSwapIntervalMESAProc) {
|
||||||
printf_errf("(): Failed to get MESA_swap_control function.");
|
printf_errf("(): Failed to get MESA_swap_control function.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ps->glXSwapIntervalMESAProc(1);
|
ps->psglx->glXSwapIntervalMESAProc(1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
|
@ -6273,8 +6298,8 @@ static int
|
||||||
vsync_opengl_wait(session_t *ps) {
|
vsync_opengl_wait(session_t *ps) {
|
||||||
unsigned vblank_count = 0;
|
unsigned vblank_count = 0;
|
||||||
|
|
||||||
ps->glXGetVideoSyncSGI(&vblank_count);
|
ps->psglx->glXGetVideoSyncSGI(&vblank_count);
|
||||||
ps->glXWaitVideoSyncSGI(2, (vblank_count + 1) % 2, &vblank_count);
|
ps->psglx->glXWaitVideoSyncSGI(2, (vblank_count + 1) % 2, &vblank_count);
|
||||||
// I see some code calling glXSwapIntervalSGI(1) afterwards, is it required?
|
// I see some code calling glXSwapIntervalSGI(1) afterwards, is it required?
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -6289,8 +6314,8 @@ static int
|
||||||
vsync_opengl_oml_wait(session_t *ps) {
|
vsync_opengl_oml_wait(session_t *ps) {
|
||||||
int64_t ust = 0, msc = 0, sbc = 0;
|
int64_t ust = 0, msc = 0, sbc = 0;
|
||||||
|
|
||||||
ps->glXGetSyncValuesOML(ps->dpy, ps->reg_win, &ust, &msc, &sbc);
|
ps->psglx->glXGetSyncValuesOML(ps->dpy, ps->reg_win, &ust, &msc, &sbc);
|
||||||
ps->glXWaitForMscOML(ps->dpy, ps->reg_win, 0, 2, (msc + 1) % 2,
|
ps->psglx->glXWaitForMscOML(ps->dpy, ps->reg_win, 0, 2, (msc + 1) % 2,
|
||||||
&ust, &msc, &sbc);
|
&ust, &msc, &sbc);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -6299,14 +6324,14 @@ vsync_opengl_oml_wait(session_t *ps) {
|
||||||
static void
|
static void
|
||||||
vsync_opengl_swc_deinit(session_t *ps) {
|
vsync_opengl_swc_deinit(session_t *ps) {
|
||||||
// The standard says it doesn't accept 0, but in fact it probably does
|
// The standard says it doesn't accept 0, but in fact it probably does
|
||||||
if (ps->glx_context && ps->glXSwapIntervalProc)
|
if (glx_has_context(ps) && ps->psglx->glXSwapIntervalProc)
|
||||||
ps->glXSwapIntervalProc(0);
|
ps->psglx->glXSwapIntervalProc(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vsync_opengl_mswc_deinit(session_t *ps) {
|
vsync_opengl_mswc_deinit(session_t *ps) {
|
||||||
if (ps->glx_context && ps->glXSwapIntervalMESAProc)
|
if (glx_has_context(ps) && ps->psglx->glXSwapIntervalMESAProc)
|
||||||
ps->glXSwapIntervalMESAProc(0);
|
ps->psglx->glXSwapIntervalMESAProc(0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -6343,7 +6368,6 @@ void
|
||||||
vsync_deinit(session_t *ps) {
|
vsync_deinit(session_t *ps) {
|
||||||
if (ps->o.vsync && VSYNC_FUNCS_DEINIT[ps->o.vsync])
|
if (ps->o.vsync && VSYNC_FUNCS_DEINIT[ps->o.vsync])
|
||||||
VSYNC_FUNCS_DEINIT[ps->o.vsync](ps);
|
VSYNC_FUNCS_DEINIT[ps->o.vsync](ps);
|
||||||
ps->o.vsync = VSYNC_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6383,7 +6407,7 @@ init_dbe(session_t *ps) {
|
||||||
/**
|
/**
|
||||||
* Initialize X composite overlay window.
|
* Initialize X composite overlay window.
|
||||||
*/
|
*/
|
||||||
static void
|
static bool
|
||||||
init_overlay(session_t *ps) {
|
init_overlay(session_t *ps) {
|
||||||
ps->overlay = XCompositeGetOverlayWindow(ps->dpy, ps->root);
|
ps->overlay = XCompositeGetOverlayWindow(ps->dpy, ps->root);
|
||||||
if (ps->overlay) {
|
if (ps->overlay) {
|
||||||
|
@ -6411,6 +6435,11 @@ init_overlay(session_t *ps) {
|
||||||
"back to painting on root window.\n");
|
"back to painting on root window.\n");
|
||||||
ps->o.paint_on_overlay = false;
|
ps->o.paint_on_overlay = false;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_REDIR
|
||||||
|
printf_dbgf("(): overlay = %#010lx\n", ps->overlay);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ps->overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6940,15 +6969,6 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
.drm_fd = -1,
|
.drm_fd = -1,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL
|
|
||||||
.glx_context = None,
|
|
||||||
.glx_has_texture_non_power_of_two = false,
|
|
||||||
.glXGetVideoSyncSGI = NULL,
|
|
||||||
.glXWaitVideoSyncSGI = NULL,
|
|
||||||
.glXGetSyncValuesOML = NULL,
|
|
||||||
.glXWaitForMscOML = NULL,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.xfixes_event = 0,
|
.xfixes_event = 0,
|
||||||
.xfixes_error = 0,
|
.xfixes_error = 0,
|
||||||
.damage_event = 0,
|
.damage_event = 0,
|
||||||
|
@ -6996,14 +7016,6 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
// Allocate a session and copy default values into it
|
// Allocate a session and copy default values into it
|
||||||
session_t *ps = malloc(sizeof(session_t));
|
session_t *ps = malloc(sizeof(session_t));
|
||||||
memcpy(ps, &s_def, sizeof(session_t));
|
memcpy(ps, &s_def, sizeof(session_t));
|
||||||
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
|
||||||
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
|
||||||
glx_blur_pass_t *ppass = &ps->glx_blur_passes[i];
|
|
||||||
ppass->unifm_factor_center = -1;
|
|
||||||
ppass->unifm_offset_x = -1;
|
|
||||||
ppass->unifm_offset_y = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ps_g = ps;
|
ps_g = ps;
|
||||||
ps->ignore_tail = &ps->ignore_head;
|
ps->ignore_tail = &ps->ignore_head;
|
||||||
gettimeofday(&ps->time_start, NULL);
|
gettimeofday(&ps->time_start, NULL);
|
||||||
|
|
|
@ -270,7 +270,7 @@ free_reg_data(reg_data_t *pregd) {
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
free_paint(session_t *ps, paint_t *ppaint) {
|
free_paint(session_t *ps, paint_t *ppaint) {
|
||||||
free_texture(ps, &ppaint->ptex);
|
free_paint_glx(ps, ppaint);
|
||||||
free_picture(ps, &ppaint->pict);
|
free_picture(ps, &ppaint->pict);
|
||||||
free_pixmap(ps, &ppaint->pixmap);
|
free_pixmap(ps, &ppaint->pixmap);
|
||||||
}
|
}
|
||||||
|
@ -289,6 +289,7 @@ free_wpaint(session_t *ps, win *w) {
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
free_win_res(session_t *ps, win *w) {
|
free_win_res(session_t *ps, win *w) {
|
||||||
|
free_win_res_glx(ps, w);
|
||||||
free_region(ps, &w->extents);
|
free_region(ps, &w->extents);
|
||||||
free_paint(ps, &w->paint);
|
free_paint(ps, &w->paint);
|
||||||
free_region(ps, &w->border_size);
|
free_region(ps, &w->border_size);
|
||||||
|
@ -299,9 +300,6 @@ free_win_res(session_t *ps, win *w) {
|
||||||
free(w->class_instance);
|
free(w->class_instance);
|
||||||
free(w->class_general);
|
free(w->class_general);
|
||||||
free(w->role);
|
free(w->role);
|
||||||
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
|
||||||
free_glx_bc(ps, &w->glx_blur_cache);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1224,10 +1222,10 @@ swopti_handle_timeout(session_t *ps, struct timeval *ptv);
|
||||||
static inline bool
|
static inline bool
|
||||||
ensure_glx_context(session_t *ps) {
|
ensure_glx_context(session_t *ps) {
|
||||||
// Create GLX context
|
// Create GLX context
|
||||||
if (!ps->glx_context)
|
if (!glx_has_context(ps))
|
||||||
glx_init(ps, false);
|
glx_init(ps, false);
|
||||||
|
|
||||||
return ps->glx_context;
|
return ps->psglx->context;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1274,7 +1272,7 @@ init_alpha_picts(session_t *ps);
|
||||||
static bool
|
static bool
|
||||||
init_dbe(session_t *ps);
|
init_dbe(session_t *ps);
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
init_overlay(session_t *ps);
|
init_overlay(session_t *ps);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
164
src/opengl.c
164
src/opengl.c
|
@ -14,15 +14,15 @@
|
||||||
void
|
void
|
||||||
xr_glx_sync(session_t *ps, Drawable d, XSyncFence *pfence) {
|
xr_glx_sync(session_t *ps, Drawable d, XSyncFence *pfence) {
|
||||||
if (*pfence) {
|
if (*pfence) {
|
||||||
// GLsync sync = ps->glFenceSyncProc(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
// GLsync sync = ps->psglx->glFenceSyncProc(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
GLsync sync = ps->glImportSyncEXT(GL_SYNC_X11_FENCE_EXT, *pfence, 0);
|
GLsync sync = ps->psglx->glImportSyncEXT(GL_SYNC_X11_FENCE_EXT, *pfence, 0);
|
||||||
/* GLenum ret = ps->glClientWaitSyncProc(sync, GL_SYNC_FLUSH_COMMANDS_BIT,
|
/* GLenum ret = ps->psglx->glClientWaitSyncProc(sync, GL_SYNC_FLUSH_COMMANDS_BIT,
|
||||||
1000);
|
1000);
|
||||||
assert(GL_CONDITION_SATISFIED == ret); */
|
assert(GL_CONDITION_SATISFIED == ret); */
|
||||||
XSyncTriggerFence(ps->dpy, *pfence);
|
XSyncTriggerFence(ps->dpy, *pfence);
|
||||||
XFlush(ps->dpy);
|
XFlush(ps->dpy);
|
||||||
ps->glWaitSyncProc(sync, 0, GL_TIMEOUT_IGNORED);
|
ps->psglx->glWaitSyncProc(sync, 0, GL_TIMEOUT_IGNORED);
|
||||||
// ps->glDeleteSyncProc(sync);
|
// ps->psglx->glDeleteSyncProc(sync);
|
||||||
// XSyncResetFence(ps->dpy, *pfence);
|
// XSyncResetFence(ps->dpy, *pfence);
|
||||||
}
|
}
|
||||||
glx_check_err(ps);
|
glx_check_err(ps);
|
||||||
|
@ -98,10 +98,26 @@ glx_init(session_t *ps, bool need_render) {
|
||||||
if (need_render && !glx_hasglxext(ps, "GLX_EXT_texture_from_pixmap"))
|
if (need_render && !glx_hasglxext(ps, "GLX_EXT_texture_from_pixmap"))
|
||||||
goto glx_init_end;
|
goto glx_init_end;
|
||||||
|
|
||||||
if (!ps->glx_context) {
|
// Initialize GLX data structure
|
||||||
|
if (!ps->psglx) {
|
||||||
|
static const glx_session_t CGLX_SESSION_DEF = CGLX_SESSION_INIT;
|
||||||
|
ps->psglx = cmalloc(1, glx_session_t);
|
||||||
|
memcpy(ps->psglx, &CGLX_SESSION_DEF, sizeof(glx_session_t));
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
||||||
|
glx_blur_pass_t *ppass = &ps->psglx->blur_passes[i];
|
||||||
|
ppass->unifm_factor_center = -1;
|
||||||
|
ppass->unifm_offset_x = -1;
|
||||||
|
ppass->unifm_offset_y = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glx_session_t *psglx = ps->psglx;
|
||||||
|
|
||||||
|
if (!psglx->context) {
|
||||||
// Get GLX context
|
// Get GLX context
|
||||||
#ifndef DEBUG_GLX_DEBUG_CONTEXT
|
#ifndef DEBUG_GLX_DEBUG_CONTEXT
|
||||||
ps->glx_context = glXCreateContext(ps->dpy, pvis, None, GL_TRUE);
|
psglx->context = glXCreateContext(ps->dpy, pvis, None, GL_TRUE);
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
GLXFBConfig fbconfig = get_fbconfig_from_visualinfo(ps, pvis);
|
GLXFBConfig fbconfig = get_fbconfig_from_visualinfo(ps, pvis);
|
||||||
|
@ -123,18 +139,18 @@ glx_init(session_t *ps, bool need_render) {
|
||||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
|
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
ps->glx_context = p_glXCreateContextAttribsARB(ps->dpy, fbconfig, NULL,
|
psglx->context = p_glXCreateContextAttribsARB(ps->dpy, fbconfig, NULL,
|
||||||
GL_TRUE, attrib_list);
|
GL_TRUE, attrib_list);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!ps->glx_context) {
|
if (!psglx->context) {
|
||||||
printf_errf("(): Failed to get GLX context.");
|
printf_errf("(): Failed to get GLX context.");
|
||||||
goto glx_init_end;
|
goto glx_init_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach GLX context
|
// Attach GLX context
|
||||||
if (!glXMakeCurrent(ps->dpy, get_tgt_window(ps), ps->glx_context)) {
|
if (!glXMakeCurrent(ps->dpy, get_tgt_window(ps), psglx->context)) {
|
||||||
printf_errf("(): Failed to attach GLX context.");
|
printf_errf("(): Failed to attach GLX context.");
|
||||||
goto glx_init_end;
|
goto glx_init_end;
|
||||||
}
|
}
|
||||||
|
@ -169,52 +185,52 @@ glx_init(session_t *ps, bool need_render) {
|
||||||
// Check GL_ARB_texture_non_power_of_two, requires a GLX context and
|
// Check GL_ARB_texture_non_power_of_two, requires a GLX context and
|
||||||
// must precede FBConfig fetching
|
// must precede FBConfig fetching
|
||||||
if (need_render)
|
if (need_render)
|
||||||
ps->glx_has_texture_non_power_of_two = glx_hasglext(ps,
|
psglx->has_texture_non_power_of_two = glx_hasglext(ps,
|
||||||
"GL_ARB_texture_non_power_of_two");
|
"GL_ARB_texture_non_power_of_two");
|
||||||
|
|
||||||
// Acquire function addresses
|
// Acquire function addresses
|
||||||
if (need_render) {
|
if (need_render) {
|
||||||
#ifdef DEBUG_GLX_MARK
|
#ifdef DEBUG_GLX_MARK
|
||||||
ps->glStringMarkerGREMEDY = (f_StringMarkerGREMEDY)
|
psglx->glStringMarkerGREMEDY = (f_StringMarkerGREMEDY)
|
||||||
glXGetProcAddress((const GLubyte *) "glStringMarkerGREMEDY");
|
glXGetProcAddress((const GLubyte *) "glStringMarkerGREMEDY");
|
||||||
ps->glFrameTerminatorGREMEDY = (f_FrameTerminatorGREMEDY)
|
psglx->glFrameTerminatorGREMEDY = (f_FrameTerminatorGREMEDY)
|
||||||
glXGetProcAddress((const GLubyte *) "glFrameTerminatorGREMEDY");
|
glXGetProcAddress((const GLubyte *) "glFrameTerminatorGREMEDY");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ps->glXBindTexImageProc = (f_BindTexImageEXT)
|
psglx->glXBindTexImageProc = (f_BindTexImageEXT)
|
||||||
glXGetProcAddress((const GLubyte *) "glXBindTexImageEXT");
|
glXGetProcAddress((const GLubyte *) "glXBindTexImageEXT");
|
||||||
ps->glXReleaseTexImageProc = (f_ReleaseTexImageEXT)
|
psglx->glXReleaseTexImageProc = (f_ReleaseTexImageEXT)
|
||||||
glXGetProcAddress((const GLubyte *) "glXReleaseTexImageEXT");
|
glXGetProcAddress((const GLubyte *) "glXReleaseTexImageEXT");
|
||||||
if (!ps->glXBindTexImageProc || !ps->glXReleaseTexImageProc) {
|
if (!psglx->glXBindTexImageProc || !psglx->glXReleaseTexImageProc) {
|
||||||
printf_errf("(): Failed to acquire glXBindTexImageEXT() / glXReleaseTexImageEXT().");
|
printf_errf("(): Failed to acquire glXBindTexImageEXT() / glXReleaseTexImageEXT().");
|
||||||
goto glx_init_end;
|
goto glx_init_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps->o.glx_use_copysubbuffermesa) {
|
if (ps->o.glx_use_copysubbuffermesa) {
|
||||||
ps->glXCopySubBufferProc = (f_CopySubBuffer)
|
psglx->glXCopySubBufferProc = (f_CopySubBuffer)
|
||||||
glXGetProcAddress((const GLubyte *) "glXCopySubBufferMESA");
|
glXGetProcAddress((const GLubyte *) "glXCopySubBufferMESA");
|
||||||
if (!ps->glXCopySubBufferProc) {
|
if (!psglx->glXCopySubBufferProc) {
|
||||||
printf_errf("(): Failed to acquire glXCopySubBufferMESA().");
|
printf_errf("(): Failed to acquire glXCopySubBufferMESA().");
|
||||||
goto glx_init_end;
|
goto glx_init_end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_GLX_SYNC
|
#ifdef CONFIG_GLX_SYNC
|
||||||
ps->glFenceSyncProc = (f_FenceSync)
|
psglx->glFenceSyncProc = (f_FenceSync)
|
||||||
glXGetProcAddress((const GLubyte *) "glFenceSync");
|
glXGetProcAddress((const GLubyte *) "glFenceSync");
|
||||||
ps->glIsSyncProc = (f_IsSync)
|
psglx->glIsSyncProc = (f_IsSync)
|
||||||
glXGetProcAddress((const GLubyte *) "glIsSync");
|
glXGetProcAddress((const GLubyte *) "glIsSync");
|
||||||
ps->glDeleteSyncProc = (f_DeleteSync)
|
psglx->glDeleteSyncProc = (f_DeleteSync)
|
||||||
glXGetProcAddress((const GLubyte *) "glDeleteSync");
|
glXGetProcAddress((const GLubyte *) "glDeleteSync");
|
||||||
ps->glClientWaitSyncProc = (f_ClientWaitSync)
|
psglx->glClientWaitSyncProc = (f_ClientWaitSync)
|
||||||
glXGetProcAddress((const GLubyte *) "glClientWaitSync");
|
glXGetProcAddress((const GLubyte *) "glClientWaitSync");
|
||||||
ps->glWaitSyncProc = (f_WaitSync)
|
psglx->glWaitSyncProc = (f_WaitSync)
|
||||||
glXGetProcAddress((const GLubyte *) "glWaitSync");
|
glXGetProcAddress((const GLubyte *) "glWaitSync");
|
||||||
ps->glImportSyncEXT = (f_ImportSyncEXT)
|
psglx->glImportSyncEXT = (f_ImportSyncEXT)
|
||||||
glXGetProcAddress((const GLubyte *) "glImportSyncEXT");
|
glXGetProcAddress((const GLubyte *) "glImportSyncEXT");
|
||||||
if (!ps->glFenceSyncProc || !ps->glIsSyncProc || !ps->glDeleteSyncProc
|
if (!psglx->glFenceSyncProc || !psglx->glIsSyncProc || !psglx->glDeleteSyncProc
|
||||||
|| !ps->glClientWaitSyncProc || !ps->glWaitSyncProc
|
|| !psglx->glClientWaitSyncProc || !psglx->glWaitSyncProc
|
||||||
|| !ps->glImportSyncEXT) {
|
|| !psglx->glImportSyncEXT) {
|
||||||
printf_errf("(): Failed to acquire GLX sync functions.");
|
printf_errf("(): Failed to acquire GLX sync functions.");
|
||||||
goto glx_init_end;
|
goto glx_init_end;
|
||||||
}
|
}
|
||||||
|
@ -281,10 +297,17 @@ glx_free_prog_main(session_t *ps, glx_prog_main_t *pprogram) {
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
glx_destroy(session_t *ps) {
|
glx_destroy(session_t *ps) {
|
||||||
|
if (!ps->psglx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Free all GLX resources of windows
|
||||||
|
for (win *w = ps->list; w; w = w->next)
|
||||||
|
free_win_res_glx(ps, w);
|
||||||
|
|
||||||
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
||||||
// Free GLSL shaders/programs
|
// Free GLSL shaders/programs
|
||||||
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
for (int i = 0; i < MAX_BLUR_PASS; ++i) {
|
||||||
glx_blur_pass_t *ppass = &ps->glx_blur_passes[i];
|
glx_blur_pass_t *ppass = &ps->psglx->blur_passes[i];
|
||||||
if (ppass->frag_shader)
|
if (ppass->frag_shader)
|
||||||
glDeleteShader(ppass->frag_shader);
|
glDeleteShader(ppass->frag_shader);
|
||||||
if (ppass->prog)
|
if (ppass->prog)
|
||||||
|
@ -298,15 +321,40 @@ glx_destroy(session_t *ps) {
|
||||||
|
|
||||||
// Free FBConfigs
|
// Free FBConfigs
|
||||||
for (int i = 0; i <= OPENGL_MAX_DEPTH; ++i) {
|
for (int i = 0; i <= OPENGL_MAX_DEPTH; ++i) {
|
||||||
free(ps->glx_fbconfigs[i]);
|
free(ps->psglx->fbconfigs[i]);
|
||||||
ps->glx_fbconfigs[i] = NULL;
|
ps->psglx->fbconfigs[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy GLX context
|
// Destroy GLX context
|
||||||
if (ps->glx_context) {
|
if (ps->psglx->context) {
|
||||||
glXDestroyContext(ps->dpy, ps->glx_context);
|
glXDestroyContext(ps->dpy, ps->psglx->context);
|
||||||
ps->glx_context = NULL;
|
ps->psglx->context = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(ps->psglx);
|
||||||
|
ps->psglx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reinitialize GLX.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
glx_reinit(session_t *ps, bool need_render) {
|
||||||
|
// Reinitialize VSync as well
|
||||||
|
vsync_deinit(ps);
|
||||||
|
|
||||||
|
glx_destroy(ps);
|
||||||
|
if (!glx_init(ps, need_render)) {
|
||||||
|
printf_errf("(): Failed to initialize GLX.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vsync_init(ps)) {
|
||||||
|
printf_errf("(): Failed to initialize VSync.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -376,7 +424,7 @@ glx_init_blur(session_t *ps) {
|
||||||
" gl_FragColor = sum / (factor_center + float(%.7g));\n"
|
" gl_FragColor = sum / (factor_center + float(%.7g));\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
const bool use_texture_rect = !ps->glx_has_texture_non_power_of_two;
|
const bool use_texture_rect = !ps->psglx->has_texture_non_power_of_two;
|
||||||
const char *sampler_type = (use_texture_rect ?
|
const char *sampler_type = (use_texture_rect ?
|
||||||
"sampler2DRect": "sampler2D");
|
"sampler2DRect": "sampler2D");
|
||||||
const char *texture_func = (use_texture_rect ?
|
const char *texture_func = (use_texture_rect ?
|
||||||
|
@ -395,7 +443,7 @@ glx_init_blur(session_t *ps) {
|
||||||
if (!kern)
|
if (!kern)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
glx_blur_pass_t *ppass = &ps->glx_blur_passes[i];
|
glx_blur_pass_t *ppass = &ps->psglx->blur_passes[i];
|
||||||
|
|
||||||
// Build shader
|
// Build shader
|
||||||
{
|
{
|
||||||
|
@ -527,15 +575,15 @@ glx_update_fbconfig_bydepth(session_t *ps, int depth, glx_fbconfig_t *pfbcfg) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Compare new FBConfig with current one
|
// Compare new FBConfig with current one
|
||||||
if (glx_cmp_fbconfig(ps, ps->glx_fbconfigs[depth], pfbcfg) < 0) {
|
if (glx_cmp_fbconfig(ps, ps->psglx->fbconfigs[depth], pfbcfg) < 0) {
|
||||||
#ifdef DEBUG_GLX
|
#ifdef DEBUG_GLX
|
||||||
printf_dbgf("(%d): %#x overrides %#x, target %#x.\n", depth, (unsigned) pfbcfg->cfg, (ps->glx_fbconfigs[depth] ? (unsigned) ps->glx_fbconfigs[depth]->cfg: 0), pfbcfg->texture_tgts);
|
printf_dbgf("(%d): %#x overrides %#x, target %#x.\n", depth, (unsigned) pfbcfg->cfg, (ps->psglx->fbconfigs[depth] ? (unsigned) ps->psglx->fbconfigs[depth]->cfg: 0), pfbcfg->texture_tgts);
|
||||||
#endif
|
#endif
|
||||||
if (!ps->glx_fbconfigs[depth]) {
|
if (!ps->psglx->fbconfigs[depth]) {
|
||||||
ps->glx_fbconfigs[depth] = malloc(sizeof(glx_fbconfig_t));
|
ps->psglx->fbconfigs[depth] = malloc(sizeof(glx_fbconfig_t));
|
||||||
allocchk(ps->glx_fbconfigs[depth]);
|
allocchk(ps->psglx->fbconfigs[depth]);
|
||||||
}
|
}
|
||||||
(*ps->glx_fbconfigs[depth]) = *pfbcfg;
|
(*ps->psglx->fbconfigs[depth]) = *pfbcfg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -617,19 +665,19 @@ glx_update_fbconfig(session_t *ps) {
|
||||||
cxfree(pfbcfgs);
|
cxfree(pfbcfgs);
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
if (!ps->glx_fbconfigs[ps->depth]) {
|
if (!ps->psglx->fbconfigs[ps->depth]) {
|
||||||
printf_errf("(): No FBConfig found for default depth %d.", ps->depth);
|
printf_errf("(): No FBConfig found for default depth %d.", ps->depth);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ps->glx_fbconfigs[32]) {
|
if (!ps->psglx->fbconfigs[32]) {
|
||||||
printf_errf("(): No FBConfig found for depth 32. Expect crazy things.");
|
printf_errf("(): No FBConfig found for depth 32. Expect crazy things.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_GLX
|
#ifdef DEBUG_GLX
|
||||||
printf_dbgf("(): %d-bit: %#3x, 32-bit: %#3x\n",
|
printf_dbgf("(): %d-bit: %#3x, 32-bit: %#3x\n",
|
||||||
ps->depth, (int) ps->glx_fbconfigs[ps->depth]->cfg,
|
ps->depth, (int) ps->psglx->fbconfigs[ps->depth]->cfg,
|
||||||
(int) ps->glx_fbconfigs[32]->cfg);
|
(int) ps->psglx->fbconfigs[32]->cfg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -733,7 +781,7 @@ glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, Pixmap pixmap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const glx_fbconfig_t *pcfg = ps->glx_fbconfigs[depth];
|
const glx_fbconfig_t *pcfg = ps->psglx->fbconfigs[depth];
|
||||||
if (!pcfg) {
|
if (!pcfg) {
|
||||||
printf_errf("(%d): Couldn't find FBConfig with requested depth.", depth);
|
printf_errf("(%d): Couldn't find FBConfig with requested depth.", depth);
|
||||||
return false;
|
return false;
|
||||||
|
@ -744,7 +792,7 @@ glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, Pixmap pixmap,
|
||||||
// pixmap-specific parameters, and this may change in the future
|
// pixmap-specific parameters, and this may change in the future
|
||||||
GLenum tex_tgt = 0;
|
GLenum tex_tgt = 0;
|
||||||
if (GLX_TEXTURE_2D_BIT_EXT & pcfg->texture_tgts
|
if (GLX_TEXTURE_2D_BIT_EXT & pcfg->texture_tgts
|
||||||
&& ps->glx_has_texture_non_power_of_two)
|
&& ps->psglx->has_texture_non_power_of_two)
|
||||||
tex_tgt = GLX_TEXTURE_2D_EXT;
|
tex_tgt = GLX_TEXTURE_2D_EXT;
|
||||||
else if (GLX_TEXTURE_RECTANGLE_BIT_EXT & pcfg->texture_tgts)
|
else if (GLX_TEXTURE_RECTANGLE_BIT_EXT & pcfg->texture_tgts)
|
||||||
tex_tgt = GLX_TEXTURE_RECTANGLE_EXT;
|
tex_tgt = GLX_TEXTURE_RECTANGLE_EXT;
|
||||||
|
@ -809,9 +857,9 @@ glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, Pixmap pixmap,
|
||||||
// The specification requires rebinding whenever the content changes...
|
// The specification requires rebinding whenever the content changes...
|
||||||
// We can't follow this, too slow.
|
// We can't follow this, too slow.
|
||||||
if (need_release)
|
if (need_release)
|
||||||
ps->glXReleaseTexImageProc(ps->dpy, ptex->glpixmap, GLX_FRONT_LEFT_EXT);
|
ps->psglx->glXReleaseTexImageProc(ps->dpy, ptex->glpixmap, GLX_FRONT_LEFT_EXT);
|
||||||
|
|
||||||
ps->glXBindTexImageProc(ps->dpy, ptex->glpixmap, GLX_FRONT_LEFT_EXT, NULL);
|
ps->psglx->glXBindTexImageProc(ps->dpy, ptex->glpixmap, GLX_FRONT_LEFT_EXT, NULL);
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
glBindTexture(ptex->target, 0);
|
glBindTexture(ptex->target, 0);
|
||||||
|
@ -830,7 +878,7 @@ glx_release_pixmap(session_t *ps, glx_texture_t *ptex) {
|
||||||
// Release binding
|
// Release binding
|
||||||
if (ptex->glpixmap && ptex->texture) {
|
if (ptex->glpixmap && ptex->texture) {
|
||||||
glBindTexture(ptex->target, ptex->texture);
|
glBindTexture(ptex->target, ptex->texture);
|
||||||
ps->glXReleaseTexImageProc(ps->dpy, ptex->glpixmap, GLX_FRONT_LEFT_EXT);
|
ps->psglx->glXReleaseTexImageProc(ps->dpy, ptex->glpixmap, GLX_FRONT_LEFT_EXT);
|
||||||
glBindTexture(ptex->target, 0);
|
glBindTexture(ptex->target, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,7 +896,7 @@ glx_release_pixmap(session_t *ps, glx_texture_t *ptex) {
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
glx_paint_pre(session_t *ps, XserverRegion *preg) {
|
glx_paint_pre(session_t *ps, XserverRegion *preg) {
|
||||||
ps->glx_z = 0.0;
|
ps->psglx->z = 0.0;
|
||||||
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// Get buffer age
|
// Get buffer age
|
||||||
|
@ -1116,8 +1164,8 @@ glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
|
||||||
GLfloat factor_center,
|
GLfloat factor_center,
|
||||||
XserverRegion reg_tgt, const reg_data_t *pcache_reg,
|
XserverRegion reg_tgt, const reg_data_t *pcache_reg,
|
||||||
glx_blur_cache_t *pbc) {
|
glx_blur_cache_t *pbc) {
|
||||||
assert(ps->glx_blur_passes[0].prog);
|
assert(ps->psglx->blur_passes[0].prog);
|
||||||
const bool more_passes = ps->glx_blur_passes[1].prog;
|
const bool more_passes = ps->psglx->blur_passes[1].prog;
|
||||||
const bool have_scissors = glIsEnabled(GL_SCISSOR_TEST);
|
const bool have_scissors = glIsEnabled(GL_SCISSOR_TEST);
|
||||||
const bool have_stencil = glIsEnabled(GL_STENCIL_TEST);
|
const bool have_stencil = glIsEnabled(GL_STENCIL_TEST);
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
@ -1154,7 +1202,7 @@ glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GLenum tex_tgt = GL_TEXTURE_RECTANGLE;
|
GLenum tex_tgt = GL_TEXTURE_RECTANGLE;
|
||||||
if (ps->glx_has_texture_non_power_of_two)
|
if (ps->psglx->has_texture_non_power_of_two)
|
||||||
tex_tgt = GL_TEXTURE_2D;
|
tex_tgt = GL_TEXTURE_2D;
|
||||||
|
|
||||||
// Free textures if size inconsistency discovered
|
// Free textures if size inconsistency discovered
|
||||||
|
@ -1217,9 +1265,9 @@ glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
|
||||||
|
|
||||||
bool last_pass = false;
|
bool last_pass = false;
|
||||||
for (int i = 0; !last_pass; ++i) {
|
for (int i = 0; !last_pass; ++i) {
|
||||||
last_pass = !ps->glx_blur_passes[i + 1].prog;
|
last_pass = !ps->psglx->blur_passes[i + 1].prog;
|
||||||
assert(i < MAX_BLUR_PASS - 1);
|
assert(i < MAX_BLUR_PASS - 1);
|
||||||
const glx_blur_pass_t *ppass = &ps->glx_blur_passes[i];
|
const glx_blur_pass_t *ppass = &ps->psglx->blur_passes[i];
|
||||||
assert(ppass->prog);
|
assert(ppass->prog);
|
||||||
|
|
||||||
assert(tex_scr);
|
assert(tex_scr);
|
||||||
|
@ -1392,7 +1440,7 @@ glx_render_(session_t *ps, const glx_texture_t *ptex,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
argb = argb || (GLX_TEXTURE_FORMAT_RGBA_EXT ==
|
argb = argb || (GLX_TEXTURE_FORMAT_RGBA_EXT ==
|
||||||
ps->glx_fbconfigs[ptex->depth]->texture_fmt);
|
ps->psglx->fbconfigs[ptex->depth]->texture_fmt);
|
||||||
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
#ifdef CONFIG_VSYNC_OPENGL_GLSL
|
||||||
const bool has_prog = pprogram && pprogram->prog;
|
const bool has_prog = pprogram && pprogram->prog;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1695,7 +1743,7 @@ glx_swap_copysubbuffermesa(session_t *ps, XserverRegion reg) {
|
||||||
#ifdef DEBUG_GLX
|
#ifdef DEBUG_GLX
|
||||||
printf_dbgf("(): %d, %d, %d, %d\n", x, y, wid, hei);
|
printf_dbgf("(): %d, %d, %d, %d\n", x, y, wid, hei);
|
||||||
#endif
|
#endif
|
||||||
ps->glXCopySubBufferProc(ps->dpy, get_tgt_window(ps), x, y, wid, hei);
|
ps->psglx->glXCopySubBufferProc(ps->dpy, get_tgt_window(ps), x, y, wid, hei);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ glx_dump_err_str(GLenum err) {
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
glx_check_err_(session_t *ps, const char *func, int line) {
|
glx_check_err_(session_t *ps, const char *func, int line) {
|
||||||
if (!ps->glx_context) return;
|
if (!ps->psglx->context) return;
|
||||||
|
|
||||||
GLenum err = GL_NO_ERROR;
|
GLenum err = GL_NO_ERROR;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue