Index: beryl-plugins-unsupported/src/group/group.h =================================================================== --- beryl-plugins-unsupported/src/group/group.h (Revision 3571) +++ beryl-plugins-unsupported/src/group/group.h (Arbeitskopie) @@ -595,7 +595,7 @@ Bool groupPaintScreen(CompScreen * s, const ScreenPaintAttrib * sAttrib, Region region, int output, unsigned int mask); void groupPaintTransformedScreen(CompScreen * s, const ScreenPaintAttrib * sa, Region region, int output, unsigned int mask); void groupDonePaintScreen(CompScreen * s); -Bool groupDrawWindow(CompWindow * w, const WindowPaintAttrib * attrib, Region region, unsigned int mask); +Bool groupDrawWindow(CompWindow * w, const FragmentAttrib * attrib, Region region, unsigned int mask); Bool groupPaintWindow(CompWindow * w, const WindowPaintAttrib * attrib, Region region, unsigned int mask); /* Index: beryl-plugins-unsupported/src/group/paint.c =================================================================== --- beryl-plugins-unsupported/src/group/paint.c (Revision 3571) +++ beryl-plugins-unsupported/src/group/paint.c (Arbeitskopie) @@ -61,6 +61,7 @@ sAttrib.opacity = sAttrib.opacity * targetOpacity / 0xffff; if (w->mapNum) { + FragmentAttrib fragment; if (WIN_WIDTH(w) > tw) sAttrib.xScale = (float) tw / WIN_WIDTH(w); @@ -83,9 +84,14 @@ sAttrib.xTranslate = slot->region->extents.x1 - w->attrib.x + vx; sAttrib.yTranslate = slot->region->extents.y1 - w->attrib.y + vy; - (w->screen->drawWindow) (w, &sAttrib, getInfiniteRegion(), + initFragmentAttrib (&fragment, &sAttrib); + pushWindowTransform (w, &sAttrib); + + (w->screen->drawWindow) (w, &fragment, getInfiniteRegion(), PAINT_WINDOW_TRANSFORMED_MASK); + glPopMatrix(); + addWindowDamage(w); } @@ -480,10 +486,19 @@ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor4us(alpha, alpha, alpha, alpha); - (*topTab->screen->drawWindowTexture) (topTab, - &layer->texture, &attrib, - PAINT_WINDOW_TRANSLUCENT_MASK | PAINT_WINDOW_TRANSFORMED_MASK); + if (topTab->vCount) { + FragmentAttrib fAttrib; + initFragmentAttrib (&fAttrib, &attrib); + pushWindowTransform (topTab, &attrib); + + (*topTab->screen->drawWindowTexture) (topTab, + &layer->texture, &fAttrib, + PAINT_WINDOW_TRANSLUCENT_MASK | PAINT_WINDOW_TRANSFORMED_MASK); + + glPopMatrix(); + } + screenTexEnvMode (s, GL_REPLACE); glColor4usv(defaultColor); } @@ -941,7 +956,7 @@ */ Bool groupDrawWindow(CompWindow * w, - const WindowPaintAttrib * attrib, + const FragmentAttrib * attrib, Region region, unsigned int mask) { Bool status; @@ -972,11 +987,11 @@ } if (w->vCount) { - WindowPaintAttrib wAttrib = *attrib; + FragmentAttrib fAttrib = *attrib; - wAttrib.opacity = OPAQUE; - wAttrib.saturation = COLOR; - wAttrib.brightness = BRIGHT; + fAttrib.opacity = OPAQUE; + fAttrib.saturation = COLOR; + fAttrib.brightness = BRIGHT; glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //glBlendFunc(GL_SRC_ALPHA, GL_ONE); - maybe add an option for that... @@ -986,7 +1001,8 @@ /* we use PAINT_WINDOW_TRANSFORMED_MASK here to force the usage of a good texture filter */ - (*w->screen->drawWindowTexture) (w, &gs->glowTexture, &wAttrib, + + (*w->screen->drawWindowTexture) (w, &gs->glowTexture, &fAttrib, mask | PAINT_WINDOW_TRANSLUCENT_MASK | PAINT_WINDOW_TRANSFORMED_MASK); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); Index: beryl-plugins-unsupported/src/tile.c =================================================================== --- beryl-plugins-unsupported/src/tile.c (Revision 3571) +++ beryl-plugins-unsupported/src/tile.c (Arbeitskopie) @@ -224,6 +224,7 @@ if(tw->isResizing && td->currentAnimationType != outline) // on window texture animation { WindowPaintAttrib sAttrib = *attrib; + FragmentAttrib fragment; glPushMatrix(); glLoadIdentity(); @@ -236,7 +237,11 @@ */ case drop: glRotatef(100.0f/td->animationDuration*ts->msResizing - 100, 0,0,1); - (*s->drawWindow) (w, &sAttrib, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + + initFragmentAttrib(&fragment, attrib); + pushWindowTransform(w, attrib); + (*s->drawWindow) (w, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + glPopMatrix(); break; /* @@ -244,7 +249,10 @@ */ case zoom: glTranslatef(0,0, -1 + ts->msResizing/(float)td->animationDuration); - (*s->drawWindow) (w, &sAttrib, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + initFragmentAttrib(&fragment, attrib); + pushWindowTransform(w, attrib); + (*s->drawWindow) (w, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + glPopMatrix(); break; /* @@ -255,10 +263,14 @@ sAttrib.opacity = OPAQUE / 2; else sAttrib.opacity = OPAQUE/2 + OPAQUE/2*(ts->msResizing - 0.75*td->animationDuration)/(0.25*td->animationDuration); + + initFragmentAttrib (&fragment, &sAttrib); if(ts->msResizing > current*ts->oneDuration) // windows that have animation finished already { - (*s->drawWindow) (w, &sAttrib, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + pushWindowTransform (w, &sAttrib); + (*s->drawWindow) (w, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + glPopMatrix(); } else if(ts->msResizing > (current-1)*ts->oneDuration && ts->msResizing < current*ts->oneDuration) // animation in progress { @@ -271,7 +283,9 @@ else glTranslatef(s->width - s->width * (float)thisDur/ts->oneDuration, 0, 0); - (*s->drawWindow) (w, &sAttrib, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + pushWindowTransform(w, &sAttrib); + (*s->drawWindow) (w, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + glPopMatrix(); } break; @@ -290,14 +304,20 @@ if(ts->msResizing < 0.40f*td->animationDuration) { sAttrib.opacity = OPAQUE - OPAQUE*ts->msResizing/(0.40f*td->animationDuration); - (*s->drawWindow) (w, &sAttrib, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + initFragmentAttrib(&fragment, &sAttrib); + pushWindowTransform(w, &sAttrib); + (*s->drawWindow) (w, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + glPopMatrix(); } else if(ts->msResizing > 0.40f*td->animationDuration && !tw->resizedAlready) // resize window right after first half setWindowFutureSize(w); else if(ts->msResizing > 0.60f*td->animationDuration) // second half of animation, fade in { sAttrib.opacity = OPAQUE*(ts->msResizing - 0.60f*td->animationDuration)/(0.40f*td->animationDuration); - (*s->drawWindow) (w, &sAttrib, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + initFragmentAttrib(&fragment, &sAttrib); + pushWindowTransform(w, &sAttrib); + (*s->drawWindow) (w, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + glPopMatrix(); } break; } Index: beryl-plugins/src/wobbly.c =================================================================== --- beryl-plugins/src/wobbly.c (Revision 3571) +++ beryl-plugins/src/wobbly.c (Arbeitskopie) @@ -278,7 +278,6 @@ DamageWindowRectProc damageWindowRect; AddWindowGeometryProc addWindowGeometry; DrawWindowGeometryProc drawWindowGeometry; - DrawWindowTextureProc drawWindowTexture; WindowResizeNotifyProc windowResizeNotify; WindowMoveNotifyProc windowMoveNotify; Index: beryl-plugins/src/blurfx.c =================================================================== --- beryl-plugins/src/blurfx.c (Revision 3571) +++ beryl-plugins/src/blurfx.c (Arbeitskopie) @@ -1198,7 +1198,9 @@ for (w = s->reverseWindows; w; w = w->prev) { + FragmentAttrib fragment; BLURFX_WINDOW(w); + if (w->destroyed) continue; @@ -1211,8 +1213,14 @@ continue; } XUnionRegion(bs->occlusion, getEmptyRegion(), bw->clip); - (*s->drawWindow) (w, &w->paint, &s->region, + + initFragmentAttrib (&fragment, &w->paint); + pushWindowTransform (w, &w->paint); + + (*s->drawWindow) (w, &fragment, &s->region, PAINT_WINDOW_SOLID_MASK); + + glPopMatrix(); } } @@ -1545,7 +1553,9 @@ for (w = s->reverseWindows; w; w = w->prev) { + FragmentAttrib fragment; BLURFX_WINDOW(w); + if (w->destroyed) continue; @@ -1555,8 +1565,14 @@ continue; } XUnionRegion(bs->occlusion, getEmptyRegion(), bw->clip); - (*s->drawWindow) (w, &w->paint, &s->region, + + initFragmentAttrib (&fragment, &w->paint); + pushWindowTransform (w, &w->paint); + + (*s->drawWindow) (w, &fragment, &s->region, PAINT_WINDOW_SOLID_MASK); + + glPopMatrix(); } } bs->mode = MODE_NORMAL; @@ -1567,7 +1583,7 @@ static Bool -blurfxDrawWindow(CompWindow * w, const WindowPaintAttrib * attrib, +blurfxDrawWindow(CompWindow * w, const FragmentAttrib * attrib, Region region, unsigned int mask) { Bool status; @@ -1796,7 +1812,7 @@ static void blurfxDrawWindowTexture(CompWindow * w, CompTexture * texture, - const WindowPaintAttrib * attrib, unsigned int mask) + const FragmentAttrib * attrib, unsigned int mask) { CompScreen *s = w->screen; @@ -4084,7 +4100,7 @@ static void drawReflection(CompWindow * w, CompScreen * s, CompTexture * texture, - const WindowPaintAttrib * attrib, int mask, + const FragmentAttrib * attrib, int mask, CompTextureFilter filter) { Index: beryl-plugins/src/blurfx.h =================================================================== --- beryl-plugins/src/blurfx.h (Revision 3571) +++ beryl-plugins/src/blurfx.h (Arbeitskopie) @@ -331,9 +331,9 @@ 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, +static Bool blurfxDrawWindow (CompWindow *w, const FragmentAttrib *attrib, Region region, unsigned int mask); -static void blurfxDrawWindowTexture(CompWindow *w,CompTexture *texture, const WindowPaintAttrib *attrib, unsigned int mask); +static void blurfxDrawWindowTexture(CompWindow *w,CompTexture *texture, const FragmentAttrib *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); Index: beryl-plugins/src/animation.c =================================================================== --- beryl-plugins/src/animation.c (Revision 3571) +++ beryl-plugins/src/animation.c (Arbeitskopie) @@ -8304,7 +8304,8 @@ static void animDrawWindowTexture(CompWindow * w, CompTexture * texture, - const WindowPaintAttrib * attrib, unsigned int mask) + const FragmentAttrib * attrib, + unsigned int mask) { ANIM_WINDOW(w); ANIM_SCREEN(w->screen); @@ -8314,7 +8315,9 @@ //printf("%X animDrawWindowTexture, texture: %X\n", // (unsigned)aw, (unsigned)texture); aw->curTexture = texture; - aw->curPaintAttrib = *attrib; + aw->curPaintAttrib.opacity = attrib->opacity; + aw->curPaintAttrib.saturation = attrib->saturation; + aw->curPaintAttrib.brightness = attrib->brightness; } UNWRAP(as, w->screen, drawWindowTexture); Index: beryl-plugins/src/neg.c =================================================================== --- beryl-plugins/src/neg.c (Revision 3571) +++ beryl-plugins/src/neg.c (Arbeitskopie) @@ -179,13 +179,15 @@ static void NEGDrawWindowTexture(CompWindow * w, CompTexture * texture, - const WindowPaintAttrib * attrib, unsigned int mask) + const FragmentAttrib * attrib, + unsigned int mask) { int filter; NEG_SCREEN(w->screen); NEG_WINDOW(w); +#ifdef FIX_THIS_CODE /* PAINT_WINDOW_DECORATION_MASK is set when the decorations are being painted * I didn't want to paint them negative too */ @@ -484,11 +486,12 @@ } else { +#endif /* not negative */ UNWRAP(ns, w->screen, drawWindowTexture); (*w->screen->drawWindowTexture) (w, texture, attrib, mask); WRAP(ns, w->screen, drawWindowTexture, NEGDrawWindowTexture); - } +// } } static Bool NEGDamageWindowRect(CompWindow * w, Bool initial, BoxPtr rect) { Index: beryl-plugins/src/water.c =================================================================== --- beryl-plugins/src/water.c (Revision 3571) +++ beryl-plugins/src/water.c (Arbeitskopie) @@ -36,15 +36,17 @@ #define TEXTURE_SIZE 256 -#define PROGRAM_BUMP 0 -#define PROGRAM_BUMP_RECT 1 -#define PROGRAM_BUMP_SAT 2 -#define PROGRAM_BUMP_SAT_RECT 3 -#define PROGRAM_WATER 4 -#define PROGRAM_NUM 5 - #define TEXTURE_NUM 3 +typedef struct _WaterFunction { + struct _WaterFunction *next; + + int handle; + int target; + int param; + int unit; +} WaterFunction; + #define TINDEX(ws, i) (((ws)->tIndex + (i)) % TEXTURE_NUM) #define CLAMP(v, min, max) \ @@ -135,7 +137,7 @@ int grabIndex; int width, height; - GLuint program[PROGRAM_NUM]; + GLuint program; GLuint texture[TEXTURE_NUM]; int tIndex; @@ -160,6 +162,7 @@ Window current; + WaterFunction *bumpMapFunctions; } WaterScreen; #define GET_WATER_DISPLAY(d) \ @@ -180,42 +183,6 @@ static Bool waterWiperTimeout(void *closure); -static const char *saturateFpString = - "MUL temp, rgb, { 1.0, 1.0, 1.0, 0.0 };" - "DP3 temp, temp, program.local[1];" - "LRP rgb.xyz, program.local[1].w, rgb, temp;"; - -static const char *bumpFpString = - "!!ARBfp1.0" - "PARAM light0color = state.light[0].diffuse;" - "TEMP rgb, normal, temp, total, bump, offset;" -/* get normal from normal map */ - "TEX normal, fragment.texcoord[1], texture[1], %s;" -/* save height */ - "MOV offset, normal;" -/* remove scale and bias from normal */ - "SUB normal, normal, 0.5;" "MUL normal, normal, 2.0;" -/* normalize the normal map */ - "DP3 temp, normal, normal;" - "RSQ temp, temp.x;" "MUL normal, normal, temp;" -/* scale down normal by height and constant and use as offset in texture */ - "MUL offset, normal, offset.w;" - "MUL offset, offset, program.local[0];" - "ADD offset, fragment.texcoord[0].xyzw, offset.yxzz;" -/* get texture data */ - "TEX rgb, offset, texture[0], %s;" -/* normal dot lightdir, this should eventually be changed to a real light - vector */ - "DP3 bump, normal, { 0.707, 0.707, 0.0, 0.0 };" - "MUL bump, bump, light0color;" -/* diffuse per-vertex lighting, opacity and brightness - and add lightsource bump color */ - "MAD rgb, fragment.color, rgb, bump;" -/* saturation */ - "%s" -/* output */ - "MOV result.color, rgb;" "END"; - static const char *waterFpString = "!!ARBfp1.0" "PARAM param = program.local[0];" @@ -300,57 +267,131 @@ "RECT", "RECT", 1.0f, 1.0f, 1.0f, 1.0f, "RECT", "RECT", "RECT", "RECT"); - return loadFragmentProgram(s, &ws->program[PROGRAM_WATER], buffer); + return loadFragmentProgram(s, &ws->program, buffer); } -static int loadBumpMapProgram(CompScreen * s, int program) +static int +getBumpMapFragmentFunction (CompScreen *s, + CompTexture *texture, + int unit, + int param) { - const char *normalTarget = "2D"; - const char *textureTarget = "2D"; - const char *saturation = ""; - char buffer[1024]; + WaterFunction *function; + CompFunctionData *data; + int target; WATER_SCREEN(s); - if (!s->fragmentProgram) + if (texture->target == GL_TEXTURE_2D) + target = COMP_FETCH_TARGET_2D; + else + target = COMP_FETCH_TARGET_RECT; + + for (function = ws->bumpMapFunctions; function; function = function->next) { - fprintf(stderr, - "%s: water: GL_ARB_fragment_program is missing\n", - getProgramName()); - return 0; + if (function->param == param && function->unit == unit && + function->target == target) + return function->handle; } - switch (program) + data = createFunctionData (); + if (data) { - case PROGRAM_BUMP_SAT: - saturation = saturateFpString; - /* fall-through */ - case PROGRAM_BUMP: - break; - case PROGRAM_BUMP_SAT_RECT: - saturation = saturateFpString; - /* fall-through */ - case PROGRAM_BUMP_RECT: - textureTarget = "RECT"; - break; - } + static char *temp[] = { "normal", "temp", "total", "bump", "offset" }; + int i, handle = 0; + char str[1024]; - if (ws->target != GL_TEXTURE_2D) - normalTarget = "RECT"; + for (i = 0; i < sizeof (temp) / sizeof (temp[0]); i++) + { + if (!addTempHeaderOpToFunctionData (data, temp[i])) + { + destroyFunctionData (data); + return 0; + } + } - sprintf(buffer, bumpFpString, normalTarget, textureTarget, saturation); + snprintf (str, 1024, + /* get normal from normal map */ + "TEX normal, fragment.texcoord[%d], texture[%d], %s;" + /* save height */ + "MOV offset, normal;" + /* remove scale and bias from normal */ + "SUB normal, normal, 0.5;" + "MUL normal, normal, 2.0;" + /* normalize the normal map */ + "DP3 temp, normal, normal;" + "RSQ temp, temp.x;" + "MUL normal, normal, temp;" + /* scale down normal by height and constant and use as + offset in texture */ + "MUL offset, normal, offset.w;" + "MUL offset, offset, program.env[%d];", - return loadFragmentProgram(s, &ws->program[program], buffer); -} + unit, unit, + (ws->target == GL_TEXTURE_2D) ? "2D" : "RECT", + param); -static int ensureBumpMapProgram(CompScreen * s, int program) -{ - WATER_SCREEN(s); + if (!addDataOpToFunctionData (data, str)) + { + destroyFunctionData (data); + return 0; + } - if (!ws->program[program]) - return loadBumpMapProgram(s, program); + if (!addFetchOpToFunctionData (data, "output", "offset.yxzz", target)) + { + destroyFunctionData (data); + return 0; + } - return 1; + snprintf (str, 1024, + /* normal dot lightdir, this should eventually be + changed to a real light vector */ + "DP3 bump, normal, { 0.707, 0.707, 0.0, 0.0 };" + "MUL bump, bump, state.light[0].diffuse;"); + + if (!addDataOpToFunctionData (data, str)) + { + destroyFunctionData (data); + return 0; + } + + if (!addColorOpToFunctionData (data, "output", "output")) + { + destroyFunctionData (data); + return 0; + } + + snprintf (str, 1024, + /* diffuse per-vertex lighting, opacity and brightness + and add lightsource bump color */ + "ADD output, output, bump;"); + + if (!addDataOpToFunctionData (data, str)) + { + destroyFunctionData (data); + return 0; + } + + function = malloc (sizeof (WaterFunction)); + if (function) + { + handle = createFragmentFunction (s, "water", data); + + function->handle = handle; + function->target = target; + function->param = param; + function->unit = unit; + + function->next = ws->bumpMapFunctions; + ws->bumpMapFunctions = function; + } + + destroyFunctionData (data); + + return handle; + } + + return 0; } static void allocTexture(CompScreen * s, int index) @@ -477,7 +518,7 @@ glTexParameteri(ws->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_FRAGMENT_PROGRAM_ARB); - (*s->bindProgram) (GL_FRAGMENT_PROGRAM_ARB, ws->program[PROGRAM_WATER]); + (*s->bindProgram) (GL_FRAGMENT_PROGRAM_ARB, ws->program); (*s->programLocalParameter4f) (GL_FRAGMENT_PROGRAM_ARB, 0, dt * @@ -855,7 +896,7 @@ WATER_SCREEN(s); WATER_DISPLAY(s->display); - if (!ensureBumpMapProgram(s, PROGRAM_BUMP)) + if (!s->fragmentProgram) return; scaleVertices(s, p, n); @@ -931,7 +972,7 @@ ws->ty = ws->height; } - if (!loadBumpMapProgram(s, PROGRAM_BUMP)) + if (!s->fragmentProgram) return; if (s->fbo) @@ -978,9 +1019,9 @@ static void waterDrawWindowTexture(CompWindow * w, CompTexture * texture, - const WindowPaintAttrib * attrib, unsigned int mask) + const FragmentAttrib *attrib, + unsigned int mask) { - WATER_DISPLAY(w->screen->display); WATER_SCREEN(w->screen); if (w->id == ws->current) @@ -994,160 +1035,67 @@ if (ws->count) { + FragmentAttrib fa = *attrib; Bool lighting = w->screen->lighting; + int param, function, unit; GLfloat plane[4]; - int program; - screenLighting(w->screen, TRUE); + WATER_DISPLAY (w->screen->display); - glPushMatrix(); + param = allocFragmentParameters (&fa, 1); + unit = allocFragmentTextureUnits (&fa, 1); - enableTexture(w->screen, texture, - w->screen->filter[WINDOW_TRANS_FILTER]); - - (*w->screen->activeTexture) (GL_TEXTURE1_ARB); - - glBindTexture(ws->target, ws->texture[TINDEX(ws, 0)]); - - plane[1] = plane[2] = 0.0f; - plane[0] = ws->tx / (GLfloat) w->screen->width; - plane[3] = 0.0f; - - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - glTexGenfv(GL_S, GL_EYE_PLANE, plane); - glEnable(GL_TEXTURE_GEN_S); - - plane[0] = plane[2] = 0.0f; - plane[1] = ws->ty / (GLfloat) w->screen->height; - plane[3] = 0.0f; - - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); - glTexGenfv(GL_T, GL_EYE_PLANE, plane); - glEnable(GL_TEXTURE_GEN_T); - - if (mask & PAINT_WINDOW_TRANSFORMED_MASK) + function = getBumpMapFragmentFunction (w->screen, texture, unit, param); + if (function) { - glTranslatef(w->attrib.x, w->attrib.y, 0.0f); - glScalef(attrib->xScale, attrib->yScale, 0.0f); - glTranslatef(attrib->xTranslate / attrib->xScale - - w->attrib.x, - attrib->yTranslate / attrib->yScale - - w->attrib.y, 0.0f); - } + addFragmentFunction (&fa, function); + screenLighting (w->screen, TRUE); - glEnable(GL_FRAGMENT_PROGRAM_ARB); + (*w->screen->activeTexture) (GL_TEXTURE0_ARB + unit); + glBindTexture (ws->target, ws->texture[TINDEX (ws, 0)]); - if (w->screen->canDoSaturated && attrib->saturation != COLOR) - { - if (texture->target == GL_TEXTURE_2D) - program = PROGRAM_BUMP_SAT; - else - program = PROGRAM_BUMP_SAT_RECT; + plane[0] = ws->tx / (GLfloat) w->screen->width; + plane[1] = plane[2] = plane[3] = 0.0f; - ensureBumpMapProgram(w->screen, program); + glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv (GL_S, GL_EYE_PLANE, plane); + glEnable (GL_TEXTURE_GEN_S); - (*w->screen->bindProgram) (GL_FRAGMENT_PROGRAM_ARB, - ws->program[program]); + plane[0] = 0.0f; + plane[1] = ws->ty / (GLfloat) w->screen->height; + plane[2] = plane[3] = 0.0f; - (*w->screen-> - programLocalParameter4f) (GL_FRAGMENT_PROGRAM_ARB, - 0, - texture->matrix.yy * - wd-> - opt - [WATER_DISPLAY_OPTION_OFFSET_SCALE]. - value.f * 50.0f, - -texture->matrix.xx * - wd-> - opt - [WATER_DISPLAY_OPTION_OFFSET_SCALE]. - value.f * 50.0f, 0.0f, 0.0f); + glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + glTexGenfv (GL_T, GL_EYE_PLANE, plane); + glEnable (GL_TEXTURE_GEN_T); - (*w->screen-> - programLocalParameter4f) (GL_FRAGMENT_PROGRAM_ARB, - 1, - RED_SATURATION_WEIGHT, - GREEN_SATURATION_WEIGHT, - BLUE_SATURATION_WEIGHT, - attrib->saturation / 65535.0f); - } - else - { - if (texture->target == GL_TEXTURE_2D) - program = PROGRAM_BUMP; - else - program = PROGRAM_BUMP_RECT; + (*w->screen->activeTexture) (GL_TEXTURE0_ARB); - ensureBumpMapProgram(w->screen, program); - - (*w->screen->bindProgram) (GL_FRAGMENT_PROGRAM_ARB, - ws->program[program]); - - (*w->screen-> - programLocalParameter4f) (GL_FRAGMENT_PROGRAM_ARB, - 0, - texture->matrix.yy * - wd-> - opt - [WATER_DISPLAY_OPTION_OFFSET_SCALE]. - value.f * 50.0f, - -texture->matrix.xx * - wd-> - opt - [WATER_DISPLAY_OPTION_OFFSET_SCALE]. - value.f * 50.0f, 0.0f, 0.0f); + (*w->screen->programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, + param, texture->matrix.yy * + wd->opt[WATER_DISPLAY_OPTION_OFFSET_SCALE].value.f, + -texture->matrix.xx * + wd->opt[WATER_DISPLAY_OPTION_OFFSET_SCALE].value.f, + 0.0f, 0.0f); } - if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) - { - glEnable(GL_BLEND); - if (attrib->opacity != OPAQUE || attrib->brightness != BRIGHT) - { - GLushort color; + /* to get appropriate texture filtering */ + mask |= PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK; - color = (attrib->opacity * attrib->brightness) >> 16; + UNWRAP (ws, w->screen, drawWindowTexture); + (*w->screen->drawWindowTexture) (w, texture, &fa, mask); + WRAP (ws, w->screen, drawWindowTexture, waterDrawWindowTexture); - glColor4us(color, color, color, attrib->opacity); - - (*w->screen->drawWindowGeometry) (w); - - glColor4usv(defaultColor); - } - else - { - (*w->screen->drawWindowGeometry) (w); - } - - glDisable(GL_BLEND); - } - else if (attrib->brightness != BRIGHT) + if (function) { - screenTexEnvMode(w->screen, GL_MODULATE); - glColor4us(attrib->brightness, attrib->brightness, - attrib->brightness, BRIGHT); + (*w->screen->activeTexture) (GL_TEXTURE0_ARB + unit); + glDisable (GL_TEXTURE_GEN_T); + glDisable (GL_TEXTURE_GEN_S); + glBindTexture (ws->target, 0); + (*w->screen->activeTexture) (GL_TEXTURE0_ARB); - (*w->screen->drawWindowGeometry) (w); - - glColor4usv(defaultColor); - screenTexEnvMode(w->screen, GL_REPLACE); + screenLighting (w->screen, lighting); } - else - { - (*w->screen->drawWindowGeometry) (w); - } - - glDisable(GL_FRAGMENT_PROGRAM_ARB); - - glDisable(GL_TEXTURE_GEN_T); - glDisable(GL_TEXTURE_GEN_S); - - glBindTexture(ws->target, 0); - (*w->screen->activeTexture) (GL_TEXTURE0_ARB); - disableTexture(w->screen, texture); - - glPopMatrix(); - - screenLighting(w->screen, lighting); } else { @@ -2132,6 +2080,7 @@ static void waterFiniScreen(CompPlugin * p, CompScreen * s) { + WaterFunction *function, *next; int i; WATER_SCREEN(s); @@ -2152,15 +2101,23 @@ glDeleteTextures(1, &ws->texture[i]); } - for (i = 0; i < PROGRAM_NUM; i++) - { - if (ws->program[i]) - (*s->deletePrograms) (1, &ws->program[i]); - } + if (ws->program) + (*s->deletePrograms) (1, &ws->program); if (ws->data) free(ws->data); + function = ws->bumpMapFunctions; + while (function) + { + destroyFragmentFunction (s, function->handle); + + next = function->next; + free (function); + + function = next; + } + UNWRAP(ws, s, preparePaintScreen); UNWRAP(ws, s, donePaintScreen); UNWRAP(ws, s, drawWindowTexture); Index: beryl-plugins/src/scale.c =================================================================== --- beryl-plugins/src/scale.c (Revision 3571) +++ beryl-plugins/src/scale.c (Arbeitskopie) @@ -982,13 +982,20 @@ if (scaled) { + FragmentAttrib fragment; + sAttrib.xScale = sw->scale; sAttrib.yScale = sw->scale; sAttrib.xTranslate = sw->tx; sAttrib.yTranslate = sw->ty; - (*s->drawWindow) (w, &sAttrib, region, + initFragmentAttrib (&fragment, &sAttrib); + pushWindowTransform (w, &sAttrib); + + (*s->drawWindow) (w, &fragment, region, mask | PAINT_WINDOW_TRANSFORMED_MASK); + + glPopMatrix (); } if ((ss->iconOverlay != ScaleIconNone) && scaled) @@ -1153,9 +1160,21 @@ &iconReg); if (w->vCount) + { + FragmentAttrib fAttrib; + + initFragmentAttrib (&fAttrib, &sAttrib); + + if (mask & PAINT_WINDOW_TRANSFORMED_MASK) + pushWindowTransform (w, &sAttrib); + (*w->screen->drawWindowTexture) (w, - &icon->texture, &sAttrib, - mask); + &icon->texture, + &fAttrib, mask); + + if (mask & PAINT_WINDOW_TRANSFORMED_MASK) + glPopMatrix (); + } } } } Index: beryl-plugins/src/decoration.c =================================================================== --- beryl-plugins/src/decoration.c (Revision 3571) +++ beryl-plugins/src/decoration.c (Arbeitskopie) @@ -315,7 +315,7 @@ static Bool decorDrawWindow(CompWindow * w, - const WindowPaintAttrib * attrib, + const FragmentAttrib *attrib, Region region, unsigned int mask) { Bool status; @@ -327,6 +327,10 @@ DECOR_SCREEN(w->screen); DECOR_DISPLAY(w->screen->display); + UNWRAP(ds, w->screen, drawWindow); + status = (*w->screen->drawWindow) (w, attrib, region, mask); + WRAP(ds, w->screen, drawWindow, decorDrawWindow); + if (!(mask & PAINT_WINDOW_SOLID_MASK)) { DECOR_WINDOW(w); @@ -337,7 +341,7 @@ if (dw->wd && region->numRects) { WindowDecoration *wd = dw->wd; - WindowPaintAttrib sAttrib = *attrib; + FragmentAttrib fAttrib = *attrib; REGION box; int i; @@ -363,28 +367,21 @@ if (!dd->opt[DECOR_DISPLAY_OPTION_APPLY_PAINT_MODIFIERS].value.b) { - sAttrib.opacity = OPAQUE; - sAttrib.saturation = COLOR; - sAttrib.brightness = BRIGHT; + fAttrib.opacity = OPAQUE; + fAttrib.saturation = COLOR; + fAttrib.brightness = BRIGHT; } if (w->vCount) { (*w->screen->drawWindowTexture) (w, - &wd->decor->texture->texture, - &sAttrib, - mask | - PAINT_WINDOW_TRANSLUCENT_MASK - | - PAINT_WINDOW_DECORATION_MASK); + &wd->decor->texture->texture, &fAttrib, + mask | PAINT_WINDOW_TRANSLUCENT_MASK | + PAINT_WINDOW_DECORATION_MASK); } } } - UNWRAP(ds, w->screen, drawWindow); - status = (*w->screen->drawWindow) (w, attrib, region, mask); - WRAP(ds, w->screen, drawWindow, decorDrawWindow); - return status; } Index: beryl-plugins/src/switcher.c =================================================================== --- beryl-plugins/src/switcher.c (Revision 3571) +++ beryl-plugins/src/switcher.c (Arbeitskopie) @@ -1866,6 +1866,7 @@ if (w->mapNum || w->thumbPixmap) { int ww, wh; + FragmentAttrib fragment; if (ss->switchMode == RingSwitcher) { @@ -1919,8 +1920,13 @@ wx - w->attrib.x + w->input.left * sAttrib.xScale; sAttrib.yTranslate = wy - w->attrib.y + w->input.top * sAttrib.yScale; - (w->screen->drawWindow) (w, &sAttrib, getInfiniteRegion(), mask); + initFragmentAttrib (&fragment, &sAttrib); + pushWindowTransform (w, &sAttrib); + (w->screen->drawWindow) (w, &fragment, getInfiniteRegion(), mask); + + glPopMatrix (); + if (ss->opt[SWITCH_SCREEN_OPTION_ICON].value.b) { icon = getWindowIcon(w, 96, 96); @@ -2076,8 +2082,17 @@ addWindowGeometry(w, &matrix, 1, &iconReg, getInfiniteRegion()); if (w->vCount) + { + FragmentAttrib fAttrib; + + initFragmentAttrib (&fAttrib, &sAttrib); + pushWindowTransform (w, &sAttrib); + (*w->screen->drawWindowTexture) (w, - &icon->texture, &sAttrib, mask); + &icon->texture, &fAttrib, mask); + + glPopMatrix (); + } } w->screen->drawWindowGeometry = oldDrawWindowGeometry; Index: beryl-core/include/beryl.h =================================================================== --- beryl-core/include/beryl.h (Revision 3571) +++ beryl-core/include/beryl.h (Arbeitskopie) @@ -26,7 +26,7 @@ #ifndef _BERYL_H #define _BERYL_H -#define BERYL_VERSION 50 +#define BERYL_VERSION 51 #define BERYL_ABI_INFO \ BERYL_VERSION, \ @@ -91,13 +91,17 @@ #define N_(x) x #endif -typedef struct _CompPlugin CompPlugin; -typedef struct _CompDisplay CompDisplay; -typedef struct _CompScreen CompScreen; -typedef struct _CompWindow CompWindow; -typedef struct _CompTexture CompTexture; -typedef struct _CompIcon CompIcon; +typedef struct _CompPlugin CompPlugin; +typedef struct _CompDisplay CompDisplay; +typedef struct _CompScreen CompScreen; +typedef struct _CompWindow CompWindow; +typedef struct _CompTexture CompTexture; +typedef struct _CompIcon CompIcon; typedef struct _CompWindowExtents CompWindowExtents; +typedef struct _CompProgram CompProgram; +typedef struct _CompFunction CompFunction; +typedef struct _CompFunctionData CompFunctionData; +typedef struct _FragmentAttrib FragmentAttrib; /* virtual modifiers */ @@ -1206,10 +1210,10 @@ Region region, unsigned int mask); -typedef Bool (*DrawWindowProc) (CompWindow *window, - const WindowPaintAttrib *attrib, - Region region, - unsigned int mask); +typedef Bool (*DrawWindowProc) (CompWindow *window, + const FragmentAttrib *attrib, + Region region, + unsigned int mask); typedef void (*AddWindowGeometryProc) (CompWindow *window, CompMatrix *matrix, @@ -1217,9 +1221,9 @@ Region region, Region clip); -typedef void (*DrawWindowTextureProc) (CompWindow *w, +typedef void (*DrawWindowTextureProc) (CompWindow *w, CompTexture *texture, - const WindowPaintAttrib *attrib, + const FragmentAttrib *fragment, unsigned int mask); typedef void (*DrawWindowGeometryProc) (CompWindow *window); @@ -1290,14 +1294,14 @@ void drawWindowTexture (CompWindow *w, CompTexture *texture, - const WindowPaintAttrib *attrib, + const FragmentAttrib *fragment, unsigned int mask); Bool -drawWindow (CompWindow *w, - const WindowPaintAttrib *attrib, - Region region, - unsigned int mask); +drawWindow (CompWindow *w, + const FragmentAttrib *attrib, + Region region, + unsigned int mask); Bool paintWindow (CompWindow *w, @@ -1310,6 +1314,9 @@ Region region, unsigned int mask); +void +pushWindowTransform (CompWindow *w, + const WindowPaintAttrib *attrib); /* texture.c */ @@ -1526,7 +1533,7 @@ GLenum format, GLsizei len, const GLvoid *string); -typedef void (*GLProgramLocalParameter4fProc) (GLenum target, +typedef void (*GLProgramParameter4fProc) (GLenum target, GLuint index, GLfloat x, GLfloat y, @@ -1798,6 +1805,13 @@ int timeLeft; Bool pendingCommands; + int lastFunctionId; + + CompFunction *fragmentFunctions; + CompProgram *fragmentPrograms; + + int saturateFunction[2][64]; + Bool cleared; Bool lighting; @@ -1828,11 +1842,12 @@ GLActiveTextureProc activeTexture; GLClientActiveTextureProc clientActiveTexture; - GLGenProgramsProc genPrograms; - GLDeleteProgramsProc deletePrograms; - GLBindProgramProc bindProgram; - GLProgramStringProc programString; - GLProgramLocalParameter4fProc programLocalParameter4f; + GLGenProgramsProc genPrograms; + GLDeleteProgramsProc deletePrograms; + GLBindProgramProc bindProgram; + GLProgramStringProc programString; + GLProgramParameter4fProc programEnvParameter4f; + GLProgramParameter4fProc programLocalParameter4f; GLGenFramebuffersProc genFramebuffers; GLDeleteFramebuffersProc deleteFramebuffers; @@ -2851,6 +2866,104 @@ void closeSession (void); + +/* fragment.c */ + +#define MAX_FRAGMENT_FUNCTIONS 16 + +struct _FragmentAttrib { + GLushort opacity; + GLushort brightness; + GLushort saturation; + int nTexture; + int function[MAX_FRAGMENT_FUNCTIONS]; + int nFunction; + int nParam; +}; + +CompFunctionData * +createFunctionData (void); + +void +destroyFunctionData (CompFunctionData *data); + +Bool +addTempHeaderOpToFunctionData (CompFunctionData *data, + char *name); + +Bool +addParamHeaderOpToFunctionData (CompFunctionData *data, + char *name); + +Bool +addAttribHeaderOpToFunctionData (CompFunctionData *data, + char *name); + +#define COMP_FETCH_TARGET_2D 0 +#define COMP_FETCH_TARGET_RECT 1 +#define COMP_FETCH_TARGET_NUM 2 + +Bool +addFetchOpToFunctionData (CompFunctionData *data, + char *dst, + char *offset, + int target); + +Bool +addColorOpToFunctionData (CompFunctionData *data, + char *dst, + char *src); + +Bool +addDataOpToFunctionData (CompFunctionData *data, + char *str); + +Bool +addBlendOpToFunctionData (CompFunctionData *data, + char *str); + +int +createFragmentFunction (CompScreen *s, + char *name, + CompFunctionData *data); + +void +destroyFragmentFunction (CompScreen *s, + int id); + +int +getSaturateFragmentFunction (CompScreen *s, + CompTexture *texture, + int param); + +int +allocFragmentTextureUnits (FragmentAttrib *attrib, + int nTexture); + +int +allocFragmentParameters (FragmentAttrib *attrib, + int nParam); + +void +addFragmentFunction (FragmentAttrib *attrib, + int function); + +void +initFragmentAttrib (FragmentAttrib *attrib, + const WindowPaintAttrib *paint); +Bool +enableFragmentAttrib (CompScreen *s, + FragmentAttrib *attrib, + Bool *blending); + +void +disableFragmentAttrib (CompScreen *s, + FragmentAttrib *attrib); + + /* activation.c */ -Bool shouldFocusWindow(CompWindow * w, Time t); + +Bool +shouldFocusWindow(CompWindow * w, Time t); + #endif Index: beryl-core/src/paint.c =================================================================== --- beryl-core/src/paint.c (Revision 3571) +++ beryl-core/src/paint.c (Arbeitskopie) @@ -888,42 +888,105 @@ } } -void -drawWindowTexture(CompWindow * w, - CompTexture * texture, - const WindowPaintAttrib * attrib, unsigned int mask) +static Bool +enableFragmentProgramAndDrawGeometry (CompWindow *w, + CompTexture *texture, + const FragmentAttrib *attrib, + int filter, + unsigned int mask) { - int filter; + FragmentAttrib fa = *attrib; + CompScreen *s = w->screen; + Bool blending; - glPushMatrix(); + if (s->canDoSaturated && attrib->saturation != COLOR) + { + int param, function; - if (mask & PAINT_WINDOW_TRANSFORMED_MASK) + param = allocFragmentParameters (&fa, 1); + function = getSaturateFragmentFunction (s, texture, param); + + addFragmentFunction (&fa, function); + + (*s->programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, param, + RED_SATURATION_WEIGHT, + GREEN_SATURATION_WEIGHT, + BLUE_SATURATION_WEIGHT, + attrib->saturation / 65535.0f); + } + + if (!enableFragmentAttrib (s, &fa, &blending)) + return FALSE; + + enableTexture (s, texture, filter); + + if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) { - glTranslatef(w->attrib.x, w->attrib.y, 0.0f); - glScalef(attrib->xScale, attrib->yScale, 1.0f); - glTranslatef(attrib->xTranslate / attrib->xScale - - w->attrib.x, - attrib->yTranslate / attrib->yScale - w->attrib.y, 0.0f); + if (blending) + glEnable (GL_BLEND); - filter = w->screen->filter[WINDOW_TRANS_FILTER]; + if (attrib->opacity != OPAQUE || attrib->brightness != BRIGHT) + { + GLushort color; + + color = (attrib->opacity * attrib->brightness) >> 16; + + screenTexEnvMode (s, GL_MODULATE); + glColor4us (color, color, color, attrib->opacity); + + (*s->drawWindowGeometry) (w); + + glColor4usv (defaultColor); + screenTexEnvMode (s, GL_REPLACE); + } + else + { + (*s->drawWindowGeometry) (w); + } + + if (blending) + glDisable (GL_BLEND); } - else if (mask & PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK) + else if (attrib->brightness != BRIGHT) { - filter = w->screen->filter[SCREEN_TRANS_FILTER]; + screenTexEnvMode (s, GL_MODULATE); + glColor4us (attrib->brightness, attrib->brightness, + attrib->brightness, BRIGHT); + + (*w->screen->drawWindowGeometry) (w); + + glColor4usv (defaultColor); + screenTexEnvMode (s, GL_REPLACE); } else { - filter = w->screen->filter[NOTHING_TRANS_FILTER]; + (*w->screen->drawWindowGeometry) (w); } - if (w->screen->canDoSaturated && attrib->saturation != COLOR) + disableTexture (w->screen, texture); + + disableFragmentAttrib (s, &fa); + + return TRUE; +} + +static void +enableFragmentOperationsAndDrawGeometry (CompWindow *w, + CompTexture *texture, + const FragmentAttrib *attrib, + int filter, + unsigned int mask) +{ + CompScreen *s = w->screen; + + if (s->canDoSaturated && attrib->saturation != COLOR) { GLfloat constant[4]; if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) glEnable(GL_BLEND); - enableTexture(w->screen, texture, filter); + enableTexture(s, texture, filter); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); @@ -941,9 +1004,9 @@ glColor4f(1.0f, 1.0f, 1.0f, 0.5f); - w->screen->activeTexture(GL_TEXTURE1_ARB); + s->activeTexture(GL_TEXTURE1_ARB); - enableTexture(w->screen, texture, filter); + enableTexture(s, texture, filter); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); @@ -953,7 +1016,7 @@ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - if (w->screen->canDoSlightlySaturated && attrib->saturation > 0) + if (s->canDoSlightlySaturated && attrib->saturation > 0) { glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); @@ -966,9 +1029,9 @@ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant); - w->screen->activeTexture(GL_TEXTURE2_ARB); + s->activeTexture(GL_TEXTURE2_ARB); - enableTexture(w->screen, texture, filter); + enableTexture(s, texture, filter); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); @@ -990,9 +1053,9 @@ if (attrib->opacity < OPAQUE || attrib->brightness != BRIGHT) { - w->screen->activeTexture(GL_TEXTURE3_ARB); + s->activeTexture(GL_TEXTURE3_ARB); - enableTexture(w->screen, texture, filter); + enableTexture(s, texture, filter); constant[3] = attrib->opacity / 65535.0f; constant[0] = constant[1] = constant[2] = @@ -1014,24 +1077,24 @@ glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); - (*w->screen->drawWindowGeometry) (w); + (*s->drawWindowGeometry) (w); - disableTexture(w->screen, texture); + disableTexture(s, texture); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - w->screen->activeTexture(GL_TEXTURE2_ARB); + s->activeTexture(GL_TEXTURE2_ARB); } else { - (*w->screen->drawWindowGeometry) (w); + (*s->drawWindowGeometry) (w); } - disableTexture(w->screen, texture); + disableTexture(s, texture); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - w->screen->activeTexture(GL_TEXTURE1_ARB); + s->activeTexture(GL_TEXTURE1_ARB); } else { @@ -1051,26 +1114,26 @@ glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant); - (*w->screen->drawWindowGeometry) (w); + (*s->drawWindowGeometry) (w); } - disableTexture(w->screen, texture); + disableTexture(s, texture); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - w->screen->activeTexture(GL_TEXTURE0_ARB); + s->activeTexture(GL_TEXTURE0_ARB); - disableTexture(w->screen, texture); + disableTexture(s, texture); glColor4usv(defaultColor); - screenTexEnvMode(w->screen, GL_REPLACE); + screenTexEnvMode(s, GL_REPLACE); if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) glDisable(GL_BLEND); } else { - enableTexture(w->screen, texture, filter); + enableTexture(s, texture, filter); if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) { @@ -1081,31 +1144,31 @@ color = (attrib->opacity * attrib->brightness) >> 16; - screenTexEnvMode(w->screen, GL_MODULATE); + screenTexEnvMode(s, GL_MODULATE); glColor4us(color, color, color, attrib->opacity); - (*w->screen->drawWindowGeometry) (w); + (*s->drawWindowGeometry) (w); glColor4usv(defaultColor); - screenTexEnvMode(w->screen, GL_REPLACE); + screenTexEnvMode(s, GL_REPLACE); } else { - (*w->screen->drawWindowGeometry) (w); + (*s->drawWindowGeometry) (w); } glDisable(GL_BLEND); } else if (attrib->brightness != BRIGHT) { - screenTexEnvMode(w->screen, GL_MODULATE); + screenTexEnvMode(s, GL_MODULATE); glColor4us(attrib->brightness, attrib->brightness, attrib->brightness, BRIGHT); - (*w->screen->drawWindowGeometry) (w); + (*s->drawWindowGeometry) (w); glColor4usv(defaultColor); - screenTexEnvMode(w->screen, GL_REPLACE); + screenTexEnvMode(s, GL_REPLACE); } else { @@ -1114,14 +1177,43 @@ disableTexture(w->screen, texture); } +} - glPopMatrix(); +void +drawWindowTexture (CompWindow *w, + CompTexture *texture, + const FragmentAttrib *attrib, + unsigned int mask) +{ + int filter; + + glPushMatrix (); + + if (mask & PAINT_WINDOW_TRANSFORMED_MASK) + { + filter = w->screen->filter[WINDOW_TRANS_FILTER]; + } + else if (mask & PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK) + { + filter = w->screen->filter[SCREEN_TRANS_FILTER]; + } + else + { + filter = w->screen->filter[NOTHING_TRANS_FILTER]; + } + + if (!attrib->nFunction || !enableFragmentProgramAndDrawGeometry (w, + texture, attrib, filter, mask)) + { + enableFragmentOperationsAndDrawGeometry (w,texture, + attrib, filter, mask); + } } Bool -drawWindow(CompWindow * w, - const WindowPaintAttrib * attrib, Region region, unsigned int mask) +drawWindow(CompWindow * w, const FragmentAttrib *fragment, + Region region, unsigned int mask) { if (mask & PAINT_WINDOW_TRANSFORMED_MASK) region = &infiniteRegion; @@ -1137,12 +1229,12 @@ if (w->alpha) return FALSE; - if (attrib->opacity != OPAQUE) + if (fragment->opacity != OPAQUE) return FALSE; } else if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) { - if (!w->alpha && attrib->opacity == OPAQUE) + if (!w->alpha && fragment->opacity == OPAQUE) return FALSE; } else @@ -1150,7 +1242,7 @@ if (w->attrib.map_state != IsViewable && !w->thumbPixmap) return TRUE; - if (w->alpha || attrib->opacity != OPAQUE) + if (w->alpha || fragment->opacity != OPAQUE) mask |= PAINT_WINDOW_TRANSLUCENT_MASK; else mask |= PAINT_WINDOW_SOLID_MASK; @@ -1165,7 +1257,8 @@ (*w->screen->addWindowGeometry) (w, &w->thumbMatrix, 1, w->region, region); if (w->vCount) { - (*w->screen->drawWindowTexture) (w, w->thumbTexture, attrib, mask); + (*w->screen->drawWindowTexture) (w, w->thumbTexture, + fragment, mask); } return TRUE; } @@ -1180,7 +1273,7 @@ (*w->screen->addWindowGeometry) (w, &w->matrix, 1, w->region, region); if (w->vCount) { - (*w->screen->drawWindowTexture) (w, w->texture, attrib, mask); + (*w->screen->drawWindowTexture) (w, w->texture, fragment, mask); } return TRUE; @@ -1190,6 +1283,9 @@ paintWindow(CompWindow * w, const WindowPaintAttrib * attrib, Region region, unsigned int mask) { + FragmentAttrib fragment; + Bool status; + w->lastPaint = *attrib; if (w->state & CompWindowStateOffscreenMask) @@ -1203,7 +1299,17 @@ return TRUE; } - return (*w->screen->drawWindow) (w, attrib, region, mask); + initFragmentAttrib (&fragment, attrib); + + if (mask & PAINT_WINDOW_TRANSFORMED_MASK) + pushWindowTransform (w, attrib); + + status = (*w->screen->drawWindow) (w, &fragment, region, mask); + + if (mask & PAINT_WINDOW_TRANSFORMED_MASK) + glPopMatrix (); + + return status; } void paintBackground(CompScreen * s, Region region, unsigned int mask) @@ -1287,3 +1393,16 @@ free(data); } + +void +pushWindowTransform (CompWindow *w, + const WindowPaintAttrib *attrib) +{ + glPushMatrix (); + + glTranslatef (w->attrib.x, w->attrib.y, 0.0f); + glScalef (attrib->xScale, attrib->yScale, 0.0f); + glTranslatef (attrib->xTranslate / attrib->xScale - w->attrib.x, + attrib->yTranslate / attrib->yScale - w->attrib.y, + 0.0f); +} Index: beryl-core/src/screen.c =================================================================== --- beryl-core/src/screen.c (Revision 3571) +++ beryl-core/src/screen.c (Arbeitskopie) @@ -1298,6 +1298,13 @@ s->pendingCommands = TRUE; + s->lastFunctionId = 0; + + s->fragmentFunctions = NULL; + s->fragmentPrograms = NULL; + + memset (s->saturateFunction, 0, sizeof (s->saturateFunction)); + s->showingDesktopMask = 0; s->overlayWindowCount = 0; @@ -1586,13 +1593,14 @@ getProcAddress(s, "glBindProgramARB"); s->programString = (GLProgramStringProc) getProcAddress(s, "glProgramStringARB"); - s->programLocalParameter4f = - (GLProgramLocalParameter4fProc) + s->programEnvParameter4f = (GLProgramParameter4fProc) + getProcAddress(s, "glProgramEnvParameter4fARB"); + s->programLocalParameter4f = (GLProgramParameter4fProc) getProcAddress(s, "glProgramLocalParameter4fARB"); - if (s->genPrograms && - s->deletePrograms && - s->bindProgram && s->programString && s->programLocalParameter4f) + if (s->genPrograms && s->deletePrograms && + s->bindProgram && s->programString && + s->programEnvParameter4f && s->programLocalParameter4f) s->fragmentProgram = 1; } Index: beryl-core/src/Makefile.am =================================================================== --- beryl-core/src/Makefile.am (Revision 3571) +++ beryl-core/src/Makefile.am (Arbeitskopie) @@ -29,6 +29,7 @@ option.c \ plugin.c \ session.c \ + fragment.c \ screen_options.c \ display_options.c \ type_mask.c \