summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZack Rusin <zack@kde.org>2006-01-02 07:11:21 +0000
committerZack Rusin <zack@kde.org>2006-01-02 07:11:21 +0000
commitba0bd60b9261a0bcedba9dfc1905d8929e14d440 (patch)
tree93be25405222a4e0732ccdf1511ddd92534adc30 /src
parent7f820289fc18e20881b56227cef6d0f1b5353f3d (diff)
updating from airlied copy and adding cvsignores
Diffstat (limited to 'src')
-rw-r--r--src/.cvsignore5
-rw-r--r--src/display.c24
-rw-r--r--src/event.c64
-rw-r--r--src/glxcompmgr.c11
-rw-r--r--src/paint.c399
-rw-r--r--src/screen.c66
-rw-r--r--src/texture.c31
-rw-r--r--src/window.c69
8 files changed, 430 insertions, 239 deletions
diff --git a/src/.cvsignore b/src/.cvsignore
new file mode 100644
index 0000000..51cbb8e
--- /dev/null
+++ b/src/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+Makefile.in
+glxcompmgr
+.deps
+.libs
diff --git a/src/display.c b/src/display.c
index 69d01b0..0a11d80 100644
--- a/src/display.c
+++ b/src/display.c
@@ -1010,8 +1010,7 @@ addDisplay (char *name,
d->initPluginForDisplay = initPluginForDisplay;
d->finiPluginForDisplay = finiPluginForDisplay;
- d->handleEvent = handleEvent;
- d->handleDamageEvent = handleDamageEvent;
+ d->handleEvent = handleEvent;
d->winTypeAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE", 0);
d->winDesktopAtom = XInternAtom (dpy, "_NET_WM_WINDOW_TYPE_DESKTOP", 0);
@@ -1135,14 +1134,21 @@ CompWindow *
findWindowAtDisplay (CompDisplay *d,
Window id)
{
- CompScreen *s;
- CompWindow *w;
-
- for (s = d->screens; s; s = s->next)
+ if (lastFoundWindow && lastFoundWindow->id == id)
+ {
+ return lastFoundWindow;
+ }
+ else
{
- w = findWindowAtScreen (s, id);
- if (w)
- return w;
+ CompScreen *s;
+ CompWindow *w;
+
+ for (s = d->screens; s; s = s->next)
+ {
+ w = findWindowAtScreen (s, id);
+ if (w)
+ return w;
+ }
}
return 0;
diff --git a/src/event.c b/src/event.c
index ccabfca..6dd80b7 100644
--- a/src/event.c
+++ b/src/event.c
@@ -230,39 +230,45 @@ handleEvent (CompDisplay *display,
}
else if (event->type == display->damageEvent + XDamageNotify)
{
- (*display->handleDamageEvent) (display,
- (XDamageNotifyEvent *) event);
- }
- break;
- }
-}
+ XDamageNotifyEvent *de = (XDamageNotifyEvent *) event;
-void
-handleDamageEvent (CompDisplay *display,
- XDamageNotifyEvent *event)
-{
- CompScreen *screen;
- REGION rect;
-
- rect.rects = &rect.extents;
- rect.numRects = rect.size = 1;
+ if (lastDamagedWindow && de->drawable == lastDamagedWindow->id)
+ {
+ w = lastDamagedWindow;
+ }
+ else
+ {
+ w = findWindowAtDisplay (display, de->drawable);
+ if (w)
+ lastDamagedWindow = w;
+ }
- screen = display->screens;
- if (screen->next)
- {
- CompWindow *w;
+ if (w)
+ {
+ REGION region;
+ Bool initial = FALSE;
- w = findWindowAtDisplay (display, event->drawable);
- if (!w)
- return;
+ if (!w->damaged)
+ {
+ w->damaged = initial = TRUE;
+ w->invisible = WINDOW_INVISIBLE (w);
+ }
- screen = w->screen;
- }
+ region.extents.x1 = de->geometry.x + de->area.x;
+ region.extents.y1 = de->geometry.y + de->area.y;
+ region.extents.x2 = region.extents.x1 + de->area.width;
+ region.extents.y2 = region.extents.y1 + de->area.height;
- rect.extents.x1 = event->geometry.x + event->area.x;
- rect.extents.y1 = event->geometry.y + event->area.y;
- rect.extents.x2 = rect.extents.x1 + event->area.width;
- rect.extents.y2 = rect.extents.y1 + event->area.height;
+ if (!(*w->screen->damageWindowRect) (w, initial,
+ &region.extents))
+ {
+ region.rects = &region.extents;
+ region.numRects = region.size = 1;
- damageScreenRegion (screen, &rect);
+ damageScreenRegion (w->screen, &region);
+ }
+ }
+ }
+ break;
+ }
}
diff --git a/src/glxcompmgr.c b/src/glxcompmgr.c
index 21673f3..0862d38 100644
--- a/src/glxcompmgr.c
+++ b/src/glxcompmgr.c
@@ -39,6 +39,7 @@ char *backgroundImage = "background.png";
char *windowImage = "window.png";
REGION emptyRegion;
+REGION infiniteRegion;
GLushort defaultColor[4] = { 0, 0, 0, 0 };
Window currentRoot = 0;
@@ -48,6 +49,9 @@ char *defaultTextureFilter = "Good";
Bool testMode = FALSE;
Bool restartSignal = FALSE;
+CompWindow *lastFoundWindow = 0;
+CompWindow *lastDamagedWindow = 0;
+
static void
usage (void)
{
@@ -91,6 +95,13 @@ main (int argc, char **argv)
emptyRegion.extents.y2 = 0;
emptyRegion.size = 0;
+ infiniteRegion.rects = &infiniteRegion.extents;
+ infiniteRegion.numRects = 1;
+ infiniteRegion.extents.x1 = MINSHORT;
+ infiniteRegion.extents.y1 = MINSHORT;
+ infiniteRegion.extents.x2 = MAXSHORT;
+ infiniteRegion.extents.y2 = MAXSHORT;
+
for (i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "--help"))
diff --git a/src/paint.c b/src/paint.c
index 5174e95..29e5646 100644
--- a/src/paint.c
+++ b/src/paint.c
@@ -86,8 +86,14 @@ paintTransformedScreen (CompScreen *screen,
glEnable (GL_STENCIL_TEST);
for (w = screen->windows; w; w = w->next)
- (*screen->paintWindow) (w, wAttrib, &screen->region,
- windowMask);
+ {
+ if (w->destroyed || w->attrib.map_state != IsViewable)
+ continue;
+
+ if (w->damaged)
+ (*screen->paintWindow) (w, wAttrib, &screen->region,
+ windowMask);
+ }
glDisable (GL_STENCIL_TEST);
@@ -102,7 +108,13 @@ paintTransformedScreen (CompScreen *screen,
(*screen->paintBackground) (screen, &screen->region, backgroundMask);
for (w = screen->windows; w; w = w->next)
- (*screen->paintWindow) (w, wAttrib, &screen->region, windowMask);
+ {
+ if (w->destroyed || w->attrib.map_state != IsViewable)
+ continue;
+
+ if (w->damaged)
+ (*screen->paintWindow) (w, wAttrib, &screen->region, windowMask);
+ }
glPopMatrix ();
}
@@ -164,7 +176,7 @@ paintScreen (CompScreen *screen,
/* paint solid windows */
for (w = screen->reverseWindows; w; w = w->prev)
{
- if (w->invisible)
+ if (w->destroyed || w->invisible)
continue;
if ((*screen->paintWindow) (w, wAttrib, tmpRegion,
@@ -173,18 +185,23 @@ paintScreen (CompScreen *screen,
/* copy region */
XSubtractRegion (tmpRegion, &emptyRegion, w->clip);
+
+ if (!tmpRegion->numRects)
+ break;
}
- (*screen->paintBackground) (screen, tmpRegion, 0);
+ if (tmpRegion->numRects)
+ (*screen->paintBackground) (screen, tmpRegion, 0);
/* paint translucent windows */
for (w = screen->windows; w; w = w->next)
{
- if (w->invisible)
+ if (w->destroyed || w->invisible)
continue;
- (*screen->paintWindow) (w, wAttrib, w->clip,
- PAINT_WINDOW_TRANSLUCENT_MASK);
+ if (w->clip->numRects)
+ (*screen->paintWindow) (w, wAttrib, w->clip,
+ PAINT_WINDOW_TRANSLUCENT_MASK);
}
glPopMatrix ();
@@ -192,146 +209,127 @@ paintScreen (CompScreen *screen,
return TRUE;
}
-#define ADD_QUAD(data, w, x1, y1, x2, y2) \
- if (!(w)->pixmap) \
- bindWindow (w); \
- *(data)++ = X_WINDOW_TO_TEXTURE_SPACE (w, x1); \
- *(data)++ = Y_WINDOW_TO_TEXTURE_SPACE (w, y2); \
- *(data)++ = (x1); \
- *(data)++ = (y2); \
- *(data)++ = X_WINDOW_TO_TEXTURE_SPACE (w, x2); \
- *(data)++ = Y_WINDOW_TO_TEXTURE_SPACE (w, y2); \
- *(data)++ = (x2); \
- *(data)++ = (y2); \
- *(data)++ = X_WINDOW_TO_TEXTURE_SPACE (w, x2); \
- *(data)++ = Y_WINDOW_TO_TEXTURE_SPACE (w, y1); \
- *(data)++ = (x2); \
- *(data)++ = (y1); \
- *(data)++ = X_WINDOW_TO_TEXTURE_SPACE (w, x1); \
- *(data)++ = Y_WINDOW_TO_TEXTURE_SPACE (w, y1); \
- *(data)++ = (x1); \
+#define ADD_QUAD(data, m, n, x1, y1, x2, y2) \
+ for (it = 0; it < n; it++) \
+ { \
+ *(data)++ = COMP_TEX_COORD_X (&m[it], x1, y2); \
+ *(data)++ = COMP_TEX_COORD_Y (&m[it], x1, y2); \
+ } \
+ *(data)++ = (x1); \
+ *(data)++ = (y2); \
+ for (it = 0; it < n; it++) \
+ { \
+ *(data)++ = COMP_TEX_COORD_X (&m[it], x2, y2); \
+ *(data)++ = COMP_TEX_COORD_Y (&m[it], x2, y2); \
+ } \
+ *(data)++ = (x2); \
+ *(data)++ = (y2); \
+ for (it = 0; it < n; it++) \
+ { \
+ *(data)++ = COMP_TEX_COORD_X (&m[it], x2, y1); \
+ *(data)++ = COMP_TEX_COORD_Y (&m[it], x2, y1); \
+ } \
+ *(data)++ = (x2); \
+ *(data)++ = (y1); \
+ for (it = 0; it < n; it++) \
+ { \
+ *(data)++ = COMP_TEX_COORD_X (&m[it], x1, y1); \
+ *(data)++ = COMP_TEX_COORD_Y (&m[it], x1, y1); \
+ } \
+ *(data)++ = (x1); \
*(data)++ = (y1)
-#define ADD_BOX(data, w, box) \
- ADD_QUAD (data, w, (box)->x1, (box)->y1, (box)->x2, (box)->y2)
-
Bool
-paintWindow (CompWindow *w,
- const WindowPaintAttrib *attrib,
- Region region,
- unsigned int mask)
+moreWindowVertices (CompWindow *w,
+ int newSize)
{
- BoxPtr pClip;
- int nClip, n;
- GLfloat *data, *d;
- GLushort opacity;
- int x1, y1, x2, y2;
-
- if (!region->numRects)
- return TRUE;
-
- if (w->destroyed || w->attrib.map_state != IsViewable)
- return TRUE;
-
- if (mask & PAINT_WINDOW_SOLID_MASK)
+ if (newSize > w->vertexSize)
{
- if (w->alpha)
- return FALSE;
+ GLfloat *vertices;
- opacity = MULTIPLY_USHORT (w->opacity, attrib->opacity);
- if (opacity != OPAQUE)
+ vertices = realloc (w->vertices, sizeof (GLfloat) * newSize);
+ if (!vertices)
return FALSE;
+
+ w->vertices = vertices;
+ w->vertexSize = newSize;
}
- else if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
+
+ return TRUE;
+}
+
+Bool
+moreWindowIndices (CompWindow *w,
+ int newSize)
+{
+ if (newSize > w->indexSize)
{
- opacity = MULTIPLY_USHORT (w->opacity, attrib->opacity);
- if (!w->alpha && opacity == OPAQUE)
+ GLushort *indices;
+
+ indices = realloc (w->indices, sizeof (GLushort) * newSize);
+ if (!indices)
return FALSE;
- }
- else
- {
- opacity = MULTIPLY_USHORT (w->opacity, attrib->opacity);
- if (w->alpha || opacity != OPAQUE)
- mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
- else
- mask |= PAINT_WINDOW_SOLID_MASK;
+
+ w->indices = indices;
+ w->indexSize = newSize;
}
- if (attrib->xTranslate != 0.0f ||
- attrib->yTranslate != 0.0f ||
- attrib->xScale != 1.0f ||
- attrib->yScale != 1.0f)
- {
- nClip = w->region->numRects;
- pClip = w->region->rects;
+ return TRUE;
+}
- mask |= PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
+void
+addWindowGeometry (CompWindow *w,
+ CompMatrix *matrix,
+ int nMatrix,
+ Region region,
+ Region clip)
+{
+ BoxRec full;
- data = malloc (sizeof (GLfloat) * nClip * 16);
- if (!data)
- return FALSE;
+ w->texUnits = nMatrix;
- d = data;
+ full = clip->extents;
+ if (region->extents.x1 > full.x1)
+ full.x1 = region->extents.x1;
+ if (region->extents.y1 > full.y1)
+ full.y1 = region->extents.y1;
+ if (region->extents.x2 < full.x2)
+ full.x2 = region->extents.x2;
+ if (region->extents.y2 < full.y2)
+ full.y2 = region->extents.y2;
- n = nClip;
- while (nClip--)
- {
- x1 = pClip->x1 - w->attrib.x;
- y1 = pClip->y1 - w->attrib.y;
- x2 = pClip->x2 - w->attrib.x;
- y2 = pClip->y2 - w->attrib.y;
+ if (full.x1 < full.x2 && full.y1 < full.y2)
+ {
+ BoxPtr pBox;
+ int nBox;
+ BoxPtr pClip;
+ int nClip;
+ BoxRec cbox;
+ int vSize;
+ int n, it, x1, y1, x2, y2;
+ GLfloat *d;
- ADD_QUAD (d, w, x1, y1, x2, y2);
+ pBox = region->rects;
+ nBox = region->numRects;
- pClip++;
+ vSize = 2 + nMatrix * 2;
+
+ n = w->vCount / 4;
+
+ if ((n + nBox) * vSize * 4 > w->vertexSize)
+ {
+ if (!moreWindowVertices (w, (n + nBox) * vSize * 4))
+ return;
}
- }
- else
- {
- BoxRec clip, full;
- BoxPtr pExtent = &region->extents;
- BoxPtr pBox = region->rects;
- int nBox = region->numRects;
- int dataSize;
-
- full.x1 = 0;
- full.y1 = 0;
- full.x2 = w->width;
- full.y2 = w->height;
-
- x1 = pExtent->x1 - w->attrib.x;
- y1 = pExtent->y1 - w->attrib.y;
- x2 = pExtent->x2 - w->attrib.x;
- y2 = pExtent->y2 - w->attrib.y;
-
- if (x1 > 0)
- full.x1 = x1;
- if (y1 > 0)
- full.y1 = y1;
- if (x2 < w->width)
- full.x2 = x2;
- if (y2 < w->height)
- full.y2 = y2;
-
- if (full.x1 >= full.x2 || full.y1 >= full.y2)
- return TRUE;
-
- dataSize = nBox * 16;
- data = malloc (sizeof (GLfloat) * dataSize);
- if (!data)
- return FALSE;
- d = data;
- n = 0;
+ d = w->vertices + (w->vCount * vSize);
- pBox = region->rects;
- nBox = region->numRects;
while (nBox--)
{
- x1 = pBox->x1 - w->attrib.x;
- y1 = pBox->y1 - w->attrib.y;
- x2 = pBox->x2 - w->attrib.x;
- y2 = pBox->y2 - w->attrib.y;
+ x1 = pBox->x1;
+ y1 = pBox->y1;
+ x2 = pBox->x2;
+ y2 = pBox->y2;
pBox++;
@@ -346,50 +344,45 @@ paintWindow (CompWindow *w,
if (x1 < x2 && y1 < y2)
{
- nClip = w->region->numRects;
+ nClip = clip->numRects;
if (nClip == 1)
{
- ADD_QUAD (d, w, x1, y1, x2, y2);
+ ADD_QUAD (d, matrix, nMatrix, x1, y1, x2, y2);
n++;
}
else
{
- pClip = w->region->rects;
+ pClip = clip->rects;
+
+ if (((n + nClip) * vSize * 4) > w->vertexSize)
+ {
+ if (!moreWindowVertices (w, (n + nClip) * vSize * 4))
+ return;
+
+ d = w->vertices + (n * vSize * 4);
+ }
while (nClip--)
{
- clip.x1 = pClip->x1 - w->attrib.x;
- clip.y1 = pClip->y1 - w->attrib.y;
- clip.x2 = pClip->x2 - w->attrib.x;
- clip.y2 = pClip->y2 - w->attrib.y;
+ cbox = *pClip;
pClip++;
- if (clip.x1 < x1)
- clip.x1 = x1;
- if (clip.y1 < y1)
- clip.y1 = y1;
- if (clip.x2 > x2)
- clip.x2 = x2;
- if (clip.y2 > y2)
- clip.y2 = y2;
+ if (cbox.x1 < x1)
+ cbox.x1 = x1;
+ if (cbox.y1 < y1)
+ cbox.y1 = y1;
+ if (cbox.x2 > x2)
+ cbox.x2 = x2;
+ if (cbox.y2 > y2)
+ cbox.y2 = y2;
- if (clip.x1 < clip.x2 && clip.y1 < clip.y2)
+ if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)
{
- if ((n << 4) == dataSize)
- {
- dataSize <<= 2;
- data = realloc (data,
- sizeof (GLfloat) * dataSize);
- if (!data)
- return FALSE;
-
- d = data + (n * 16);
- }
-
- ADD_BOX (d, w, &clip);
+ ADD_QUAD (d, matrix, nMatrix,
+ cbox.x1, cbox.y1, cbox.x2, cbox.y2);
n++;
}
@@ -397,13 +390,78 @@ paintWindow (CompWindow *w,
}
}
}
+ w->vCount = n * 4;
+ }
+}
+
+void
+drawWindowGeometry (CompWindow *w)
+{
+ int texUnit = w->texUnits;
+ int currentTexUnit = 0;
+ int stride = (1 + texUnit) * 2;
+ GLfloat *vertices = w->vertices + (stride - 2);
+
+ stride *= sizeof (GLfloat);
+
+ glVertexPointer (2, GL_FLOAT, stride, vertices);
+
+ while (texUnit--)
+ {
+ if (texUnit != currentTexUnit)
+ {
+ w->screen->clientActiveTexture (GL_TEXTURE0_ARB + texUnit);
+ currentTexUnit = texUnit;
+ }
+ vertices -= 2;
+ glTexCoordPointer (2, GL_FLOAT, stride, vertices);
}
- if (n)
+ glDrawArrays (GL_QUADS, 0, w->vCount);
+}
+
+Bool
+paintWindow (CompWindow *w,
+ const WindowPaintAttrib *attrib,
+ Region region,
+ unsigned int mask)
+{
+ GLushort opacity;
+
+ if (mask & PAINT_WINDOW_SOLID_MASK)
+ {
+ if (w->alpha)
+ return FALSE;
+
+ opacity = MULTIPLY_USHORT (w->opacity, attrib->opacity);
+ if (opacity != OPAQUE)
+ return FALSE;
+ }
+ else if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
+ {
+ opacity = MULTIPLY_USHORT (w->opacity, attrib->opacity);
+ if (!w->alpha && opacity == OPAQUE)
+ return FALSE;
+ }
+ else
{
- glTexCoordPointer (2, GL_FLOAT, sizeof (GLfloat) * 4, data);
- glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 4, data + 2);
+ opacity = MULTIPLY_USHORT (w->opacity, attrib->opacity);
+ if (w->alpha || opacity != OPAQUE)
+ mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
+ else
+ mask |= PAINT_WINDOW_SOLID_MASK;
+ }
+
+ if (!w->pixmap)
+ bindWindow (w);
+
+ if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
+ region = &infiniteRegion;
+ w->vCount = 0;
+ (*w->screen->addWindowGeometry) (w, &w->matrix, 1, w->region, region);
+ if (w->vCount)
+ {
if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
{
glEnable (GL_BLEND);
@@ -416,22 +474,25 @@ paintWindow (CompWindow *w,
glPushMatrix ();
- if (mask & PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK)
+ if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
{
glTranslatef (w->attrib.x + attrib->xTranslate,
w->attrib.y + attrib->yTranslate, 0.0f);
glScalef (attrib->xScale, attrib->yScale, 0.0f);
+ glTranslatef (-w->attrib.x, -w->attrib.y, 0.0f);
enableTexture (w->screen, &w->texture, COMP_TEXTURE_FILTER_GOOD);
}
+ else if (mask & PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK)
+ {
+ enableTexture (w->screen, &w->texture, COMP_TEXTURE_FILTER_GOOD);
+ }
else
{
- glTranslatef (w->attrib.x, w->attrib.y, 0.0f);
-
enableTexture (w->screen, &w->texture, COMP_TEXTURE_FILTER_FAST);
}
- glDrawArrays (GL_QUADS, 0, n * 4);
+ (*w->screen->drawWindowGeometry) (w);
disableTexture (&w->texture);
@@ -448,8 +509,6 @@ paintWindow (CompWindow *w,
}
}
- free (data);
-
return TRUE;
}
@@ -491,26 +550,26 @@ paintBackground (CompScreen *s,
n = nBox;
while (n--)
{
- *d++ = bg->dx * pBox->x1;
- *d++ = bg->dy * (s->backgroundHeight - pBox->y2);
+ *d++ = COMP_TEX_COORD_X (&bg->matrix, pBox->x1, pBox->y2);
+ *d++ = COMP_TEX_COORD_Y (&bg->matrix, pBox->x1, pBox->y2);
*d++ = pBox->x1;
*d++ = pBox->y2;
- *d++ = bg->dx * pBox->x2;
- *d++ = bg->dy * (s->backgroundHeight - pBox->y2);
+ *d++ = COMP_TEX_COORD_X (&bg->matrix, pBox->x2, pBox->y2);
+ *d++ = COMP_TEX_COORD_Y (&bg->matrix, pBox->x2, pBox->y2);
*d++ = pBox->x2;
*d++ = pBox->y2;
- *d++ = bg->dx * pBox->x2;
- *d++ = bg->dy * (s->backgroundHeight - pBox->y1);
+ *d++ = COMP_TEX_COORD_X (&bg->matrix, pBox->x2, pBox->y1);
+ *d++ = COMP_TEX_COORD_Y (&bg->matrix, pBox->x2, pBox->y1);
*d++ = pBox->x2;
*d++ = pBox->y1;
- *d++ = bg->dx * pBox->x1;
- *d++ = bg->dy * (s->backgroundHeight - pBox->y1);
+ *d++ = COMP_TEX_COORD_X (&bg->matrix, pBox->x1, pBox->y1);
+ *d++ = COMP_TEX_COORD_Y (&bg->matrix, pBox->x1, pBox->y1);
*d++ = pBox->x1;
*d++ = pBox->y1;
diff --git a/src/screen.c b/src/screen.c
index 3664961..8a8235d 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -346,9 +346,6 @@ updateScreenBackground (CompScreen *screen,
glTexParameteri (texture->target, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindTexture (texture->target, 0);
}
-
- screen->backgroundWidth = width;
- screen->backgroundHeight = height;
}
Bool
@@ -530,7 +527,11 @@ addScreen (CompDisplay *display,
s->paintTransformedScreen = paintTransformedScreen;
s->paintBackground = paintBackground;
s->paintWindow = paintWindow;
+ s->addWindowGeometry = addWindowGeometry;
+ s->drawWindowGeometry = drawWindowGeometry;
s->invisibleWindowMove = invisibleWindowMove;
+ s->damageWindowRect = damageWindowRect;
+ s->damageWindowRegion = damageWindowRegion;
s->getProcAddress = 0;
@@ -714,12 +715,14 @@ addScreen (CompDisplay *display,
return FALSE;
}
+ s->textureRectangle = 0;
glExtensions = (const char *) glGetString (GL_EXTENSIONS);
if (strstr (glExtensions, "GL_NV_texture_rectangle") ||
strstr (glExtensions, "GL_EXT_texture_rectangle") ||
strstr (glExtensions, "GL_ARB_texture_rectangle"))
s->textureRectangle = 1;
+ s->textureNonPowerOfTwo = 0;
if (strstr (glExtensions, "GL_ARB_texture_non_power_of_two"))
s->textureNonPowerOfTwo = 1;
@@ -730,6 +733,22 @@ addScreen (CompDisplay *display,
return FALSE;
}
+ s->textureEnvCombine = 0;
+ if (strstr (glExtensions, "GL_ARB_texture_env_combine"))
+ s->textureEnvCombine = 1;
+
+ s->maxTextureUnits = 1;
+ if (strstr (glExtensions, "GL_ARB_multitexture"))
+ {
+ s->activeTexture = (GLActiveTextureProc)
+ getProcAddress (s, "glActiveTexture");
+ s->clientActiveTexture = (GLClientActiveTextureProc)
+ getProcAddress (s, "glClientActiveTexture");
+
+ if (s->activeTexture && s->clientActiveTexture)
+ glGetIntegerv (GL_MAX_TEXTURE_UNITS_ARB, &s->maxTextureUnits);
+ }
+
initTexture (s, &s->backgroundTexture);
s->desktopWindowCount = 0;
@@ -747,9 +766,18 @@ addScreen (CompDisplay *display,
glEnable (GL_CULL_FACE);
glDisable (GL_BLEND);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glColor4usv (defaultColor);
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
- glColor4usv (defaultColor);
+
+ for (i = 1; i < s->maxTextureUnits; i++)
+ {
+ s->clientActiveTexture (GL_TEXTURE0_ARB + i);
+ glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+ }
+
+ if (s->maxTextureUnits > 1)
+ s->clientActiveTexture (GL_TEXTURE0_ARB);
s->activeWindow = getActiveWindow (display, s->root);
@@ -806,11 +834,18 @@ CompWindow *
findWindowAtScreen (CompScreen *s,
Window id)
{
- CompWindow *w;
+ if (lastFoundWindow && lastFoundWindow->id == id)
+ {
+ return lastFoundWindow;
+ }
+ else
+ {
+ CompWindow *w;
- for (w = s->windows; w; w = w->next)
- if (w->id == id)
- return w;
+ for (w = s->windows; w; w = w->next)
+ if (w->id == id)
+ return (lastFoundWindow = w);
+ }
return 0;
}
@@ -819,11 +854,18 @@ CompWindow *
findClientWindowAtScreen (CompScreen *s,
Window id)
{
- CompWindow *w;
+ if (lastFoundWindow && lastFoundWindow->client == id)
+ {
+ return lastFoundWindow;
+ }
+ else
+ {
+ CompWindow *w;
- for (w = s->windows; w; w = w->next)
- if (w->client == id)
- return w;
+ for (w = s->windows; w; w = w->next)
+ if (w->client == id)
+ return (lastFoundWindow = w);
+ }
return 0;
}
diff --git a/src/texture.c b/src/texture.c
index 6ef4e74..3b7d384 100644
--- a/src/texture.c
+++ b/src/texture.c
@@ -29,16 +29,21 @@
#include <comp.h>
+static CompMatrix _identity_matrix = {
+ 1, 0,
+ 0, 1,
+ 0, 0
+};
+
void
initTexture (CompScreen *screen,
CompTexture *texture)
{
texture->name = 0;
texture->target = GL_TEXTURE_2D;
- texture->dx = 0.0f;
- texture->dy = 0.0f;
texture->pixmap = None;
texture->filter = COMP_TEXTURE_FILTER_FAST;
+ texture->matrix = _identity_matrix;
}
void
@@ -90,13 +95,16 @@ readImageToTexture (CompScreen *screen,
(POWER_OF_TWO (width) && POWER_OF_TWO (height)))
{
texture->target = GL_TEXTURE_2D;
- texture->dx = 1.0f / width;
- texture->dy = 1.0f / height;
+ texture->matrix.xx = 1.0f / width;
+ texture->matrix.yy = -1.0f / height;
+ texture->matrix.y0 = 1.0f;
}
else
{
texture->target = GL_TEXTURE_RECTANGLE_NV;
- texture->dx = texture->dy = 1.0f;
+ texture->matrix.xx = 1.0f;
+ texture->matrix.yy = -1.0f;
+ texture->matrix.y0 = height;
}
if (!texture->name)
@@ -119,8 +127,8 @@ readImageToTexture (CompScreen *screen,
glTexParameteri (texture->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri (texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri (texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri (texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri (texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP);
glBindTexture (texture->target, 0);
@@ -177,12 +185,15 @@ bindPixmapToTexture (CompScreen *screen,
switch (target) {
case GLX_TEXTURE_2D_EXT:
texture->target = GL_TEXTURE_2D;
- texture->dx = 1.0f / width;
- texture->dy = 1.0f / height;
+ texture->matrix.xx = 1.0f / width;
+ texture->matrix.yy = -1.0f / height;
+ texture->matrix.y0 = 1.0f;
break;
case GLX_TEXTURE_RECTANGLE_EXT:
texture->target = GL_TEXTURE_RECTANGLE_ARB;
- texture->dx = texture->dy = 1.0f;
+ texture->matrix.xx = 1.0f;
+ texture->matrix.yy = -1.0f;
+ texture->matrix.y0 = height;
break;
default:
fprintf (stderr, "%s: pixmap 0x%x can't be bound to texture\n",
diff --git a/src/window.c b/src/window.c
index 8c9a126..ae6d6bb 100644
--- a/src/window.c
+++ b/src/window.c
@@ -220,6 +220,14 @@ getWindowOpacity (CompDisplay *display,
return MAXSHORT;
}
+static void
+setWindowMatrix (CompWindow *w)
+{
+ w->matrix = w->texture.matrix;
+ w->matrix.x0 -= (w->attrib.x * w->matrix.xx);
+ w->matrix.y0 -= (w->attrib.y * w->matrix.yy);
+}
+
void
bindWindow (CompWindow *w)
{
@@ -257,6 +265,8 @@ bindWindow (CompWindow *w)
"texture\n", programName, (int) w->id);
}
}
+
+ setWindowMatrix (w);
}
void
@@ -290,14 +300,47 @@ freeWindow (CompWindow *w)
if (w->privates)
free (w->privates);
+ if (w->vertices)
+ free (w->vertices);
+
+ if (w->indices)
+ free (w->indices);
+
+ if (lastFoundWindow == w)
+ lastFoundWindow = 0;
+
+ if (lastDamagedWindow == w)
+ lastDamagedWindow = 0;
+
free (w);
}
+Bool
+damageWindowRegion (CompWindow *w,
+ Region region)
+{
+ return FALSE;
+}
+
+Bool
+damageWindowRect (CompWindow *w,
+ Bool initial,
+ BoxPtr rect)
+{
+ return FALSE;
+}
+
void
addWindowDamage (CompWindow *w)
{
- if (w->attrib.map_state == IsViewable)
- damageScreenRegion (w->screen, w->region);
+ if (w->screen->allDamaged)
+ return;
+
+ if (w->attrib.map_state == IsViewable && w->damaged)
+ {
+ if (!(*w->screen->damageWindowRegion) (w, w->region))
+ damageScreenRegion (w->screen, w->region);
+ }
}
void
@@ -367,6 +410,13 @@ addWindow (CompScreen *screen,
w->texture.name = 0;
w->pixmap = None;
w->destroyed = FALSE;
+ w->damaged = FALSE;
+
+ w->vertices = 0;
+ w->vertexSize = 0;
+ w->indices = 0;
+ w->indexSize = 0;
+ w->vCount = 0;
if (screen->windowPrivateLen)
{
@@ -437,14 +487,12 @@ addWindow (CompScreen *screen,
bindWindow (w);
}
- w->invisible = WINDOW_INVISIBLE (w);
+ w->invisible = TRUE;
if (w->type == w->screen->display->winDesktopAtom)
w->screen->desktopWindowCount++;
windowInitPlugins (w);
-
- addWindowDamage (w);
}
void
@@ -484,9 +532,8 @@ mapWindow (CompWindow *w)
w->screen->desktopWindowCount++;
w->attrib.map_state = IsViewable;
- w->invisible = WINDOW_INVISIBLE (w);
-
- addWindowDamage (w);
+ w->invisible = TRUE;
+ w->damaged = FALSE;
}
void
@@ -501,7 +548,7 @@ unmapWindow (CompWindow *w)
addWindowDamage (w);
w->attrib.map_state = IsUnmapped;
- w->invisible = WINDOW_INVISIBLE (w);
+ w->invisible = TRUE;
releaseWindow (w);
}
@@ -560,6 +607,8 @@ configureWindow (CompWindow *w,
w->attrib.x = ce->x;
w->attrib.y = ce->y;
+ setWindowMatrix (w);
+
damage = TRUE;
}
else
@@ -602,4 +651,6 @@ invisibleWindowMove (CompWindow *w,
w->attrib.y += dy;
XOffsetRegion (w->region, dx, dy);
+
+ setWindowMatrix (w);
}