~compiz-team/compiz/0.9.12

« back to all changes in this revision

Viewing changes to plugins/opengl/src/paint.cpp

  • Committer: Dennis kasprzyk
  • Author(s): Dennis Kasprzyk
  • Date: 2009-03-15 05:09:18 UTC
  • Revision ID: git-v1:163f6b6f3c3b7764987cbdf8e03cc355edeaa499
New generalized build system.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2005 Novell, Inc.
 
3
 *
 
4
 * Permission to use, copy, modify, distribute, and sell this software
 
5
 * and its documentation for any purpose is hereby granted without
 
6
 * fee, provided that the above copyright notice appear in all copies
 
7
 * and that both that copyright notice and this permission notice
 
8
 * appear in supporting documentation, and that the name of
 
9
 * Novell, Inc. not be used in advertising or publicity pertaining to
 
10
 * distribution of the software without specific, written prior permission.
 
11
 * Novell, Inc. makes no representations about the suitability of this
 
12
 * software for any purpose. It is provided "as is" without express or
 
13
 * implied warranty.
 
14
 *
 
15
 * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
16
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 
17
 * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
18
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 
19
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 
20
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 
21
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
22
 *
 
23
 * Author: David Reveman <davidr@novell.com>
 
24
 */
 
25
 
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
#include <math.h>
 
29
 
 
30
#include <boost/foreach.hpp>
 
31
#define foreach BOOST_FOREACH
 
32
 
 
33
#include <core/core.h>
 
34
#include <opengl/opengl.h>
 
35
 
 
36
#include "privates.h"
 
37
 
 
38
 
 
39
GLScreenPaintAttrib defaultScreenPaintAttrib = {
 
40
    0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA
 
41
};
 
42
 
 
43
GLWindowPaintAttrib defaultWindowPaintAttrib = {
 
44
    OPAQUE, BRIGHT, COLOR, 1.0f, 1.0f, 0.0f, 0.0f
 
45
};
 
46
 
 
47
void
 
48
GLScreen::glApplyTransform (const GLScreenPaintAttrib &sAttrib,
 
49
                            CompOutput                *output,
 
50
                            GLMatrix                  *transform)
 
51
{
 
52
    WRAPABLE_HND_FUNC(2, glApplyTransform, sAttrib, output, transform)
 
53
 
 
54
    transform->translate (sAttrib.xTranslate,
 
55
                          sAttrib.yTranslate,
 
56
                          sAttrib.zTranslate + sAttrib.zCamera);
 
57
    transform->rotate (sAttrib.xRotate, 0.0f, 1.0f, 0.0f);
 
58
    transform->rotate (sAttrib.vRotate,
 
59
                       cosf (sAttrib.xRotate * DEG2RAD),
 
60
                       0.0f,
 
61
                       sinf (sAttrib.xRotate * DEG2RAD));
 
62
    transform->rotate (sAttrib.yRotate, 0.0f, 1.0f, 0.0f);
 
63
}
 
64
 
 
65
void
 
66
PrivateGLScreen::paintBackground (const CompRegion &region,
 
67
                                  bool             transformed)
 
68
{
 
69
    BoxPtr    pBox = const_cast <Region> (region.handle ())->rects;
 
70
    int       n, nBox = const_cast <Region> (region.handle ())->numRects;
 
71
    GLfloat   *d, *data;
 
72
 
 
73
    if (!nBox)
 
74
        return;
 
75
 
 
76
    if (screen->desktopWindowCount ())
 
77
    {
 
78
        if (!backgroundTextures.empty ())
 
79
        {
 
80
            backgroundTextures.clear ();
 
81
        }
 
82
 
 
83
        backgroundLoaded = false;
 
84
 
 
85
        return;
 
86
    }
 
87
    else
 
88
    {
 
89
        if (!backgroundLoaded)
 
90
            updateScreenBackground ();
 
91
 
 
92
        backgroundLoaded = true;
 
93
    }
 
94
 
 
95
    data = new GLfloat [nBox * 16];
 
96
    if (!data)
 
97
        return;
 
98
 
 
99
    d = data;
 
100
    n = nBox;
 
101
 
 
102
    if (backgroundTextures.empty ())
 
103
    {
 
104
        while (n--)
 
105
        {
 
106
            *d++ = pBox->x1;
 
107
            *d++ = pBox->y2;
 
108
 
 
109
            *d++ = pBox->x2;
 
110
            *d++ = pBox->y2;
 
111
 
 
112
            *d++ = pBox->x2;
 
113
            *d++ = pBox->y1;
 
114
 
 
115
            *d++ = pBox->x1;
 
116
            *d++ = pBox->y1;
 
117
 
 
118
            pBox++;
 
119
        }
 
120
 
 
121
        glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 2, data + 2);
 
122
        
 
123
        glColor4us (0, 0, 0, 0);
 
124
        glDrawArrays (GL_QUADS, 0, nBox * 4);
 
125
        glColor4usv (defaultColor);
 
126
    }
 
127
    else
 
128
    {
 
129
        for (unsigned int i = 0; i < backgroundTextures.size (); i++)
 
130
        {
 
131
            GLTexture *bg = backgroundTextures[i];
 
132
            CompRegion r = region & *bg;
 
133
 
 
134
            pBox = const_cast <Region> (r.handle ())->rects;
 
135
            nBox = const_cast <Region> (r.handle ())->numRects;
 
136
            d = data;
 
137
            n = nBox;
 
138
 
 
139
            while (n--)
 
140
            {
 
141
                *d++ = COMP_TEX_COORD_X (bg->matrix (), pBox->x1);
 
142
                *d++ = COMP_TEX_COORD_Y (bg->matrix (), pBox->y2);
 
143
 
 
144
                *d++ = pBox->x1;
 
145
                *d++ = pBox->y2;
 
146
 
 
147
                *d++ = COMP_TEX_COORD_X (bg->matrix (), pBox->x2);
 
148
                *d++ = COMP_TEX_COORD_Y (bg->matrix (), pBox->y2);
 
149
 
 
150
                *d++ = pBox->x2;
 
151
                *d++ = pBox->y2;
 
152
 
 
153
                *d++ = COMP_TEX_COORD_X (bg->matrix (), pBox->x2);
 
154
                *d++ = COMP_TEX_COORD_Y (bg->matrix (), pBox->y1);
 
155
 
 
156
                *d++ = pBox->x2;
 
157
                *d++ = pBox->y1;
 
158
 
 
159
                *d++ = COMP_TEX_COORD_X (bg->matrix (), pBox->x1);
 
160
                *d++ = COMP_TEX_COORD_Y (bg->matrix (), pBox->y1);
 
161
 
 
162
                *d++ = pBox->x1;
 
163
                *d++ = pBox->y1;
 
164
 
 
165
                pBox++;
 
166
            }
 
167
 
 
168
            glTexCoordPointer (2, GL_FLOAT, sizeof (GLfloat) * 4, data);
 
169
            glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 4, data + 2);
 
170
 
 
171
            if (bg->name ())
 
172
            {
 
173
                if (transformed)
 
174
                    bg->enable (GLTexture::Good);
 
175
                else
 
176
                    bg->enable (GLTexture::Fast);
 
177
 
 
178
                glDrawArrays (GL_QUADS, 0, nBox * 4);
 
179
 
 
180
                bg->disable ();
 
181
            }
 
182
        }
 
183
    }
 
184
 
 
185
    delete data;
 
186
}
 
187
 
 
188
 
 
189
/* This function currently always performs occlusion detection to
 
190
   minimize paint regions. OpenGL precision requirements are no good
 
191
   enough to guarantee that the results from using occlusion detection
 
192
   is the same as without. It's likely not possible to see any
 
193
   difference with most hardware but occlusion detection in the
 
194
   transformed screen case should be made optional for those who do
 
195
   see a difference. */
 
196
void
 
197
PrivateGLScreen::paintOutputRegion (const GLMatrix   &transform,
 
198
                                    const CompRegion &region,
 
199
                                    CompOutput       *output,
 
200
                                    unsigned int     mask)
 
201
{
 
202
    CompRegion    tmpRegion (region);
 
203
    CompWindow    *w;
 
204
    GLWindow      *gw;
 
205
    int           count, windowMask, odMask;
 
206
    CompWindow    *fullscreenWindow = NULL;
 
207
    bool          status, unredirectFS;
 
208
    bool          withOffset = false;
 
209
    GLMatrix      vTransform;
 
210
    CompPoint     offXY;
 
211
 
 
212
    CompWindowList                   pl;
 
213
    CompWindowList::reverse_iterator rit;
 
214
 
 
215
    unredirectFS = CompositeScreen::get (screen)->
 
216
        getOption("unredirect_fullscreen_windows")->value ().b ();
 
217
 
 
218
 
 
219
 
 
220
    if (mask & PAINT_SCREEN_TRANSFORMED_MASK)
 
221
    {
 
222
        windowMask     = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
 
223
        count          = 1;
 
224
    }
 
225
    else
 
226
    {
 
227
        windowMask     = 0;
 
228
        count          = 0;
 
229
    }
 
230
 
 
231
    pl = cScreen->getWindowPaintList ();
 
232
 
 
233
    if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
 
234
    {
 
235
        /* detect occlusions */
 
236
        for (rit = pl.rbegin (); rit != pl.rend(); rit++)
 
237
        {
 
238
            w = (*rit);
 
239
            gw = GLWindow::get (w);
 
240
 
 
241
            if (w->destroyed ())
 
242
                continue;
 
243
 
 
244
            if (!w->shaded ())
 
245
            {
 
246
                if (!w->isViewable () ||
 
247
                    !CompositeWindow::get (w)->damaged ())
 
248
                    continue;
 
249
            }
 
250
 
 
251
            /* copy region */
 
252
            gw->priv->clip = tmpRegion;
 
253
 
 
254
            odMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK;
 
255
                
 
256
            if ((cScreen->windowPaintOffset ().x () != 0 ||
 
257
                 cScreen->windowPaintOffset ().x () != 0) &&
 
258
                !w->onAllViewports ())
 
259
            {
 
260
                withOffset = true;
 
261
 
 
262
                offXY = w->getMovementForOffset (cScreen->windowPaintOffset ());
 
263
 
 
264
                vTransform = transform;
 
265
                vTransform.translate (offXY.x (), offXY.y (), 0);
 
266
 
 
267
                gw->priv->clip.translate (-offXY.x (), -offXY. y());
 
268
 
 
269
                odMask |= PAINT_WINDOW_WITH_OFFSET_MASK;
 
270
                status = gw->glPaint (gw->paintAttrib (), vTransform,
 
271
                                      tmpRegion, odMask);
 
272
            }
 
273
            else
 
274
            {
 
275
                withOffset = false;
 
276
                status = gw->glPaint (gw->paintAttrib (), transform, tmpRegion,
 
277
                                      odMask);
 
278
            }
 
279
 
 
280
            if (status)
 
281
            {
 
282
                if (withOffset)
 
283
                {
 
284
                    tmpRegion -= w->region ().translated (offXY);
 
285
                }
 
286
                else
 
287
                    tmpRegion -= w->region ();
 
288
 
 
289
                /* unredirect top most fullscreen windows. */
 
290
                if (count == 0 && unredirectFS)
 
291
                {
 
292
                    if (w->region () == screen->region () &&
 
293
                        tmpRegion.isEmpty ())
 
294
                    {
 
295
                        fullscreenWindow = w;
 
296
                    }
 
297
                    else
 
298
                    {
 
299
                        foreach (CompOutput &o, screen->outputDevs ())
 
300
                            if (w->region () == CompRegion (o))
 
301
                                fullscreenWindow = w;
 
302
                    }
 
303
                }
 
304
            }
 
305
 
 
306
            count++;
 
307
        }
 
308
    }
 
309
 
 
310
    if (fullscreenWindow)
 
311
        CompositeWindow::get (fullscreenWindow)->unredirect ();
 
312
 
 
313
    if (!(mask & PAINT_SCREEN_NO_BACKGROUND_MASK))
 
314
        paintBackground (tmpRegion, (mask & PAINT_SCREEN_TRANSFORMED_MASK));
 
315
 
 
316
    /* paint all windows from bottom to top */
 
317
    foreach (w, pl)
 
318
    {
 
319
        if (w->destroyed ())
 
320
            continue;
 
321
 
 
322
        if (w == fullscreenWindow)
 
323
            continue;
 
324
 
 
325
        if (!w->shaded ())
 
326
        {
 
327
            if (!w->isViewable () ||
 
328
                !CompositeWindow::get (w)->damaged ())
 
329
                continue;
 
330
        }
 
331
 
 
332
        gw = GLWindow::get (w);
 
333
 
 
334
        const CompRegion &clip =
 
335
            (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) ?
 
336
            gw->clip () : region;
 
337
 
 
338
        if ((cScreen->windowPaintOffset ().x () != 0 ||
 
339
             cScreen->windowPaintOffset ().y () != 0) &&
 
340
            !w->onAllViewports ())
 
341
        {
 
342
            offXY = w->getMovementForOffset (cScreen->windowPaintOffset ());
 
343
 
 
344
            vTransform = transform;
 
345
            vTransform.translate (offXY.x (), offXY.y (), 0);
 
346
            gw->glPaint (gw->paintAttrib (), vTransform, clip,
 
347
                         windowMask | PAINT_WINDOW_WITH_OFFSET_MASK);
 
348
        }
 
349
        else
 
350
        {
 
351
            gw->glPaint (gw->paintAttrib (), transform, clip, windowMask);
 
352
        }
 
353
    }
 
354
}
 
355
 
 
356
void
 
357
GLScreen::glEnableOutputClipping (const GLMatrix   &transform,
 
358
                                  const CompRegion &region,
 
359
                                  CompOutput       *output)
 
360
{
 
361
    WRAPABLE_HND_FUNC(3, glEnableOutputClipping, transform, region, output)
 
362
 
 
363
    GLdouble h = screen->height ();
 
364
 
 
365
    GLdouble p1[2] = { region.handle ()->extents.x1,
 
366
                       h - region.handle ()->extents.y2 };
 
367
    GLdouble p2[2] = { region.handle ()->extents.x2,
 
368
                       h - region.handle ()->extents.y1 };
 
369
 
 
370
    GLdouble halfW = output->width () / 2.0;
 
371
    GLdouble halfH = output->height () / 2.0;
 
372
 
 
373
    GLdouble cx = output->x1 () + halfW;
 
374
    GLdouble cy = (h - output->y2 ()) + halfH;
 
375
 
 
376
    GLdouble top[4]    = { 0.0, halfH / (cy - p1[1]), 0.0, 0.5 };
 
377
    GLdouble bottom[4] = { 0.0, halfH / (cy - p2[1]), 0.0, 0.5 };
 
378
    GLdouble left[4]   = { halfW / (cx - p1[0]), 0.0, 0.0, 0.5 };
 
379
    GLdouble right[4]  = { halfW / (cx - p2[0]), 0.0, 0.0, 0.5 };
 
380
 
 
381
    glPushMatrix ();
 
382
    glLoadMatrixf (transform.getMatrix ());
 
383
 
 
384
    glClipPlane (GL_CLIP_PLANE0, top);
 
385
    glClipPlane (GL_CLIP_PLANE1, bottom);
 
386
    glClipPlane (GL_CLIP_PLANE2, left);
 
387
    glClipPlane (GL_CLIP_PLANE3, right);
 
388
 
 
389
    glEnable (GL_CLIP_PLANE0);
 
390
    glEnable (GL_CLIP_PLANE1);
 
391
    glEnable (GL_CLIP_PLANE2);
 
392
    glEnable (GL_CLIP_PLANE3);
 
393
 
 
394
    glPopMatrix ();
 
395
}
 
396
 
 
397
void
 
398
GLScreen::glDisableOutputClipping ()
 
399
{
 
400
    WRAPABLE_HND_FUNC(4, glDisableOutputClipping)
 
401
 
 
402
    glDisable (GL_CLIP_PLANE0);
 
403
    glDisable (GL_CLIP_PLANE1);
 
404
    glDisable (GL_CLIP_PLANE2);
 
405
    glDisable (GL_CLIP_PLANE3);
 
406
}
 
407
 
 
408
#define CLIP_PLANE_MASK (PAINT_SCREEN_TRANSFORMED_MASK | \
 
409
                         PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK)
 
410
 
 
411
void
 
412
GLScreen::glPaintTransformedOutput (const GLScreenPaintAttrib &sAttrib,
 
413
                                    const GLMatrix            &transform,
 
414
                                    const CompRegion          &region,
 
415
                                    CompOutput                *output,
 
416
                                    unsigned int              mask)
 
417
{
 
418
    WRAPABLE_HND_FUNC(1, glPaintTransformedOutput, sAttrib, transform,
 
419
                      region, output, mask)
 
420
 
 
421
    GLMatrix sTransform = transform;
 
422
 
 
423
    if (mask & PAINT_SCREEN_CLEAR_MASK)
 
424
        clearTargetOutput (GL_COLOR_BUFFER_BIT);
 
425
 
 
426
    setLighting (true);
 
427
 
 
428
    glApplyTransform (sAttrib, output, &sTransform);
 
429
 
 
430
    if ((mask & CLIP_PLANE_MASK) == CLIP_PLANE_MASK)
 
431
    {
 
432
        glEnableOutputClipping (sTransform, region, output);
 
433
 
 
434
        sTransform.toScreenSpace (output, -sAttrib.zTranslate);
 
435
 
 
436
        glPushMatrix ();
 
437
        glLoadMatrixf (sTransform.getMatrix ());
 
438
 
 
439
        priv->paintOutputRegion (sTransform, region, output, mask);
 
440
 
 
441
        glPopMatrix ();
 
442
 
 
443
        glDisableOutputClipping ();
 
444
    }
 
445
    else
 
446
    {
 
447
        sTransform.toScreenSpace (output, -sAttrib.zTranslate);
 
448
 
 
449
        glPushMatrix ();
 
450
        glLoadMatrixf (sTransform.getMatrix ());
 
451
 
 
452
        priv->paintOutputRegion (sTransform, region, output, mask);
 
453
 
 
454
        glPopMatrix ();
 
455
    }
 
456
}
 
457
 
 
458
bool
 
459
GLScreen::glPaintOutput (const GLScreenPaintAttrib &sAttrib,
 
460
                         const GLMatrix            &transform,
 
461
                         const CompRegion          &region,
 
462
                         CompOutput                *output,
 
463
                         unsigned int              mask)
 
464
{
 
465
    WRAPABLE_HND_FUNC_RETURN(0, bool, glPaintOutput, sAttrib, transform,
 
466
                             region, output, mask)
 
467
 
 
468
    GLMatrix sTransform = transform;
 
469
 
 
470
    if (mask & PAINT_SCREEN_REGION_MASK)
 
471
    {
 
472
        if (mask & PAINT_SCREEN_TRANSFORMED_MASK)
 
473
        {
 
474
            if (mask & PAINT_SCREEN_FULL_MASK)
 
475
            {
 
476
                glPaintTransformedOutput (sAttrib, sTransform,
 
477
                                          CompRegion (*output), output, mask);
 
478
 
 
479
                return true;
 
480
            }
 
481
 
 
482
            return false;
 
483
        }
 
484
 
 
485
        /* fall through and redraw region */
 
486
    }
 
487
    else if (mask & PAINT_SCREEN_FULL_MASK)
 
488
    {
 
489
        glPaintTransformedOutput (sAttrib, sTransform, CompRegion (*output),
 
490
                                  output, mask);
 
491
 
 
492
        return true;
 
493
    }
 
494
    else
 
495
        return false;
 
496
 
 
497
    setLighting (false);
 
498
 
 
499
    sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
 
500
 
 
501
    glPushMatrix ();
 
502
    glLoadMatrixf (sTransform.getMatrix ());
 
503
 
 
504
    priv->paintOutputRegion (sTransform, region, output, mask);
 
505
 
 
506
    glPopMatrix ();
 
507
 
 
508
    return true;
 
509
}
 
510
 
 
511
#define ADD_RECT(data, m, n, x1, y1, x2, y2)       \
 
512
    for (it = 0; it < n; it++)                     \
 
513
    {                                              \
 
514
        *(data)++ = COMP_TEX_COORD_X (m[it], x1);  \
 
515
        *(data)++ = COMP_TEX_COORD_Y (m[it], y1);  \
 
516
    }                                              \
 
517
    *(data)++ = (x1);                              \
 
518
    *(data)++ = (y1);                              \
 
519
    *(data)++ = 0.0;                               \
 
520
    for (it = 0; it < n; it++)                     \
 
521
    {                                              \
 
522
        *(data)++ = COMP_TEX_COORD_X (m[it], x1);  \
 
523
        *(data)++ = COMP_TEX_COORD_Y (m[it], y2);  \
 
524
    }                                              \
 
525
    *(data)++ = (x1);                              \
 
526
    *(data)++ = (y2);                              \
 
527
    *(data)++ = 0.0;                               \
 
528
    for (it = 0; it < n; it++)                     \
 
529
    {                                              \
 
530
        *(data)++ = COMP_TEX_COORD_X (m[it], x2);  \
 
531
        *(data)++ = COMP_TEX_COORD_Y (m[it], y2);  \
 
532
    }                                              \
 
533
    *(data)++ = (x2);                              \
 
534
    *(data)++ = (y2);                              \
 
535
    *(data)++ = 0.0;                               \
 
536
    for (it = 0; it < n; it++)                     \
 
537
    {                                              \
 
538
        *(data)++ = COMP_TEX_COORD_X (m[it], x2);  \
 
539
        *(data)++ = COMP_TEX_COORD_Y (m[it], y1);  \
 
540
    }                                              \
 
541
    *(data)++ = (x2);                              \
 
542
    *(data)++ = (y1);                              \
 
543
    *(data)++ = 0.0
 
544
 
 
545
#define ADD_QUAD(data, m, n, x1, y1, x2, y2)            \
 
546
    for (it = 0; it < n; it++)                          \
 
547
    {                                                   \
 
548
        *(data)++ = COMP_TEX_COORD_XY (m[it], x1, y1);  \
 
549
        *(data)++ = COMP_TEX_COORD_YX (m[it], x1, y1);  \
 
550
    }                                                   \
 
551
    *(data)++ = (x1);                                   \
 
552
    *(data)++ = (y1);                                   \
 
553
    *(data)++ = 0.0;                                    \
 
554
    for (it = 0; it < n; it++)                          \
 
555
    {                                                   \
 
556
        *(data)++ = COMP_TEX_COORD_XY (m[it], x1, y2);  \
 
557
        *(data)++ = COMP_TEX_COORD_YX (m[it], x1, y2);  \
 
558
    }                                                   \
 
559
    *(data)++ = (x1);                                   \
 
560
    *(data)++ = (y2);                                   \
 
561
    *(data)++ = 0.0;                                    \
 
562
    for (it = 0; it < n; it++)                          \
 
563
    {                                                   \
 
564
        *(data)++ = COMP_TEX_COORD_XY (m[it], x2, y2);  \
 
565
        *(data)++ = COMP_TEX_COORD_YX (m[it], x2, y2);  \
 
566
    }                                                   \
 
567
    *(data)++ = (x2);                                   \
 
568
    *(data)++ = (y2);                                   \
 
569
    *(data)++ = 0.0;                                    \
 
570
    for (it = 0; it < n; it++)                          \
 
571
    {                                                   \
 
572
        *(data)++ = COMP_TEX_COORD_XY (m[it], x2, y1);  \
 
573
        *(data)++ = COMP_TEX_COORD_YX (m[it], x2, y1);  \
 
574
    }                                                   \
 
575
    *(data)++ = (x2);                                   \
 
576
    *(data)++ = (y1);                                   \
 
577
    *(data)++ = 0.0;
 
578
 
 
579
void
 
580
GLWindow::glDrawGeometry ()
 
581
{
 
582
    WRAPABLE_HND_FUNC(4, glDrawGeometry)
 
583
 
 
584
    int     texUnit = priv->geometry.texUnits;
 
585
    int     currentTexUnit = 0;
 
586
    int     stride = priv->geometry.vertexStride;
 
587
    GLfloat *vertices = priv->geometry.vertices + (stride - 3);
 
588
 
 
589
    stride *= sizeof (GLfloat);
 
590
 
 
591
    glVertexPointer (3, GL_FLOAT, stride, vertices);
 
592
 
 
593
    while (texUnit--)
 
594
    {
 
595
        if (texUnit != currentTexUnit)
 
596
        {
 
597
            (*GL::clientActiveTexture) (GL_TEXTURE0_ARB + texUnit);
 
598
            glEnableClientState (GL_TEXTURE_COORD_ARRAY);
 
599
            currentTexUnit = texUnit;
 
600
        }
 
601
        vertices -= priv->geometry.texCoordSize;
 
602
        glTexCoordPointer (priv->geometry.texCoordSize,
 
603
                           GL_FLOAT, stride, vertices);
 
604
    }
 
605
 
 
606
    glDrawArrays (GL_QUADS, 0, priv->geometry.vCount);
 
607
 
 
608
    /* disable all texture coordinate arrays except 0 */
 
609
    texUnit = priv->geometry.texUnits;
 
610
    if (texUnit > 1)
 
611
    {
 
612
        while (--texUnit)
 
613
        {
 
614
            (*GL::clientActiveTexture) (GL_TEXTURE0_ARB + texUnit);
 
615
            glDisableClientState (GL_TEXTURE_COORD_ARRAY);
 
616
        }
 
617
 
 
618
        (*GL::clientActiveTexture) (GL_TEXTURE0_ARB);
 
619
    }
 
620
}
 
621
 
 
622
void
 
623
GLWindow::glAddGeometry (const GLTexture::MatrixList &matrix,
 
624
                         const CompRegion            &region,
 
625
                         const CompRegion            &clip)
 
626
{
 
627
    WRAPABLE_HND_FUNC(2, glAddGeometry, matrix, region, clip)
 
628
 
 
629
    BoxRec full;
 
630
    int    nMatrix = matrix.size ();
 
631
 
 
632
    priv->geometry.texUnits = nMatrix;
 
633
 
 
634
    full = clip.handle ()->extents;
 
635
    if (region.handle ()->extents.x1 > full.x1)
 
636
        full.x1 = region.handle ()->extents.x1;
 
637
    if (region.handle ()->extents.y1 > full.y1)
 
638
        full.y1 = region.handle ()->extents.y1;
 
639
    if (region.handle ()->extents.x2 < full.x2)
 
640
        full.x2 = region.handle ()->extents.x2;
 
641
    if (region.handle ()->extents.y2 < full.y2)
 
642
        full.y2 = region.handle ()->extents.y2;
 
643
 
 
644
    if (full.x1 < full.x2 && full.y1 < full.y2)
 
645
    {
 
646
        BoxPtr  pBox;
 
647
        int     nBox;
 
648
        BoxPtr  pClip;
 
649
        int     nClip;
 
650
        BoxRec  cbox;
 
651
        int     vSize;
 
652
        int     n, it, x1, y1, x2, y2;
 
653
        GLfloat *d;
 
654
        bool    rect = true;
 
655
 
 
656
        for (it = 0; it < nMatrix; it++)
 
657
        {
 
658
            if (matrix[it].xy != 0.0f || matrix[it].yx != 0.0f)
 
659
            {
 
660
                rect = false;
 
661
                break;
 
662
            }
 
663
        }
 
664
 
 
665
        pBox = const_cast <Region> (region.handle ())->rects;
 
666
        nBox = const_cast <Region> (region.handle ())->numRects;
 
667
 
 
668
        vSize = 3 + nMatrix * 2;
 
669
 
 
670
        n = priv->geometry.vCount / 4;
 
671
 
 
672
        if ((n + nBox) * vSize * 4 > priv->geometry.vertexSize)
 
673
        {
 
674
            if (!priv->geometry.moreVertices ((n + nBox) * vSize * 4))
 
675
                return;
 
676
        }
 
677
 
 
678
        d = priv->geometry.vertices + (priv->geometry.vCount * vSize);
 
679
 
 
680
        while (nBox--)
 
681
        {
 
682
            x1 = pBox->x1;
 
683
            y1 = pBox->y1;
 
684
            x2 = pBox->x2;
 
685
            y2 = pBox->y2;
 
686
 
 
687
            pBox++;
 
688
 
 
689
            if (x1 < full.x1)
 
690
                x1 = full.x1;
 
691
            if (y1 < full.y1)
 
692
                y1 = full.y1;
 
693
            if (x2 > full.x2)
 
694
                x2 = full.x2;
 
695
            if (y2 > full.y2)
 
696
                y2 = full.y2;
 
697
 
 
698
            if (x1 < x2 && y1 < y2)
 
699
            {
 
700
                nClip = const_cast <Region> (clip.handle ())->numRects;
 
701
 
 
702
                if (nClip == 1)
 
703
                {
 
704
                    if (rect)
 
705
                    {
 
706
                        ADD_RECT (d, matrix, nMatrix, x1, y1, x2, y2);
 
707
                    }
 
708
                    else
 
709
                    {
 
710
                        ADD_QUAD (d, matrix, nMatrix, x1, y1, x2, y2);
 
711
                    }
 
712
 
 
713
                    n++;
 
714
                }
 
715
                else
 
716
                {
 
717
                    pClip = const_cast <Region> (clip.handle ())->rects;
 
718
 
 
719
                    if (((n + nClip) * vSize * 4) > priv->geometry.vertexSize)
 
720
                    {
 
721
                        if (!priv->geometry.moreVertices ((n + nClip) *
 
722
                                                          vSize * 4))
 
723
                            return;
 
724
 
 
725
                        d = priv->geometry.vertices + (n * vSize * 4);
 
726
                    }
 
727
 
 
728
                    while (nClip--)
 
729
                    {
 
730
                        cbox = *pClip;
 
731
 
 
732
                        pClip++;
 
733
 
 
734
                        if (cbox.x1 < x1)
 
735
                            cbox.x1 = x1;
 
736
                        if (cbox.y1 < y1)
 
737
                            cbox.y1 = y1;
 
738
                        if (cbox.x2 > x2)
 
739
                            cbox.x2 = x2;
 
740
                        if (cbox.y2 > y2)
 
741
                            cbox.y2 = y2;
 
742
 
 
743
                        if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)
 
744
                        {
 
745
                            if (rect)
 
746
                            {
 
747
                                ADD_RECT (d, matrix, nMatrix,
 
748
                                          cbox.x1, cbox.y1, cbox.x2, cbox.y2);
 
749
                            }
 
750
                            else
 
751
                            {
 
752
                                ADD_QUAD (d, matrix, nMatrix,
 
753
                                          cbox.x1, cbox.y1, cbox.x2, cbox.y2);
 
754
                            }
 
755
 
 
756
                            n++;
 
757
                        }
 
758
                    }
 
759
                }
 
760
            }
 
761
        }
 
762
 
 
763
        priv->geometry.vCount       = n * 4;
 
764
        priv->geometry.vertexStride = vSize;
 
765
        priv->geometry.texCoordSize = 2;
 
766
    }
 
767
}
 
768
 
 
769
static bool
 
770
enableFragmentProgramAndDrawGeometry (GLScreen           *gs,
 
771
                                      GLWindow           *w,
 
772
                                      GLTexture          *texture,
 
773
                                      GLFragment::Attrib &attrib,
 
774
                                      GLTexture::Filter  filter,
 
775
                                      unsigned int       mask)
 
776
{
 
777
    GLFragment::Attrib fa (attrib);
 
778
    bool               blending;
 
779
 
 
780
    if (GL::canDoSaturated && attrib.getSaturation () != COLOR)
 
781
    {
 
782
        int param, function;
 
783
 
 
784
        param    = fa.allocParameters (1);
 
785
        function =
 
786
            GLFragment::getSaturateFragmentFunction (texture, param);
 
787
 
 
788
        fa.addFunction (function);
 
789
 
 
790
        (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, param,
 
791
                                      RED_SATURATION_WEIGHT,
 
792
                                      GREEN_SATURATION_WEIGHT,
 
793
                                      BLUE_SATURATION_WEIGHT,
 
794
                                      attrib.getSaturation () / 65535.0f);
 
795
    }
 
796
 
 
797
    if (!fa.enable (&blending))
 
798
        return false;
 
799
 
 
800
    texture->enable (filter);
 
801
 
 
802
    if (mask & PAINT_WINDOW_BLEND_MASK)
 
803
    {
 
804
        if (blending)
 
805
            glEnable (GL_BLEND);
 
806
 
 
807
        if (attrib.getOpacity () != OPAQUE || attrib.getBrightness () != BRIGHT)
 
808
        {
 
809
            GLushort color;
 
810
 
 
811
            color = (attrib.getOpacity () * attrib.getBrightness ()) >> 16;
 
812
 
 
813
            gs->setTexEnvMode (GL_MODULATE);
 
814
            glColor4us (color, color, color, attrib.getOpacity ());
 
815
 
 
816
            w->glDrawGeometry ();
 
817
 
 
818
            glColor4usv (defaultColor);
 
819
            gs->setTexEnvMode (GL_REPLACE);
 
820
        }
 
821
        else
 
822
        {
 
823
            w->glDrawGeometry ();
 
824
        }
 
825
 
 
826
        if (blending)
 
827
            glDisable (GL_BLEND);
 
828
    }
 
829
    else if (attrib.getBrightness () != BRIGHT)
 
830
    {
 
831
        gs->setTexEnvMode (GL_MODULATE);
 
832
        glColor4us (attrib.getBrightness (), attrib.getBrightness (),
 
833
                    attrib.getBrightness (), BRIGHT);
 
834
 
 
835
        w->glDrawGeometry ();
 
836
 
 
837
        glColor4usv (defaultColor);
 
838
        gs->setTexEnvMode (GL_REPLACE);
 
839
    }
 
840
    else
 
841
    {
 
842
        w->glDrawGeometry ();
 
843
    }
 
844
 
 
845
    texture->disable ();
 
846
 
 
847
    fa.disable ();
 
848
 
 
849
    return true;
 
850
}
 
851
 
 
852
static void
 
853
enableFragmentOperationsAndDrawGeometry (GLScreen           *gs,
 
854
                                         GLWindow           *w,
 
855
                                         GLTexture          *texture,
 
856
                                         GLFragment::Attrib &attrib,
 
857
                                         GLTexture::Filter  filter,
 
858
                                         unsigned int       mask)
 
859
{
 
860
    if (GL::canDoSaturated && attrib.getSaturation () != COLOR)
 
861
    {
 
862
        GLfloat constant[4];
 
863
 
 
864
        if (mask & PAINT_WINDOW_BLEND_MASK)
 
865
            glEnable (GL_BLEND);
 
866
 
 
867
        texture->enable (filter);
 
868
 
 
869
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
 
870
 
 
871
        glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
 
872
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
 
873
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
 
874
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
 
875
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
 
876
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
 
877
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
 
878
 
 
879
        glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
 
880
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
 
881
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
 
882
 
 
883
        glColor4f (1.0f, 1.0f, 1.0f, 0.5f);
 
884
 
 
885
        GL::activeTexture (GL_TEXTURE1_ARB);
 
886
 
 
887
        texture->enable (filter);
 
888
 
 
889
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
 
890
 
 
891
        glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
 
892
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
 
893
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
 
894
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
 
895
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
 
896
 
 
897
        if (GL::canDoSlightlySaturated && attrib.getSaturation () > 0)
 
898
        {
 
899
            glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
 
900
            glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
 
901
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
 
902
 
 
903
            constant[0] = 0.5f + 0.5f * RED_SATURATION_WEIGHT;
 
904
            constant[1] = 0.5f + 0.5f * GREEN_SATURATION_WEIGHT;
 
905
            constant[2] = 0.5f + 0.5f * BLUE_SATURATION_WEIGHT;
 
906
            constant[3] = 1.0;
 
907
 
 
908
            glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
 
909
 
 
910
            GL::activeTexture (GL_TEXTURE2_ARB);
 
911
 
 
912
            texture->enable (filter);
 
913
 
 
914
            glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
 
915
 
 
916
            glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
 
917
            glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
 
918
            glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
 
919
            glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT);
 
920
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
 
921
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
 
922
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
 
923
 
 
924
            glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
 
925
            glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
 
926
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
 
927
 
 
928
            constant[3] = attrib.getSaturation () / 65535.0f;
 
929
 
 
930
            glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
 
931
 
 
932
            if (attrib.getOpacity () < OPAQUE ||
 
933
                attrib.getBrightness () != BRIGHT)
 
934
            {
 
935
                GL::activeTexture (GL_TEXTURE3_ARB);
 
936
 
 
937
                texture->enable (filter);
 
938
 
 
939
                constant[3] = attrib.getOpacity () / 65535.0f;
 
940
                constant[0] = constant[1] = constant[2] = constant[3] *
 
941
                    attrib.getBrightness () / 65535.0f;
 
942
 
 
943
                glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
 
944
 
 
945
                glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
 
946
 
 
947
                glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
 
948
                glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
 
949
                glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
 
950
                glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
 
951
                glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
 
952
 
 
953
                glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
 
954
                glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
 
955
                glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT);
 
956
                glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
 
957
                glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
 
958
 
 
959
                w->glDrawGeometry ();
 
960
 
 
961
                texture->disable ();
 
962
 
 
963
                glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
964
 
 
965
                GL::activeTexture (GL_TEXTURE2_ARB);
 
966
            }
 
967
            else
 
968
            {
 
969
                w->glDrawGeometry ();
 
970
            }
 
971
 
 
972
            texture->disable ();
 
973
 
 
974
            glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
975
 
 
976
            GL::activeTexture (GL_TEXTURE1_ARB);
 
977
        }
 
978
        else
 
979
        {
 
980
            glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
 
981
            glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
 
982
            glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT);
 
983
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
 
984
            glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
 
985
 
 
986
            constant[3] = attrib.getOpacity () / 65535.0f;
 
987
            constant[0] = constant[1] = constant[2] = constant[3] *
 
988
                          attrib.getBrightness ()/ 65535.0f;
 
989
 
 
990
            constant[0] = 0.5f + 0.5f * RED_SATURATION_WEIGHT   * constant[0];
 
991
            constant[1] = 0.5f + 0.5f * GREEN_SATURATION_WEIGHT * constant[1];
 
992
            constant[2] = 0.5f + 0.5f * BLUE_SATURATION_WEIGHT  * constant[2];
 
993
 
 
994
            glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
 
995
 
 
996
            w->glDrawGeometry ();
 
997
        }
 
998
 
 
999
        texture->disable ();
 
1000
 
 
1001
        glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
1002
 
 
1003
        GL::activeTexture (GL_TEXTURE0_ARB);
 
1004
 
 
1005
        texture->disable ();
 
1006
 
 
1007
        glColor4usv (defaultColor);
 
1008
        gs->setTexEnvMode (GL_REPLACE);
 
1009
 
 
1010
        if (mask & PAINT_WINDOW_BLEND_MASK)
 
1011
            glDisable (GL_BLEND);
 
1012
    }
 
1013
    else
 
1014
    {
 
1015
        texture->enable (filter);
 
1016
 
 
1017
        if (mask & PAINT_WINDOW_BLEND_MASK)
 
1018
        {
 
1019
            glEnable (GL_BLEND);
 
1020
            if (attrib.getOpacity ()!= OPAQUE ||
 
1021
                attrib.getBrightness () != BRIGHT)
 
1022
            {
 
1023
                GLushort color;
 
1024
 
 
1025
                color = (attrib.getOpacity () * attrib.getBrightness ()) >> 16;
 
1026
 
 
1027
                gs->setTexEnvMode (GL_MODULATE);
 
1028
                glColor4us (color, color, color, attrib.getOpacity ());
 
1029
 
 
1030
                w->glDrawGeometry ();
 
1031
 
 
1032
                glColor4usv (defaultColor);
 
1033
                gs->setTexEnvMode (GL_REPLACE);
 
1034
            }
 
1035
            else
 
1036
            {
 
1037
                w->glDrawGeometry ();
 
1038
            }
 
1039
 
 
1040
            glDisable (GL_BLEND);
 
1041
        }
 
1042
        else if (attrib.getBrightness () != BRIGHT)
 
1043
        {
 
1044
            gs->setTexEnvMode (GL_MODULATE);
 
1045
            glColor4us (attrib.getBrightness (), attrib.getBrightness (),
 
1046
                        attrib.getBrightness (), BRIGHT);
 
1047
 
 
1048
            w->glDrawGeometry ();
 
1049
 
 
1050
            glColor4usv (defaultColor);
 
1051
            gs->setTexEnvMode (GL_REPLACE);
 
1052
        }
 
1053
        else
 
1054
        {
 
1055
            w->glDrawGeometry ();
 
1056
        }
 
1057
 
 
1058
        texture->disable ();
 
1059
    }
 
1060
}
 
1061
 
 
1062
void
 
1063
GLWindow::glDrawTexture (GLTexture          *texture,
 
1064
                         GLFragment::Attrib &attrib,
 
1065
                         unsigned int       mask)
 
1066
{
 
1067
    WRAPABLE_HND_FUNC(3, glDrawTexture, texture, attrib, mask)
 
1068
 
 
1069
    GLTexture::Filter filter;
 
1070
 
 
1071
    if (mask & (PAINT_WINDOW_TRANSFORMED_MASK |
 
1072
                PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK))
 
1073
        filter = priv->gScreen->filter (SCREEN_TRANS_FILTER);
 
1074
    else
 
1075
        filter = priv->gScreen->filter (NOTHING_TRANS_FILTER);
 
1076
 
 
1077
    if ((!attrib.hasFunctions () && (!priv->gScreen->lighting () ||
 
1078
         attrib.getSaturation () == COLOR || attrib.getSaturation () == 0)) ||
 
1079
        !enableFragmentProgramAndDrawGeometry (priv->gScreen, this, texture,
 
1080
                                               attrib, filter, mask))
 
1081
    {
 
1082
        enableFragmentOperationsAndDrawGeometry (priv->gScreen, this, texture,
 
1083
                                                 attrib, filter, mask);
 
1084
    }
 
1085
}
 
1086
 
 
1087
bool
 
1088
GLWindow::glDraw (const GLMatrix     &transform,
 
1089
                  GLFragment::Attrib &fragment,
 
1090
                  const CompRegion   &region,
 
1091
                  unsigned int       mask)
 
1092
{
 
1093
    WRAPABLE_HND_FUNC_RETURN(1, bool, glDraw, transform, fragment, region, mask)
 
1094
 
 
1095
    const CompRegion reg = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ?
 
1096
                           infiniteRegion : region;
 
1097
 
 
1098
    if (reg.isEmpty ())
 
1099
        return true;
 
1100
 
 
1101
    if (!priv->window->isViewable ())
 
1102
        return true;
 
1103
 
 
1104
    if (priv->textures.empty () && !bind ())
 
1105
        return false;
 
1106
 
 
1107
    if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
 
1108
        mask |= PAINT_WINDOW_BLEND_MASK;
 
1109
 
 
1110
    GLTexture::MatrixList ml (1);
 
1111
    
 
1112
    if (priv->textures.size () == 1)
 
1113
    {
 
1114
        ml[0] = priv->matrices[0];
 
1115
        priv->geometry.reset ();
 
1116
        glAddGeometry (ml, priv->window->region (), reg);
 
1117
        if (priv->geometry.vCount)
 
1118
            glDrawTexture (priv->textures[0], fragment, mask);
 
1119
    }
 
1120
    else
 
1121
    {
 
1122
        if (priv->updateReg)
 
1123
            priv->updateWindowRegions ();
 
1124
        for (unsigned int i = 0; i < priv->textures.size (); i++)
 
1125
        {
 
1126
            ml[0] = priv->matrices[i];
 
1127
            priv->geometry.reset ();
 
1128
            glAddGeometry (ml, priv->regions[i], reg);
 
1129
            if (priv->geometry.vCount)
 
1130
                glDrawTexture (priv->textures[i], fragment, mask);
 
1131
        }
 
1132
    }
 
1133
 
 
1134
    return true;
 
1135
}
 
1136
 
 
1137
bool
 
1138
GLWindow::glPaint (const GLWindowPaintAttrib &attrib,
 
1139
                   const GLMatrix            &transform,
 
1140
                   const CompRegion          &region,
 
1141
                   unsigned int              mask)
 
1142
{
 
1143
    WRAPABLE_HND_FUNC_RETURN(0, bool, glPaint, attrib, transform, region, mask)
 
1144
 
 
1145
    GLFragment::Attrib fragment (attrib);
 
1146
    bool               status;
 
1147
 
 
1148
    priv->lastPaint = attrib;
 
1149
 
 
1150
    if (priv->window->alpha () || attrib.opacity != OPAQUE)
 
1151
        mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
 
1152
 
 
1153
    priv->lastMask = mask;
 
1154
 
 
1155
    if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
 
1156
    {
 
1157
        if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
 
1158
            return false;
 
1159
 
 
1160
        if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
 
1161
            return false;
 
1162
 
 
1163
        if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
 
1164
            return false;
 
1165
 
 
1166
        if (priv->window->shaded ())
 
1167
            return false;
 
1168
 
 
1169
        return true;
 
1170
    }
 
1171
 
 
1172
    if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
 
1173
        return true;
 
1174
 
 
1175
    if (mask & PAINT_WINDOW_TRANSFORMED_MASK ||
 
1176
        mask & PAINT_WINDOW_WITH_OFFSET_MASK)
 
1177
    {
 
1178
        glPushMatrix ();
 
1179
        glLoadMatrixf (transform.getMatrix ());
 
1180
    }
 
1181
 
 
1182
    status = glDraw (transform, fragment, region, mask);
 
1183
 
 
1184
    if (mask & PAINT_WINDOW_TRANSFORMED_MASK ||
 
1185
        mask & PAINT_WINDOW_WITH_OFFSET_MASK)
 
1186
        glPopMatrix ();
 
1187
 
 
1188
    return status;
 
1189
}