/*
*
* Beryl blur and reflection effect plugin
*
* blurfx.h
*
* Copyright : (C) 2006 by Dennis Kasprzyk
* E-mail : onestone@beryl-project.org
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef BLURFX_H_
#define BLURFX_H_
#include "blurfx_shader.h"
#include <string.h>
#define GET_BLURFX_DISPLAY(d) \
((BlurfxDisplay *) (d)->privates[displayPrivateIndex].ptr)
#define BLURFX_DISPLAY(d) \
BlurfxDisplay *bd = GET_BLURFX_DISPLAY (d)
#define GET_BLURFX_SCREEN(s, bd) \
((BlurfxScreen *) (s)->privates[(bd)->screenPrivateIndex].ptr)
#define BLURFX_SCREEN(s) \
BlurfxScreen *bs = GET_BLURFX_SCREEN (s, GET_BLURFX_DISPLAY (s->display))
#define GET_BLURFX_WINDOW(w, bs) \
((BlurfxWindow *) (w)->privates[(bs)->windowPrivateIndex].ptr)
#define BLURFX_WINDOW_PTR(w) \
GET_BLURFX_WINDOW (w, \
GET_BLURFX_SCREEN (w->screen, \
GET_BLURFX_DISPLAY (w->screen->display)))
#define BLURFX_WINDOW(w) \
BlurfxWindow *bw = BLURFX_WINDOW_PTR(w)
#define WIN_X(w) ((w)->attrib.x - (w)->output.left)
#define WIN_Y(w) ((w)->attrib.y - (w)->output.top)
#define WIN_W(w) ((w)->width + (w)->output.left + (w)->output.right)
#define WIN_H(w) ((w)->height + (w)->output.top + (w)->output.bottom)
#define WIN_XO(w) ((w)->attrib.x - (w)->input.left)
#define WIN_YO(w) ((w)->attrib.y - (w)->input.top)
#define WIN_WO(w) ((w)->width + (w)->input.left + (w)->input.right)
#define WIN_HO(w) ((w)->height + (w)->input.top + (w)->input.bottom)
#define WINDOW_INPUT_INVISIBLE(w) \
((w)->attrib.map_state != IsViewable || \
(!(w)->damaged) || \
(w)->attrib.x + (w)->width + (w)->input.right <= 0 || \
(w)->attrib.y + (w)->height + (w)->input.bottom <= 0 || \
(w)->attrib.x - (w)->input.left >= (w)->screen->width || \
(w)->attrib.y - (w)->input.top >= (w)->screen->height)
#define BFX_ADD_RECT(data, m, x1, y1, x2, y2) \
*(data)++ = COMP_TEX_COORD_X (&m, x1); \
*(data)++ = COMP_TEX_COORD_Y (&m, y2); \
*(data)++ = (x1); \
*(data)++ = (y2); \
*(data)++ = COMP_TEX_COORD_X (&m, x2); \
*(data)++ = COMP_TEX_COORD_Y (&m, y2); \
*(data)++ = (x2); \
*(data)++ = (y2); \
*(data)++ = COMP_TEX_COORD_X (&m, x2); \
*(data)++ = COMP_TEX_COORD_Y (&m, y1); \
*(data)++ = (x2); \
*(data)++ = (y1); \
*(data)++ = COMP_TEX_COORD_X (&m, x1); \
*(data)++ = COMP_TEX_COORD_Y (&m, y1); \
*(data)++ = (x1); \
*(data)++ = (y1)
#ifdef GL_DEBUG
static GLenum gl_error;
#define GLERR gl_error=glGetError(); if (gl_error != GL_NO_ERROR) { fprintf (stderr,"GL error 0x%X has occured at %s:%d\n",gl_error,__FILE__,__LINE__); }
#else
#define GLERR
#endif
#define BLURFX_DISPLAY_OPTION_MOTION_BLUR_TOGGLE 0
#define BLURFX_DISPLAY_OPTION_NUM 1
#define BLURFX_DISPLAY_OPTION_MOTION_BLUR_TOGGLE_KEY_DEFAULT "F12"
#define BLURFX_DISPLAY_OPTION_MOTION_BLUR_TOGGLE_MOD_DEFAULT ControlMask
#define BLURFX_SCREEN_OPTION_BLUR_WINDOWS 0
#define BLURFX_SCREEN_OPTION_BLUR_DECORATION 1
#define BLURFX_SCREEN_OPTION_REFLECTION_WINDOWS 2
#define BLURFX_SCREEN_OPTION_REFLECTION_DECORATION 3
#define BLURFX_SCREEN_OPTION_BLUR_ON_TRANSFORMED_SCREEN 6
#define BLURFX_SCREEN_OPTION_BLUR_TRANSFORMED_WINDOW 5
#define BLURFX_SCREEN_OPTION_BLUR_SHADER 4
#define BLURFX_SCREEN_OPTION_FORCE_NON_FBO_BLUR 7
#define BLURFX_SCREEN_OPTION_NON_FBO_BLUR_STRENGTH 8
#define BLURFX_SCREEN_OPTION_DISABLE_BLUR_ON_SCREENGRAB_OF 9
#define BLURFX_SCREEN_OPTION_REFLECTION_ON_TRANSFORMED_SCREEN 13
#define BLURFX_SCREEN_OPTION_REFLECTION_TRANSFORMED_WINDOW 11
#define BLURFX_SCREEN_OPTION_DISABLE_REFLECTION_ON_SCREENGRAB_OF 12
#define BLURFX_SCREEN_OPTION_REFLECTION_FILE 10
#define BLURFX_SCREEN_OPTION_REFLECTION_SCALE 14
#define BLURFX_SCREEN_OPTION_REFLECTION_PROPORTIONAL 15
#define BLURFX_SCREEN_OPTION_REFLECTION_USE_IMAGE_COLOR 16
#define BLURFX_SCREEN_OPTION_REFLECTION_USE_IMAGE_ALPHA 17
#define BLURFX_SCREEN_OPTION_MOTION_BLUR_MODE 18
#define BLURFX_SCREEN_OPTION_MOTION_BLUR_ON_SCREENGRAB_OF 19
#define BLURFX_SCREEN_OPTION_MOTION_BLUR_STRENGTH 20
#define BLURFX_SCREEN_OPTION_MOTION_BLUR_ON_TRANSFORMED_SCREEN 21
#define BLURFX_SCREEN_OPTION_BLUR_CACHE_TEXTURES 22
#define BLURFX_SCREEN_OPTION_NO_BLUR_CACHE_ON_TRANSFORMED_SCREEN 23
#define BLURFX_SCREEN_OPTION_DISABLE_DECORATION_ALPHADEP 24
#define BLURFX_SCREEN_OPTION_DISABLE_BLUR_WINDOW_TYPE 25
#define BLURFX_SCREEN_OPTION_DISABLE_REFLECTION_WINDOW_TYPE 26
#define BLURFX_SCREEN_OPTION_BLUR_SATURATION 27
#define BLURFX_SCREEN_OPTION_WARNING 28
#define BLURFX_SCREEN_OPTION_NUM 29
#define BLURFX_SCREEN_OPTION_BLUR_WINDOWS_DEFAULT TRUE
#define BLURFX_SCREEN_OPTION_BLUR_DECORATION_DEFAULT TRUE
#define BLURFX_SCREEN_OPTION_REFLECTION_WINDOWS_DEFAULT TRUE
#define BLURFX_SCREEN_OPTION_REFLECTION_DECORATION_DEFAULT TRUE
#define BLURFX_SCREEN_OPTION_BLUR_SHADER_DEFAULT "gaussian 5x5"
#define BLURFX_SCREEN_OPTION_BLUR_ON_TRANSFORMED_SCREEN_DEFAULT FALSE
#define BLURFX_SCREEN_OPTION_BLUR_TRANSFORMED_WINDOW_DEFAULT FALSE
#define BLURFX_SCREEN_OPTION_REFLECTION_ON_TRANSFORMED_SCREEN_DEFAULT TRUE
#define BLURFX_SCREEN_OPTION_REFLECTION_TRANSFORMED_WINDOW_DEFAULT TRUE
#define BLURFX_SCREEN_OPTION_REFLECTION_FILE_DEFAULT ""
#define BLURFX_SCREEN_OPTION_REFLECTION_SCALE_DEFAULT FALSE
#define BLURFX_SCREEN_OPTION_REFLECTION_PROPORTIONAL_DEFAULT TRUE
#define BLURFX_SCREEN_OPTION_REFLECTION_USE_IMAGE_COLOR_DEFAULT FALSE
#define BLURFX_SCREEN_OPTION_REFLECTION_USE_IMAGE_ALPHA_DEFAULT FALSE
#define BLURFX_SCREEN_OPTION_MOTION_BLUR_MODE_DEFAULT "simple"
#define BLURFX_SCREEN_OPTION_MOTION_BLUR_STRENGTH_DEFAULT 20.0
#define BLURFX_SCREEN_OPTION_MOTION_BLUR_ON_TRANSFORMED_SCREEN_DEFAULT FALSE
#define BLURFX_SCREEN_OPTION_BLUR_CACHE_TEXTURES_DEFAULT TRUE
#define BLURFX_SCREEN_OPTION_NO_BLUR_CACHE_ON_TRANSFORMED_SCREEN_DEFAULT FALSE
#define BLURFX_SCREEN_OPTION_FORCE_NON_FBO_BLUR_DEFAULT FALSE
#define BLURFX_SCREEN_OPTION_NON_FBO_BLUR_STRENGTH_DEFAULT 4
#define BLURFX_SCREEN_OPTION_DISABLE_DECORATION_ALPHADEP_DEFAULT FALSE
#define BLURFX_SCREEN_OPTION_BLUR_SATURATION_DEFAULT 100.0
#define MODE_NORMAL 0
#define MODE_OCCLUSION 1
#define MODE_BLURREFLECTION 2
static char *blurDisable[] = { "switcher" };
static char *mBlurModes[] = { N_("simple"), N_("accum"), N_("fbo") };
static char *blurShaderNames[] = { N_("gaussian 5x5"), N_("linear 5x5"), N_("gaussian 9x9"),
N_("linear 9x9"), N_("gaussian 13x13"), N_("linear 13x13"),
N_("gaussian 17x17"), N_("linear 17x17"), N_("gaussian 21x21"),
N_("linear 21x21")};
static const char *blurShader[10][2];
#define LIST_SIZE(l) (sizeof (l) / sizeof (l[0]))
#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
#define DISABLE_FEATURE(x,y) (IPCS_IsSet(IPCS_OBJECT(x),y) && IPCS_GetBool(IPCS_OBJECT(x),y))
static int displayPrivateIndex = 0;
typedef struct _BlurfxDisplay
{
int screenPrivateIndex;
CompOption opt[BLURFX_DISPLAY_OPTION_NUM];
}BlurfxDisplay;
// our vertex array container
typedef struct _BlurfxVertArray
{
GLfloat* vertices;
GLushort* indices;
int vCount;
int indexCount;
int vertexSize;
int indexSize;
}BlurfxVertArray;
// our texture container
typedef struct _BlurTexture
{
int x;
int y;
int width;
int height;
unsigned int handle;
GLenum active_filter;
unsigned int target;
float downSample;
}BlurTexture;
typedef struct _BlurfxScreen
{
int hasInit; // set to one once initiliazed
BlurTexture backTex; // texture which contains the background
BlurTexture motionTex; // texture that stores the motion blurred screen
BlurTexture blurTempTexV; // temporary texture for blur effect
BlurTexture blurTempTexH; // temporary texture for blur effect
BlurTexture modTex; // reflection effect texture
BlurfxVertArray vertArray; // temporary vertex array
int output; // current output device
unsigned int mode; // actual drawing mode
unsigned int fbo; // framebuffer object for render to texture operations
unsigned int fboStatus;
Bool fboActive;
unsigned int blurShaderV; // fragment program handle
unsigned int blurShaderH; // fragment program handle
// functions that we will intercept
PreparePaintScreenProc preparePaintScreen;
PaintScreenProc paintScreen;
PaintTransformedScreenProc paintTransformedScreen;
DrawWindowTextureProc drawWindowTexture;
DrawWindowProc drawWindow;
DamageWindowRectProc damageWindowRect;
AddWindowGeometryProc addWindowGeometry;
int windowPrivateIndex;
Region screenDamage; // region to calculate damage
Region realPaintRegion; // actual paint region
Region blurredRegion; // already blurred region
Region occlusion; // region to caclulate occlusion
Bool od_active;
Bool was_transformed;
Bool paintingSwitcher;
Bool motion_blur_active;
unsigned int mb_mode; // motion blur mode
Bool mb_update; // is an update of the motion blut texture needed
float mb_alpha; // motion blur blending value
float mb_timer; // motion blur fadeout time
Bool mb_activated;
float downSample; // down sample rate for non FBO mode
unsigned int noBlurWMask; // window types we disable blur
unsigned int noReflectionWMask; // window types we disable reflection
float pm[16]; // here we store the projection matrix
int blur_shader;
// hardware support flags
Bool blur_supported;
Bool fboBlur_supported;
Bool mblur_supported;
Bool reflection_supported;
int ipcs_disable_blur;
int ipcs_disable_mblur;
int ipcs_disable_reflection;
CompOption opt[BLURFX_SCREEN_OPTION_NUM]; // options
}BlurfxScreen;
typedef struct _BlurfxWindow
{
// last position and scale
int lastX;
int lastY;
WindowPaintAttrib lastPAttrib;
Region clip; // occluted region
Region paintRegion; // actual paint region
Region texDamage; // blur cache texture damage
Region damageRegion; // window damage
BlurTexture blurTex; // blur cache texture
Region bTexRegion; // blur cache texture damage
Bool hasTexture; // is blur cache texture initialized?
BlurfxVertArray vertArray; // temprary vertex array
BlurfxVertArray decoArray; // decoration without shadow array
CompWindow *my_next; // next window
Bool texUpdated; // is blur cache texture up to date
int bc_x; // blur_cache texture viewport
int bc_y; // blur_cache texture viewport
Bool isSwitcher; // is this the switcher window
float mvm[16]; // here we store the model view matrix
Bool mvm_updated; // is the model view matrix up to date
int ipcs_disable_blur;
int ipcs_disable_reflection;
}BlurfxWindow;
static Bool blurfxInit (CompPlugin *p);
static void blurfxFini (CompPlugin *p);
static Bool blurfxInitDisplay (CompPlugin *p, CompDisplay *d);
static void blurfxFiniDisplay (CompPlugin *p, CompDisplay *d);
static Bool blurfxInitScreen (CompPlugin *p, CompScreen *s);
static void blurfxFiniScreen (CompPlugin *p, CompScreen *s);
static Bool blurfxInitWindow (CompPlugin *p, CompWindow *w);
static void blurfxFiniWindow (CompPlugin *p, CompWindow *w);
static CompOption* blurfxGetDisplayOptions (CompDisplay *display, int *count);
static Bool blurfxSetDisplayOption (CompDisplay *display, char *name, CompOptionValue *value);
static void blurfxDisplayInitOptions (BlurfxDisplay *bd);
static Bool blurfxSetScreenOption (CompScreen *s, char *name, CompOptionValue *value);
static CompOption* blurfxGetScreenOptions (CompScreen *s, int *count);
static void blurfxScreenInitOptions (BlurfxScreen *bs);
static void blurfxPreparePaintScreen (CompScreen *s, int ms);
static Bool blurfxPaintScreen(CompScreen *s, const ScreenPaintAttrib *sa, Region region, int output, unsigned int mask);
static void blurfxPaintTransformedScreen(CompScreen *s, const ScreenPaintAttrib
*sa, Region region, int output, unsigned int mask);
static Bool blurfxDrawWindow (CompWindow *w, const WindowPaintAttrib *attrib,
Region region, unsigned int mask);
static void blurfxDrawWindowTexture(CompWindow *w,CompTexture *texture, const WindowPaintAttrib *attrib, unsigned int mask);
static void blurfxAddWindowGeometry (CompWindow *w, CompMatrix *m, int nM, Region region, Region clip);
static Bool blurfxDamageWindowRect (CompWindow *w, Bool initial, BoxPtr box);
static void updateBlur(CompWindow *w, CompScreen *s, const WindowPaintAttrib *attrib, unsigned int mask, CompTextureFilter filter);
static void updateBlurTexture(CompWindow *w, CompScreen *s, const WindowPaintAttrib *attrib, unsigned int mask, CompTextureFilter filter);
static void updateBlurTextureSize(CompWindow *w, CompScreen *s, const WindowPaintAttrib *attrib, unsigned int mask);
static void updateBlurNoFBO(CompWindow *w, CompScreen *s, const WindowPaintAttrib *attrib, unsigned int mask);
static void updateBlurTextureNoFBO(CompWindow *w, CompScreen *s, const WindowPaintAttrib *attrib, unsigned int mask);
static void drawBlur(CompWindow *w, CompScreen *s, CompTexture *texture, const WindowPaintAttrib *attrib, int mask, CompTextureFilter filter);
static void drawReflection(CompWindow *w, CompScreen *s, CompTexture *texture, const WindowPaintAttrib *attrib, int mask, CompTextureFilter filter);
static void drawBlur(CompWindow *w, CompScreen *s, CompTexture *texture, const WindowPaintAttrib *attrib, int mask, CompTextureFilter filter);
static Bool blurfxToggleMotionBlur (CompDisplay *d, CompAction *ac, CompActionState state, CompOption *option, int nOption);
static Bool bindFbo(CompScreen *s, BlurTexture tex);
static void unbindFbo(CompScreen *s);
static void genGeometry (BlurfxVertArray *vA, CompMatrix matrix, int xextend,Region region);
static Bool moreVertices (BlurfxVertArray *vA, int newSize);
static void initBlurfxScreen(BlurfxScreen* bs,int Screenwidth,int Screenheight,CompScreen* s);
static void genBlurTexture(BlurfxScreen *bs,BlurTexture *tex,int width,int height,int type);
static void loadShader(GLenum type,CompScreen* s, GLuint * shader, const char * prog);
static void loadPngToTexture2D(CompScreen *s, BlurTexture * tex, char *filename);
static void enableBlurfxTexture(BlurTexture* tex, CompTextureFilter filter);
static void switchBlurfxTexture(BlurTexture* from, BlurTexture* to, CompTextureFilter filter);
static void disableBlurfxTexture(BlurTexture* tex);
CompPluginDep blurfxDeps[] = {
{CompPluginRuleAfterCategory, "imageformat"},
{CompPluginRuleEnd, ""}
};
CompPluginVTable blurfxVTable = {
"blurfx",
N_("Blur effects"),
N_("Blur and reflection effects"),
blurfxInit,
blurfxFini,
blurfxInitDisplay,
blurfxFiniDisplay,
blurfxInitScreen,
blurfxFiniScreen,
blurfxInitWindow,
blurfxFiniWindow,
blurfxGetDisplayOptions,
blurfxSetDisplayOption,
blurfxGetScreenOptions,
blurfxSetScreenOption,
blurfxDeps,
sizeof (blurfxDeps) / sizeof(blurfxDeps[0]),
0,
0,
BERYL_ABI_INFO,
"beryl-plugins",
"effects",
0,
0,
False,
};
#endif
syntax highlighted by Code2HTML, v. 0.9.1