~townsend/compiz/fix-lp1244754-0.9.10

« back to all changes in this revision

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

  • Committer: smspillaz
  • Date: 2012-05-16 17:40:13 UTC
  • mfrom: (0.1.96 trunk)
  • Revision ID: sam.spilsbury@canonical.com-20120516174013-0rsxq2ka7zm2ypp0
MergeĀ lp:compiz-scaleaddon-plugin

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright Ā© 2011 Linaro Ltd.
3
2
 * Copyright Ā© 2008 Dennis Kasprzyk
4
3
 * Copyright Ā© 2007 Novell, Inc.
5
4
 *
24
23
 *
25
24
 * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>
26
25
 *          David Reveman <davidr@novell.com>
27
 
 *          Travis Watkins <travis.watkins@linaro.org>
28
26
 */
29
27
 
30
 
#ifndef _GNU_SOURCE
31
 
#define _GNU_SOURCE
32
 
#endif
33
 
#include <errno.h>
34
 
 
35
 
#include <boost/bind.hpp>
36
 
#include <boost/make_shared.hpp>
37
 
 
38
28
#include "privates.h"
39
 
#include "blacklist/blacklist.h"
40
29
 
41
30
#include <dlfcn.h>
42
31
#include <math.h>
43
32
 
44
 
template class WrapableInterface<GLScreen, GLScreenInterface>;
45
 
 
46
 
#ifndef USE_GLES
47
 
/*
48
 
 * Historically most versions of fglrx have contained a nasty hack that checks
49
 
 * if argv[0] == "compiz", and downgrades OpenGL features including dropping
50
 
 * GLSL support (hides GL_ARB_shading_language_100). (LP #1026920)
51
 
 * This hack in fglrx is misguided and I'm told AMD have or will remove
52
 
 * it soon. In the mean time, modify argv[0] so it's not triggered...
53
 
 */
54
 
class DetectionWorkaround
55
 
{
56
 
    public:
57
 
        DetectionWorkaround ()
58
 
        {
59
 
            program_invocation_short_name[0] = 'C';
60
 
        }
61
 
        ~DetectionWorkaround ()
62
 
        {
63
 
            program_invocation_short_name[0] = 'c';
64
 
        }
65
 
};
66
 
#endif
67
 
 
68
 
 
69
 
using namespace compiz::opengl;
70
 
 
71
33
namespace GL {
72
 
    #ifdef USE_GLES
73
 
    EGLCreateImageKHRProc  createImage;
74
 
    EGLDestroyImageKHRProc destroyImage;
75
 
 
76
 
    GLEGLImageTargetTexture2DOESProc eglImageTargetTexture;
77
 
 
78
 
    EGLPostSubBufferNVProc postSubBuffer = NULL;
79
 
    #else
80
 
 
81
 
    typedef int (*GLXSwapIntervalProc) (int interval);
82
 
 
83
34
    GLXBindTexImageProc      bindTexImage = NULL;
84
35
    GLXReleaseTexImageProc   releaseTexImage = NULL;
85
36
    GLXQueryDrawableProc     queryDrawable = NULL;
91
42
    GLXGetFBConfigAttribProc getFBConfigAttrib = NULL;
92
43
    GLXCreatePixmapProc      createPixmap = NULL;
93
44
    GLXDestroyPixmapProc     destroyPixmap = NULL;
 
45
 
 
46
    GLActiveTextureProc       activeTexture = NULL;
 
47
    GLClientActiveTextureProc clientActiveTexture = NULL;
 
48
    GLMultiTexCoord2fProc     multiTexCoord2f = NULL;
 
49
 
94
50
    GLGenProgramsProc        genPrograms = NULL;
95
51
    GLDeleteProgramsProc     deletePrograms = NULL;
96
52
    GLBindProgramProc        bindProgram = NULL;
97
53
    GLProgramStringProc      programString = NULL;
98
54
    GLProgramParameter4fProc programEnvParameter4f = NULL;
99
55
    GLProgramParameter4fProc programLocalParameter4f = NULL;
100
 
    #endif
101
 
 
102
 
    GLActiveTextureProc       activeTexture = NULL;
103
 
    GLClientActiveTextureProc clientActiveTexture = NULL;
104
 
    GLMultiTexCoord2fProc     multiTexCoord2f = NULL;
 
56
    GLGetProgramivProc       getProgramiv = NULL;
105
57
 
106
58
    GLGenFramebuffersProc        genFramebuffers = NULL;
107
59
    GLDeleteFramebuffersProc     deleteFramebuffers = NULL;
110
62
    GLFramebufferTexture2DProc   framebufferTexture2D = NULL;
111
63
    GLGenerateMipmapProc         generateMipmap = NULL;
112
64
 
113
 
    GLBindBufferProc    bindBuffer = NULL;
114
 
    GLDeleteBuffersProc deleteBuffers = NULL;
115
 
    GLGenBuffersProc    genBuffers = NULL;
116
 
    GLBufferDataProc    bufferData = NULL;
117
 
    GLBufferSubDataProc bufferSubData = NULL;
118
 
 
119
 
    GLGetShaderivProc        getShaderiv = NULL;
120
 
    GLGetShaderInfoLogProc   getShaderInfoLog = NULL;
121
 
    GLGetProgramivProc       getProgramiv = NULL;
122
 
    GLGetProgramInfoLogProc  getProgramInfoLog = NULL;
123
 
    GLCreateShaderProc       createShader = NULL;
124
 
    GLShaderSourceProc       shaderSource = NULL;
125
 
    GLCompileShaderProc      compileShader = NULL;
126
 
    GLCreateProgramProc      createProgram = NULL;
127
 
    GLAttachShaderProc       attachShader = NULL;
128
 
    GLLinkProgramProc        linkProgram = NULL;
129
 
    GLValidateProgramProc    validateProgram = NULL;
130
 
    GLDeleteShaderProc       deleteShader = NULL;
131
 
    GLDeleteProgramProc      deleteProgram = NULL;
132
 
    GLUseProgramProc         useProgram = NULL;
133
 
    GLGetUniformLocationProc getUniformLocation = NULL;
134
 
    GLUniform1fProc          uniform1f = NULL;
135
 
    GLUniform1iProc          uniform1i = NULL;
136
 
    GLUniform2fProc          uniform2f = NULL;
137
 
    GLUniform2iProc          uniform2i = NULL;
138
 
    GLUniform3fProc          uniform3f = NULL;
139
 
    GLUniform3iProc          uniform3i = NULL;
140
 
    GLUniform4fProc          uniform4f = NULL;
141
 
    GLUniform4iProc          uniform4i = NULL;
142
 
    GLUniformMatrix4fvProc   uniformMatrix4fv = NULL;
143
 
    GLGetAttribLocationProc  getAttribLocation = NULL;
144
 
 
145
 
#ifndef USE_GLES
146
 
 
147
 
    GLCreateShaderObjectARBProc createShaderObjectARB = NULL;
148
 
    GLCreateProgramObjectARBProc createProgramObjectARB = NULL;
149
 
    GLCompileShaderARBProc compileShaderARB = NULL;
150
 
    GLShaderSourceARBProc shaderSourceARB = NULL;
151
 
    GLValidateProgramARBProc validateProgramARB = NULL;
152
 
    GLDeleteObjectARBProc deleteObjectARB = NULL;
153
 
    GLAttachObjectARBProc attachObjectARB = NULL;
154
 
    GLLinkProgramARBProc linkProgramARB = NULL;
155
 
    GLUseProgramObjectARBProc useProgramObjectARB = NULL;
156
 
    GLGetUniformLocationARBProc getUniformLocationARB = NULL;
157
 
    GLGetAttribLocationARBProc getAttribLocationARB = NULL;
158
 
    GLGetObjectParameterivProc getObjectParameteriv = NULL;
159
 
    GLGetInfoLogProc         getInfoLog = NULL;
160
 
 
161
 
#endif
162
 
 
163
 
    GLEnableVertexAttribArrayProc  enableVertexAttribArray = NULL;
164
 
    GLDisableVertexAttribArrayProc disableVertexAttribArray = NULL;
165
 
    GLVertexAttribPointerProc      vertexAttribPointer = NULL;
166
 
 
167
 
    GLGenRenderbuffersProc genRenderbuffers = NULL;
168
 
    GLDeleteRenderbuffersProc deleteRenderbuffers = NULL;
169
 
    GLFramebufferRenderbufferProc framebufferRenderbuffer = NULL;
170
 
    GLBindRenderbufferProc bindRenderbuffer = NULL;
171
 
    GLRenderbufferStorageProc renderbufferStorage = NULL;
172
 
 
173
65
    bool  textureFromPixmap = true;
174
66
    bool  textureRectangle = false;
175
67
    bool  textureNonPowerOfTwo = false;
176
 
    bool  textureNonPowerOfTwoMipmap = false;
177
68
    bool  textureEnvCombine = false;
178
69
    bool  textureEnvCrossbar = false;
179
70
    bool  textureBorderClamp = false;
180
71
    bool  textureCompression = false;
181
72
    GLint maxTextureSize = 0;
182
 
    bool  fboSupported = false;
183
 
    bool  fboEnabled = false;
184
 
    bool  fboStencilSupported = false;
185
 
    bool  vboSupported = false;
186
 
    bool  vboEnabled = false;
187
 
    bool  shaders = false;
 
73
    bool  fbo = false;
 
74
    bool  fragmentProgram = false;
188
75
    GLint maxTextureUnits = 1;
189
76
 
190
77
    bool canDoSaturated = false;
191
78
    bool canDoSlightlySaturated = false;
192
79
 
193
80
    unsigned int vsyncCount = 0;
194
 
 
195
 
    bool stencilBuffer = false;
196
 
#ifndef USE_GLES
197
 
 
198
 
    GLuint createShaderARBWrapper (GLenum type)
199
 
    {
200
 
        return static_cast <GLuint> ((GL::createShaderObjectARB) (type));
201
 
    }
202
 
 
203
 
    GLuint createProgramARBWrapper (GLenum type)
204
 
    {
205
 
        return static_cast <GLuint> ((GL::createProgramObjectARB) ());
206
 
    }
207
 
 
208
 
    void shaderSourceARBWrapper (GLuint shader, GLsizei count, const GLchar **string, const GLint *length)
209
 
    {
210
 
        (GL::shaderSourceARB) (static_cast <GLhandleARB> (shader), count, string, length);
211
 
    }
212
 
 
213
 
    void compileShaderARBWrapper (GLuint shader)
214
 
    {
215
 
        (GL::compileShaderARB) (static_cast <GLhandleARB> (shader));
216
 
    }
217
 
 
218
 
    void validateProgramARBWrapper (GLuint program)
219
 
    {
220
 
        (GL::validateProgramARB) (static_cast <GLhandleARB> (program));
221
 
    }
222
 
 
223
 
    void deleteShaderARBWrapper (GLuint shader)
224
 
    {
225
 
        (GL::deleteObjectARB) (static_cast <GLhandleARB> (shader));
226
 
    }
227
 
 
228
 
    void deleteProgramARBWrapper (GLuint program)
229
 
    {
230
 
        (GL::deleteObjectARB) (static_cast <GLhandleARB> (program));
231
 
    }
232
 
 
233
 
    void attachShaderARBWrapper (GLuint program, GLuint shader)
234
 
    {
235
 
        (GL::attachObjectARB) (static_cast <GLhandleARB> (program), static_cast <GLhandleARB> (shader));
236
 
    }
237
 
 
238
 
    void linkProgramARBWrapper (GLuint program)
239
 
    {
240
 
        (GL::linkProgramARB) (static_cast <GLhandleARB> (program));
241
 
    }
242
 
 
243
 
    void useProgramARBWrapper (GLuint program)
244
 
    {
245
 
        (GL::useProgramObjectARB) (static_cast <GLhandleARB> (program));
246
 
    }
247
 
 
248
 
    int getUniformLocationARBWrapper (GLuint program, const GLchar *name)
249
 
    {
250
 
        return (GL::getUniformLocationARB) (static_cast <GLhandleARB> (program), name);
251
 
    }
252
 
 
253
 
    int getAttribLocationARBWrapper (GLuint program, const GLchar *name)
254
 
    {
255
 
        return (GL::getAttribLocationARB) (static_cast <GLhandleARB> (program), name);
256
 
    }
257
 
 
258
 
    void getProgramInfoLogARBWrapper (GLuint object, int maxLen, int *len, char *log)
259
 
    {
260
 
        (GL::getInfoLog) (static_cast <GLhandleARB> (object), maxLen, len, log);
261
 
    }
262
 
 
263
 
    void getShaderInfoLogARBWrapper (GLuint object, int maxLen, int *len, char *log)
264
 
    {
265
 
        (GL::getInfoLog) (static_cast <GLhandleARB> (object), maxLen, len, log);
266
 
    }
267
 
 
268
 
    void getShaderivARBWrapper (GLuint object, GLenum type, int *param)
269
 
    {
270
 
        (GL::getObjectParameteriv) (static_cast <GLhandleARB> (object), type, param);
271
 
    }
272
 
 
273
 
    void getProgramivARBWrapper (GLuint object, GLenum type, int *param)
274
 
    {
275
 
        (GL::getObjectParameteriv) (static_cast <GLhandleARB> (object), type, param);
276
 
    }
277
 
 
278
 
#endif
 
81
    unsigned int unthrottledFrames = 0;
279
82
}
280
83
 
281
84
CompOutput *targetOutput = NULL;
282
85
 
283
 
/**
284
 
 * Callback object to create GLPrograms automatically when using GLVertexBuffer.
285
 
 */
286
 
class GLScreenAutoProgram : public GLVertexBuffer::AutoProgram
287
 
{
288
 
public:
289
 
    GLScreenAutoProgram (GLScreen *gScreen) : gScreen(gScreen) {}
290
 
 
291
 
    GLProgram *getProgram (GLShaderParameters &params)
292
 
    {
293
 
        const GLShaderData *shaderData = gScreen->getShaderData (params);
294
 
        std::list<const GLShaderData *> tempShaders;
295
 
        tempShaders.push_back (shaderData);
296
 
        return gScreen->getProgram (tempShaders);
297
 
    }
298
 
 
299
 
    GLScreen *gScreen;
300
 
};
301
 
 
302
 
#ifndef USE_GLES
303
 
 
304
 
namespace compiz
305
 
{
306
 
namespace opengl
307
 
{
308
 
void swapIntervalGLX (Display *d, int interval)
309
 
{
310
 
    // Docs: http://www.opengl.org/registry/specs/SGI/swap_control.txt
311
 
    if (GL::swapInterval)
312
 
        GL::swapInterval (interval);
313
 
}
314
 
 
315
 
int waitVSyncGLX (int          wait,
316
 
                  int          remainder,
317
 
                  unsigned int *count)
318
 
{
319
 
    /*
320
 
     * While glXSwapBuffers/glXCopySubBufferMESA are meant to do a
321
 
     * flush before they blit, it is best to not let that happen.
322
 
     * Because that flush would occur after GL::waitVideoSync, causing
323
 
     * a delay and the final blit to be slightly out of sync resulting
324
 
     * in tearing. So we need to do a glFinish before we wait for
325
 
     * vsync, to absolutely minimize tearing.
326
 
     */
327
 
    glFinish ();
328
 
 
329
 
    // Docs: http://www.opengl.org/registry/specs/SGI/video_sync.txt
330
 
    if (GL::waitVideoSync)
331
 
        return GL::waitVideoSync (wait, remainder, count);
332
 
 
333
 
    return 0;
334
 
}
335
 
}
336
 
}
337
 
 
338
 
#else
339
 
 
340
 
namespace compiz
341
 
{
342
 
namespace opengl
343
 
{
344
 
void swapIntervalEGL (Display *display, int interval)
345
 
{
346
 
    eglSwapInterval (eglGetDisplay (display), interval);
347
 
}
348
 
 
349
 
int waitVSyncEGL (int wait,
350
 
                  int remainder,
351
 
                  unsigned int *count)
352
 
{
353
 
    /* not supported */
354
 
    return 0;
355
 
}
356
 
}
357
 
}
358
 
 
359
 
#endif
360
 
 
361
86
bool
362
87
GLScreen::glInitContext (XVisualInfo *visinfo)
363
88
{
364
 
#ifndef USE_GLES
365
 
    DetectionWorkaround workaround;
366
 
#endif
367
 
 
368
 
    #ifdef USE_GLES
369
 
    Display             *xdpy;
370
 
    Window               overlay;
371
 
    EGLDisplay           dpy;
372
 
    EGLConfig            config;
373
 
    EGLint               major, minor;
374
 
    const char          *eglExtensions, *glExtensions;
375
 
    XWindowAttributes    attr;
376
 
    EGLint               count, visualid;
377
 
    EGLConfig            configs[1024];
378
 
    CompOption::Vector   o (0);
379
 
 
380
 
    const EGLint config_attribs[] = {
381
 
        EGL_SURFACE_TYPE,         EGL_WINDOW_BIT,
382
 
        EGL_RED_SIZE,             1,
383
 
        EGL_GREEN_SIZE,           1,
384
 
        EGL_BLUE_SIZE,            1,
385
 
        EGL_ALPHA_SIZE,           0,
386
 
        EGL_RENDERABLE_TYPE,      EGL_OPENGL_ES2_BIT,
387
 
        EGL_CONFIG_CAVEAT,        EGL_NONE,
388
 
        EGL_STENCIL_SIZE,         1,
389
 
        EGL_NONE
390
 
    };
391
 
 
392
 
    const EGLint context_attribs[] = {
393
 
        EGL_CONTEXT_CLIENT_VERSION, 2,
394
 
        EGL_NONE
395
 
    };
396
 
 
397
 
    xdpy = screen->dpy ();
398
 
    dpy = eglGetDisplay ((EGLNativeDisplayType)xdpy);
399
 
    if (!eglInitialize (dpy, &major, &minor))
400
 
    {
401
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
402
 
        return false;
403
 
    }
404
 
 
405
 
    eglBindAPI (EGL_OPENGL_ES_API);
406
 
 
407
 
    if (!eglChooseConfig (dpy, config_attribs, configs, 1024, &count))
408
 
    {
409
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
410
 
        return false;
411
 
    }
412
 
 
413
 
    if (!XGetWindowAttributes (xdpy, screen->root (), &attr))
414
 
    {
415
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
416
 
        return false;
417
 
    }
418
 
 
419
 
    EGLint val;
420
 
    int msaaBuffers = MAXSHORT;
421
 
    int msaaSamples = MAXSHORT;
422
 
    visualid = XVisualIDFromVisual (attr.visual);
423
 
    config = configs[0];
424
 
 
425
 
    for (int i = 0; i < count; ++i)
426
 
    {
427
 
        eglGetConfigAttrib (dpy, configs[i], EGL_SAMPLE_BUFFERS, &val);
428
 
        if (val > msaaBuffers)
429
 
           continue;
430
 
 
431
 
        msaaBuffers = val;
432
 
 
433
 
        eglGetConfigAttrib (dpy, configs[i], EGL_SAMPLES, &val);
434
 
        if (val > msaaSamples)
435
 
            continue;
436
 
 
437
 
        msaaSamples = val;
438
 
 
439
 
        eglGetConfigAttrib (dpy, configs[i], EGL_NATIVE_VISUAL_ID, &val);
440
 
        if (val != visualid)
441
 
            continue;
442
 
 
443
 
        config = configs[i];
444
 
        break;
445
 
    }
446
 
 
447
 
    overlay = CompositeScreen::get (screen)->overlay ();
448
 
    priv->surface = eglCreateWindowSurface (dpy, config, overlay, 0);
449
 
    if (priv->surface == EGL_NO_SURFACE)
450
 
    {
451
 
        compLogMessage ("opengl", CompLogLevelFatal,
452
 
                        "eglCreateWindowSurface failed");
453
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
454
 
        return false;
455
 
    }
456
 
 
457
 
    // Do not preserve buffer contents on swap
458
 
    eglSurfaceAttrib (dpy, priv->surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
459
 
 
460
 
    priv->ctx = eglCreateContext (dpy, config, EGL_NO_CONTEXT, context_attribs);
461
 
    if (priv->ctx == EGL_NO_CONTEXT)
462
 
    {
463
 
        compLogMessage ("opengl", CompLogLevelFatal, "eglCreateContext failed");
464
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
465
 
        return false;
466
 
    }
467
 
 
468
 
    if (!eglMakeCurrent (dpy, priv->surface, priv->surface, priv->ctx))
469
 
    {
470
 
        compLogMessage ("opengl", CompLogLevelFatal,
471
 
                        "eglMakeCurrent failed");
472
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
473
 
        return false;
474
 
    }
475
 
 
476
 
    eglExtensions = (const char *) eglQueryString (dpy, EGL_EXTENSIONS);
477
 
    glExtensions = (const char *) glGetString (GL_EXTENSIONS);
478
 
 
479
 
    if (!glExtensions || !eglExtensions)
480
 
    {
481
 
        compLogMessage ("opengl", CompLogLevelFatal,
482
 
                        "No valid GL extensions string found.");
483
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
484
 
        return false;
485
 
    }
486
 
 
487
 
    GL::textureFromPixmap = true;
488
 
    GL::textureNonPowerOfTwo = true;
489
 
    GL::fboSupported = true;
490
 
    GL::fboEnabled = true;
491
 
    GL::vboSupported = true;
492
 
    GL::vboEnabled = true;
493
 
    GL::shaders = true;
494
 
    GL::stencilBuffer = true;
495
 
    GL::maxTextureUnits = 4;
496
 
    glGetIntegerv (GL_MAX_TEXTURE_SIZE, &GL::maxTextureSize);
497
 
 
498
 
    GL::createImage = (GL::EGLCreateImageKHRProc)
499
 
        eglGetProcAddress ("eglCreateImageKHR");
500
 
    GL::destroyImage = (GL::EGLDestroyImageKHRProc)
501
 
        eglGetProcAddress ("eglDestroyImageKHR");
502
 
    GL::eglImageTargetTexture = (GL::GLEGLImageTargetTexture2DOESProc)
503
 
        eglGetProcAddress ("glEGLImageTargetTexture2DOES");
504
 
 
505
 
    if (!strstr (eglExtensions, "EGL_KHR_image_pixmap") ||
506
 
        !strstr (glExtensions, "GL_OES_EGL_image") ||
507
 
        !GL::createImage || !GL::destroyImage || !GL::eglImageTargetTexture)
508
 
    {
509
 
        compLogMessage ("opengl", CompLogLevelFatal,
510
 
                        "GL_OES_EGL_image is missing");
511
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
512
 
        return false;
513
 
    }
514
 
 
515
 
// work around efika supporting GL_BGRA directly instead of via this extension
516
 
#ifndef GL_BGRA
517
 
    if (!strstr (glExtensions, "GL_EXT_texture_format_BGRA8888"))
518
 
    {
519
 
        compLogMessage ("opengl", CompLogLevelFatal,
520
 
                        "GL_EXT_texture_format_BGRA8888 is missing");
521
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
522
 
        return false;
523
 
    }
524
 
#endif
525
 
 
526
 
    if (strstr (glExtensions, "GL_OES_texture_npot"))
527
 
        GL::textureNonPowerOfTwoMipmap = true;
528
 
 
529
 
    if (strstr (eglExtensions, "EGL_NV_post_sub_buffer"))
530
 
        GL::postSubBuffer = (GL::EGLPostSubBufferNVProc)
531
 
            eglGetProcAddress ("eglPostSubBufferNV");
532
 
 
533
 
    GL::fboStencilSupported = GL::fboSupported &&
534
 
        strstr (glExtensions, "GL_OES_packed_depth_stencil");
535
 
 
536
 
    if (!GL::fboSupported &&
537
 
        !GL::postSubBuffer)
538
 
    {
539
 
        compLogMessage ("opengl", CompLogLevelFatal,
540
 
                        "GL_EXT_framebuffer_object or EGL_NV_post_sub_buffer are required");
541
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
542
 
        return false;
543
 
    }
544
 
 
545
 
    GL::activeTexture = glActiveTexture;
546
 
    GL::genFramebuffers = glGenFramebuffers;
547
 
    GL::deleteFramebuffers = glDeleteFramebuffers;
548
 
    GL::bindFramebuffer = glBindFramebuffer;
549
 
    GL::checkFramebufferStatus = glCheckFramebufferStatus;
550
 
    GL::framebufferTexture2D = glFramebufferTexture2D;
551
 
    GL::generateMipmap = glGenerateMipmap;
552
 
 
553
 
    GL::bindBuffer = glBindBuffer;
554
 
    GL::deleteBuffers = glDeleteBuffers;
555
 
    GL::genBuffers = glGenBuffers;
556
 
    GL::bufferData = glBufferData;
557
 
    GL::bufferSubData = glBufferSubData;
558
 
 
559
 
    GL::getShaderiv = glGetShaderiv;
560
 
    GL::getShaderInfoLog = glGetShaderInfoLog;
561
 
    GL::getProgramiv = glGetProgramiv;
562
 
    GL::getProgramInfoLog = glGetProgramInfoLog;
563
 
    GL::createShader = glCreateShader;
564
 
    GL::shaderSource = (GL::GLShaderSourceProc) glShaderSource;
565
 
    GL::compileShader = glCompileShader;
566
 
    GL::createProgram = glCreateProgram;
567
 
    GL::attachShader = glAttachShader;
568
 
    GL::linkProgram = glLinkProgram;
569
 
    GL::validateProgram = glValidateProgram;
570
 
    GL::deleteShader = glDeleteShader;
571
 
    GL::deleteProgram = glDeleteProgram;
572
 
    GL::useProgram = glUseProgram;
573
 
    GL::getUniformLocation = glGetUniformLocation;
574
 
    GL::uniform1f = glUniform1f;
575
 
    GL::uniform1i = glUniform1i;
576
 
    GL::uniform2f = glUniform2f;
577
 
    GL::uniform2i = glUniform2i;
578
 
    GL::uniform3f = glUniform3f;
579
 
    GL::uniform3i = glUniform3i;
580
 
    GL::uniform4f = glUniform4f;
581
 
    GL::uniform4i = glUniform4i;
582
 
    GL::uniformMatrix4fv = glUniformMatrix4fv;
583
 
    GL::getAttribLocation = glGetAttribLocation;
584
 
 
585
 
    GL::enableVertexAttribArray = glEnableVertexAttribArray;
586
 
    GL::disableVertexAttribArray = glDisableVertexAttribArray;
587
 
    GL::vertexAttribPointer = glVertexAttribPointer;
588
 
 
589
 
    GL::genRenderbuffers = glGenRenderbuffers;
590
 
    GL::deleteRenderbuffers = glDeleteRenderbuffers;
591
 
    GL::bindRenderbuffer = glBindRenderbuffer;
592
 
    GL::framebufferRenderbuffer = glFramebufferRenderbuffer;
593
 
    GL::renderbufferStorage = glRenderbufferStorage;
594
 
 
595
 
    glClearColor (0.0, 0.0, 0.0, 1.0);
596
 
    glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
597
 
    glEnable (GL_BLEND);
598
 
    glEnable (GL_CULL_FACE);
599
 
 
600
 
    priv->updateView ();
601
 
 
602
 
    priv->lighting = false;
603
 
 
604
 
    priv->filter[NOTHING_TRANS_FILTER] = GLTexture::Fast;
605
 
    priv->filter[SCREEN_TRANS_FILTER]  = GLTexture::Good;
606
 
    priv->filter[WINDOW_TRANS_FILTER]  = GLTexture::Good;
607
 
 
608
 
    if (GL::textureFromPixmap)
609
 
        registerBindPixmap (EglTexture::bindPixmapToTexture);
610
 
 
611
 
    priv->incorrectRefreshRate = false;
612
 
 
613
 
    #else
614
 
 
615
89
    Display              *dpy = screen->dpy ();
616
90
    const char           *glExtensions;
617
91
    GLfloat              globalAmbient[]  = { 0.1f, 0.1f,  0.1f, 0.1f };
618
92
    GLfloat              ambientLight[]   = { 0.0f, 0.0f,  0.0f, 0.0f };
619
93
    GLfloat              diffuseLight[]   = { 0.9f, 0.9f,  0.9f, 0.9f };
620
94
    GLfloat              light0Position[] = { -0.5f, 0.5f, -9.0f, 1.0f };
 
95
    const char           *glRenderer;
621
96
    CompOption::Vector o (0);
622
97
 
623
98
    priv->ctx = glXCreateContext (dpy, visinfo, NULL, True);
656
131
        return false;
657
132
    }
658
133
 
659
 
    const char *glVendor = (const char *) glGetString (GL_VENDOR);
660
 
    const char *glRenderer = (const char *) glGetString (GL_RENDERER);
661
 
    const char *glVersion = (const char *) glGetString (GL_VERSION);
662
 
 
663
 
    priv->glVendor = glVendor;
664
 
    priv->glRenderer = glRenderer;
665
 
    priv->glVersion = glVersion;
666
 
 
 
134
    glRenderer = (const char *) glGetString (GL_RENDERER);
667
135
    if (glRenderer != NULL &&
668
136
        (strcmp (glRenderer, "Software Rasterizer") == 0 ||
669
137
         strcmp (glRenderer, "Mesa X11") == 0))
675
143
        return false;
676
144
    }
677
145
 
678
 
    priv->commonFrontbuffer = true;
679
 
    priv->incorrectRefreshRate = false;
680
 
    if (glRenderer != NULL && strstr (glRenderer, "on llvmpipe"))
681
 
    {
682
 
        /*
683
 
         * Most drivers use the same frontbuffer infrastructure for
684
 
         * swapbuffers as well as subbuffer copying. However there are some
685
 
         * odd exceptions like LLVMpipe (and SGX-something?) that use separate
686
 
         * buffers, so we can't dynamically switch between buffer swapping and
687
 
         * copying in those cases.
688
 
         */
689
 
        priv->commonFrontbuffer = false;
690
 
    }
691
 
 
692
 
    if (glVendor != NULL && strstr (glVendor, "NVIDIA"))
693
 
    {
694
 
        /*
695
 
         * NVIDIA provides an incorrect refresh rate, we need to
696
 
         * force 60Hz */
697
 
        priv->incorrectRefreshRate = true;
698
 
    }
699
 
 
700
146
    if (strstr (glExtensions, "GL_ARB_texture_non_power_of_two"))
701
147
        GL::textureNonPowerOfTwo = true;
702
 
    GL::textureNonPowerOfTwoMipmap = GL::textureNonPowerOfTwo;
703
148
 
704
149
    glGetIntegerv (GL_MAX_TEXTURE_SIZE, &GL::maxTextureSize);
705
150
 
756
201
            glGetIntegerv (GL_MAX_TEXTURE_UNITS_ARB, &GL::maxTextureUnits);
757
202
    }
758
203
 
 
204
    if (strstr (glExtensions, "GL_ARB_fragment_program"))
 
205
    {
 
206
        GL::genPrograms = (GL::GLGenProgramsProc)
 
207
            getProcAddress ("glGenProgramsARB");
 
208
        GL::deletePrograms = (GL::GLDeleteProgramsProc)
 
209
            getProcAddress ("glDeleteProgramsARB");
 
210
        GL::bindProgram = (GL::GLBindProgramProc)
 
211
            getProcAddress ("glBindProgramARB");
 
212
        GL::programString = (GL::GLProgramStringProc)
 
213
            getProcAddress ("glProgramStringARB");
 
214
        GL::programEnvParameter4f = (GL::GLProgramParameter4fProc)
 
215
            getProcAddress ("glProgramEnvParameter4fARB");
 
216
        GL::programLocalParameter4f = (GL::GLProgramParameter4fProc)
 
217
            getProcAddress ("glProgramLocalParameter4fARB");
 
218
        GL::getProgramiv = (GL::GLGetProgramivProc)
 
219
            getProcAddress ("glGetProgramivARB");
 
220
 
 
221
        if (GL::genPrograms             &&
 
222
            GL::deletePrograms          &&
 
223
            GL::bindProgram             &&
 
224
            GL::programString           &&
 
225
            GL::programEnvParameter4f   &&
 
226
            GL::programLocalParameter4f &&
 
227
            GL::getProgramiv)
 
228
            GL::fragmentProgram = true;
 
229
    }
 
230
 
759
231
    if (strstr (glExtensions, "GL_EXT_framebuffer_object"))
760
232
    {
761
233
        GL::genFramebuffers = (GL::GLGenFramebuffersProc)
770
242
            getProcAddress ("glFramebufferTexture2DEXT");
771
243
        GL::generateMipmap = (GL::GLGenerateMipmapProc)
772
244
            getProcAddress ("glGenerateMipmapEXT");
773
 
        GL::genRenderbuffers = (GL::GLGenRenderbuffersProc)
774
 
            getProcAddress ("glGenRenderbuffersEXT");
775
 
        GL::deleteRenderbuffers = (GL::GLDeleteRenderbuffersProc)
776
 
            getProcAddress ("glDeleteRenderbuffersEXT");
777
 
        GL::bindRenderbuffer = (GL::GLBindRenderbufferProc)
778
 
            getProcAddress ("glBindRenderbufferEXT");
779
 
        GL::framebufferRenderbuffer = (GL::GLFramebufferRenderbufferProc)
780
 
            getProcAddress ("glFramebufferRenderbufferEXT");
781
 
        GL::renderbufferStorage = (GL::GLRenderbufferStorageProc)
782
 
            getProcAddress ("glRenderbufferStorageEXT");
783
245
 
784
246
        if (GL::genFramebuffers        &&
785
247
            GL::deleteFramebuffers     &&
786
248
            GL::bindFramebuffer        &&
787
249
            GL::checkFramebufferStatus &&
788
250
            GL::framebufferTexture2D   &&
789
 
            GL::generateMipmap          &&
790
 
            GL::genRenderbuffers        &&
791
 
            GL::deleteRenderbuffers     &&
792
 
            GL::bindRenderbuffer        &&
793
 
            GL::framebufferRenderbuffer &&
794
 
            GL::renderbufferStorage
795
 
            )
796
 
            GL::fboSupported = true;
797
 
    }
798
 
 
799
 
    GL::fboStencilSupported = GL::fboSupported &&
800
 
        strstr (glExtensions, "GL_EXT_packed_depth_stencil");
801
 
 
802
 
    if (strstr (glExtensions, "GL_ARB_vertex_buffer_object"))
803
 
    {
804
 
        GL::bindBuffer = (GL::GLBindBufferProc)
805
 
            getProcAddress ("glBindBufferARB");
806
 
        GL::deleteBuffers = (GL::GLDeleteBuffersProc)
807
 
            getProcAddress ("glDeleteBuffersARB");
808
 
        GL::genBuffers = (GL::GLGenBuffersProc)
809
 
            getProcAddress ("glGenBuffersARB");
810
 
        GL::bufferData = (GL::GLBufferDataProc)
811
 
            getProcAddress ("glBufferDataARB");
812
 
        GL::bufferSubData = (GL::GLBufferSubDataProc)
813
 
            getProcAddress ("glBufferSubDataARB");
814
 
 
815
 
        if (GL::bindBuffer    &&
816
 
            GL::deleteBuffers &&
817
 
            GL::genBuffers    &&
818
 
            GL::bufferData    &&
819
 
            GL::bufferSubData)
820
 
            GL::vboSupported = true;
821
 
    }
822
 
 
823
 
    priv->updateRenderMode ();
824
 
 
825
 
    if (strstr (glExtensions, "GL_ARB_fragment_shader") &&
826
 
        strstr (glExtensions, "GL_ARB_vertex_shader") &&
827
 
        strstr (glExtensions, "GL_ARB_shader_objects") &&
828
 
        strstr (glExtensions, "GL_ARB_shading_language_100"))
829
 
    {
830
 
        GL::getShaderiv = (GL::GLGetShaderivProc) GL::getShaderivARBWrapper;
831
 
        GL::getShaderInfoLog = (GL::GLGetShaderInfoLogProc) GL::getShaderInfoLogARBWrapper;
832
 
        GL::getProgramiv = (GL::GLGetProgramivProc) GL::getProgramivARBWrapper;
833
 
        GL::getProgramInfoLog = (GL::GLGetProgramInfoLogProc) GL::getProgramInfoLogARBWrapper;
834
 
        GL::getObjectParameteriv = (GL::GLGetObjectParameterivProc) getProcAddress ("glGetObjectParameterivARB");
835
 
        GL::getInfoLog = (GL::GLGetInfoLogProc) getProcAddress ("glGetInfoLogARB");
836
 
        GL::createShader = (GL::GLCreateShaderProc) GL::createShaderARBWrapper;
837
 
        GL::createShaderObjectARB = (GL::GLCreateShaderObjectARBProc) getProcAddress ("glCreateShaderObjectARB");
838
 
        GL::shaderSource = (GL::GLShaderSourceProc) GL::shaderSourceARBWrapper;
839
 
        GL::shaderSourceARB = (GL::GLShaderSourceARBProc) getProcAddress ("glShaderSourceARB");
840
 
        GL::compileShader = (GL::GLCompileShaderProc) GL::compileShaderARBWrapper;
841
 
        GL::compileShaderARB = (GL::GLCompileShaderARBProc) getProcAddress ("glCompileShaderARB");
842
 
        GL::createProgram = (GL::GLCreateProgramProc) GL::createProgramARBWrapper;
843
 
        GL::createProgramObjectARB = (GL::GLCreateProgramObjectARBProc) getProcAddress ("glCreateProgramObjectARB");
844
 
        GL::attachShader = GL::attachShaderARBWrapper;
845
 
        GL::attachObjectARB = (GL::GLAttachObjectARBProc) getProcAddress ("glAttachObjectARB");
846
 
        GL::linkProgram = GL::linkProgramARBWrapper;
847
 
        GL::linkProgramARB = (GL::GLLinkProgramARBProc) getProcAddress ("glLinkProgramARB");
848
 
        GL::validateProgram = GL::validateProgramARBWrapper;
849
 
        GL::validateProgramARB = (GL::GLValidateProgramARBProc) getProcAddress ("glValidateProgramARB");
850
 
        GL::deleteShader = GL::deleteShaderARBWrapper;
851
 
        GL::deleteProgram = GL::deleteProgramARBWrapper;
852
 
        GL::deleteObjectARB = (GL::GLDeleteObjectARBProc) getProcAddress ("glDeleteObjectARB");
853
 
        GL::useProgram = GL::useProgramARBWrapper;
854
 
        GL::useProgramObjectARB = (GL::GLUseProgramObjectARBProc) getProcAddress ("glUseProgramObjectARB");
855
 
        GL::getUniformLocation = GL::getUniformLocationARBWrapper;
856
 
        GL::getUniformLocationARB = (GL::GLGetUniformLocationARBProc) getProcAddress ("glGetUniformLocationARB");
857
 
        GL::uniform1f = (GL::GLUniform1fProc) getProcAddress ("glUniform1fARB");
858
 
        GL::uniform1i = (GL::GLUniform1iProc) getProcAddress ("glUniform1iARB");
859
 
        GL::uniform2f = (GL::GLUniform2fProc) getProcAddress ("glUniform2fARB");
860
 
        GL::uniform2i = (GL::GLUniform2iProc) getProcAddress ("glUniform2iARB");
861
 
        GL::uniform3f = (GL::GLUniform3fProc) getProcAddress ("glUniform3fARB");
862
 
        GL::uniform3i = (GL::GLUniform3iProc) getProcAddress ("glUniform3iARB");
863
 
        GL::uniform4f = (GL::GLUniform4fProc) getProcAddress ("glUniform4fARB");
864
 
        GL::uniform4i = (GL::GLUniform4iProc) getProcAddress ("glUniform4iARB");
865
 
        GL::uniformMatrix4fv = (GL::GLUniformMatrix4fvProc) getProcAddress ("glUniformMatrix4fvARB");
866
 
        GL::getAttribLocation = (GL::GLGetAttribLocationProc) GL::getAttribLocationARBWrapper;
867
 
        GL::getAttribLocationARB = (GL::GLGetAttribLocationARBProc) getProcAddress ("glGetAttribLocationARB");
868
 
 
869
 
        GL::enableVertexAttribArray = (GL::GLEnableVertexAttribArrayProc) getProcAddress ("glEnableVertexAttribArrayARB");
870
 
        GL::disableVertexAttribArray = (GL::GLDisableVertexAttribArrayProc) getProcAddress ("glDisableVertexAttribArrayARB");
871
 
        GL::vertexAttribPointer = (GL::GLVertexAttribPointerProc) getProcAddress ("glVertexAttribPointerARB");
872
 
 
873
 
        GL::shaders = true;
 
251
            GL::generateMipmap)
 
252
            GL::fbo = true;
874
253
    }
875
254
 
876
255
    if (strstr (glExtensions, "GL_ARB_texture_compression"))
882
261
    glDisable (GL_BLEND);
883
262
    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
884
263
    glColor4usv (defaultColor);
 
264
    glEnableClientState (GL_VERTEX_ARRAY);
 
265
    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
885
266
 
886
267
    if (GL::textureEnvCombine && GL::maxTextureUnits >= 2)
887
268
    {
912
293
 
913
294
    if (GL::textureFromPixmap)
914
295
        registerBindPixmap (TfpTexture::bindPixmapToTexture);
915
 
#endif
916
 
 
917
 
    if (GL::fboSupported)
918
 
    {
919
 
        priv->scratchFbo = new GLFramebufferObject;
920
 
        priv->scratchFbo->allocate (*screen, NULL, GL_BGRA);
921
 
    }
922
 
 
923
 
    GLVertexBuffer::streamingBuffer ()->setAutoProgram (priv->autoProgram);
924
296
 
925
297
    return true;
926
298
}
927
299
 
928
300
 
929
 
template class PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>;
930
 
 
931
301
GLScreen::GLScreen (CompScreen *s) :
932
302
    PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI> (s),
933
303
    priv (new PrivateGLScreen (this))
934
304
{
935
 
#ifndef USE_GLES
936
 
    DetectionWorkaround workaround;
937
 
#endif
938
 
 
939
 
    XVisualInfo          *visinfo = NULL;
940
 
#ifndef USE_GLES
941
305
    Display              *dpy = s->dpy ();
942
306
    XVisualInfo          templ;
 
307
    XVisualInfo          *visinfo;
943
308
    GLXFBConfig          *fbConfigs;
944
309
    int                  defaultDepth, nvisinfo, nElements, value, i;
945
310
    const char           *glxExtensions;
991
356
 
992
357
    glxExtensions = glXQueryExtensionsString (dpy, s->screenNum ());
993
358
 
994
 
    if (glxExtensions == NULL)
995
 
    {
996
 
        compLogMessage ("opengl", CompLogLevelFatal,
997
 
                        "glXQueryExtensionsString is NULL for screen %d",
998
 
                        s->screenNum ());
999
 
        screen->handleCompizEvent ("opengl", "fatal_fallback", o);
1000
 
        setFailed ();
1001
 
        return;
1002
 
    }
1003
 
 
1004
359
    if (!strstr (glxExtensions, "GLX_SGIX_fbconfig"))
1005
360
    {
1006
361
        compLogMessage ("opengl", CompLogLevelFatal,
1071
426
 
1072
427
    fbConfigs = (*GL::getFBConfigs) (dpy, s->screenNum (), &nElements);
1073
428
 
1074
 
    GL::stencilBuffer = false;
1075
 
 
1076
429
    for (i = 0; i <= MAX_DEPTH; i++)
1077
430
    {
1078
 
        int j, db, stencil, depth, alpha, mipmap, msaaBuffers, msaaSamples, rgba;
 
431
        int j, db, stencil, depth, alpha, mipmap, rgba;
1079
432
 
1080
433
        priv->glxPixmapFBConfigs[i].fbConfig       = NULL;
1081
434
        priv->glxPixmapFBConfigs[i].mipmap         = 0;
1083
436
        priv->glxPixmapFBConfigs[i].textureFormat  = 0;
1084
437
        priv->glxPixmapFBConfigs[i].textureTargets = 0;
1085
438
 
1086
 
        db          = MAXSHORT;
1087
 
        stencil     = MAXSHORT;
1088
 
        depth       = MAXSHORT;
1089
 
        msaaBuffers = MAXSHORT;
1090
 
        msaaSamples = MAXSHORT;
1091
 
        mipmap      = 0;
1092
 
        rgba        = 0;
 
439
        db      = MAXSHORT;
 
440
        stencil = MAXSHORT;
 
441
        depth   = MAXSHORT;
 
442
        mipmap  = 0;
 
443
        rgba    = 0;
1093
444
 
1094
445
        for (j = 0; j < nElements; j++)
1095
446
        {
1164
515
 
1165
516
            depth = value;
1166
517
 
1167
 
            (*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
1168
 
                                      GLX_SAMPLE_BUFFERS, &value);
1169
 
            if (value > msaaBuffers)
1170
 
                continue;
1171
 
 
1172
 
            msaaBuffers = value;
1173
 
 
1174
 
            (*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
1175
 
                                      GLX_SAMPLES, &value);
1176
 
            if (value > msaaSamples)
1177
 
                continue;
1178
 
 
1179
 
            msaaSamples = value;
1180
 
 
1181
 
            (*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
1182
 
                                      GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &value);
1183
 
            if (value < mipmap)
1184
 
                continue;
1185
 
 
1186
 
            mipmap = value;
 
518
            if (GL::fbo)
 
519
            {
 
520
                (*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
 
521
                                          GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
 
522
                                          &value);
 
523
                if (value < mipmap)
 
524
                    continue;
 
525
 
 
526
                mipmap = value;
 
527
            }
1187
528
 
1188
529
            (*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
1189
530
                                      GLX_Y_INVERTED_EXT, &value);
1198
539
            priv->glxPixmapFBConfigs[i].fbConfig = fbConfigs[j];
1199
540
            priv->glxPixmapFBConfigs[i].mipmap   = mipmap;
1200
541
        }
1201
 
 
1202
 
        if (i == defaultDepth)
1203
 
            if (stencil != MAXSHORT)
1204
 
                GL::stencilBuffer = true;
1205
542
    }
1206
543
 
1207
544
    if (nElements)
1216
553
        setFailed ();
1217
554
    }
1218
555
 
1219
 
#endif
1220
556
    if (!glInitContext (visinfo))
1221
557
        setFailed ();
1222
558
}
1225
561
{
1226
562
    if (priv->hasCompositing)
1227
563
        CompositeScreen::get (screen)->unregisterPaintHandler ();
1228
 
 
1229
 
    #ifdef USE_GLES
1230
 
    Display *xdpy = screen->dpy ();
1231
 
    EGLDisplay dpy = eglGetDisplay (xdpy);
1232
 
 
1233
 
    eglMakeCurrent (dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
1234
 
    if (priv->ctx != EGL_NO_CONTEXT)
1235
 
        eglDestroyContext (dpy, priv->ctx);
1236
 
    eglDestroySurface (dpy, priv->surface);
1237
 
    eglTerminate (dpy);
1238
 
    eglReleaseThread ();
1239
 
    #else
1240
 
 
1241
 
    if (priv->ctx)
1242
 
        glXDestroyContext (screen->dpy (), priv->ctx);
1243
 
    #endif
1244
 
 
1245
 
    if (priv->scratchFbo)
1246
 
        delete priv->scratchFbo;
1247
 
 
 
564
    glXDestroyContext (screen->dpy (), priv->ctx);
1248
565
    delete priv;
1249
566
}
1250
567
 
1255
572
    backgroundTextures (),
1256
573
    backgroundLoaded (false),
1257
574
    rasterPos (0, 0),
1258
 
    projection (NULL),
 
575
    fragmentStorage (),
1259
576
    clearBuffers (true),
1260
577
    lighting (false),
1261
 
    #ifndef USE_GLES
1262
 
    ctx (NULL),
1263
578
    getProcAddress (0),
1264
 
    doubleBuffer (screen->dpy (), *screen, cScreen->output ()),
1265
 
    #else
1266
 
    ctx (EGL_NO_CONTEXT),
1267
 
    doubleBuffer (screen->dpy (), *screen, surface),
1268
 
    #endif
1269
 
    scratchFbo (NULL),
1270
579
    outputRegion (),
1271
 
    refreshSubBuffer (false),
1272
 
    lastMask (0),
1273
580
    bindPixmap (),
1274
581
    hasCompositing (false),
1275
 
    commonFrontbuffer (true),
1276
 
    incorrectRefreshRate (false),
1277
 
    programCache (new GLProgramCache (30)),
1278
 
    shaderCache (),
1279
 
    autoProgram (new GLScreenAutoProgram(gs)),
1280
582
    rootPixmapCopy (None),
1281
 
    rootPixmapSize (),
1282
 
    glVendor (NULL),
1283
 
    glRenderer (NULL),
1284
 
    glVersion (NULL),
1285
 
    prevRegex (),
1286
 
    prevBlacklisted (false)
 
583
    rootPixmapSize ()
1287
584
{
1288
585
    ScreenInterface::setHandler (screen);
1289
586
}
1290
587
 
1291
588
PrivateGLScreen::~PrivateGLScreen ()
1292
589
{
1293
 
    delete projection;
1294
 
    delete programCache;
1295
 
    delete autoProgram;
1296
590
    if (rootPixmapCopy)
1297
591
        XFreePixmap (screen->dpy (), rootPixmapCopy);
1298
592
 
1348
642
                    GLWindow::get (w)->priv->icons.clear ();
1349
643
            }
1350
644
            break;
1351
 
 
 
645
        break;
1352
646
        default:
1353
647
            if (event->type == cScreen->damageEvent () + XDamageNotify)
1354
648
            {
1355
649
                XDamageNotifyEvent *de = (XDamageNotifyEvent *) event;
1356
650
 
1357
 
                #ifdef USE_GLES
1358
 
                std::map<Damage, EglTexture*>::iterator it =
1359
 
                    boundPixmapTex.find (de->damage);
1360
 
                #else
1361
651
                std::map<Damage, TfpTexture*>::iterator it =
1362
652
                    boundPixmapTex.find (de->damage);
1363
 
                #endif
1364
653
                if (it != boundPixmapTex.end ())
1365
654
                {
1366
655
                    it->second->damaged = true;
1432
721
void
1433
722
PrivateGLScreen::updateView ()
1434
723
{
1435
 
    GLfloat projection_array[16];
1436
 
 
1437
 
    #ifndef USE_GLES
1438
724
    glMatrixMode (GL_PROJECTION);
1439
725
    glLoadIdentity ();
1440
726
    glMatrixMode (GL_MODELVIEW);
1441
727
    glLoadIdentity ();
1442
728
    glDepthRange (0, 1);
1443
 
    glRasterPos2f (0, 0);
1444
 
    #endif
1445
729
    glViewport (-1, -1, 2, 2);
 
730
    glRasterPos2f (0, 0);
1446
731
 
1447
732
    rasterPos = CompPoint (0, 0);
1448
733
 
1449
 
    perspective (projection_array, 60.0f, 1.0f, 0.1f, 100.0f);
1450
 
 
1451
 
    if (projection != NULL)
1452
 
        delete projection;
1453
 
    projection = new GLMatrix (projection_array);
1454
 
 
1455
 
    #ifndef USE_GLES
 
734
    perspective (projection, 60.0f, 1.0f, 0.1f, 100.0f);
 
735
 
1456
736
    glMatrixMode (GL_PROJECTION);
1457
737
    glLoadIdentity ();
1458
 
    glMultMatrixf (projection_array);
 
738
    glMultMatrixf (projection);
1459
739
    glMatrixMode (GL_MODELVIEW);
1460
 
    #endif
1461
740
 
1462
741
    CompRegion region (screen->region ());
1463
742
    /* remove all output regions from visible screen region */
1476
755
{
1477
756
    screen->outputChangeNotify ();
1478
757
 
1479
 
    if (scratchFbo)
1480
 
        scratchFbo->allocate (*screen, NULL, GL_BGRA);
1481
758
    updateView ();
1482
759
}
1483
760
 
1484
 
#ifndef USE_GLES
1485
761
GL::FuncPtr
1486
762
GLScreen::getProcAddress (const char *name)
1487
763
{
1507
783
 
1508
784
    return funcPtr;
1509
785
}
1510
 
#endif
1511
786
 
1512
787
void
1513
788
PrivateGLScreen::updateScreenBackground ()
1625
900
 
1626
901
        XFreeGC(dpy, gc);
1627
902
    }
 
903
 
 
904
    if (!backgroundTextures.empty ())
 
905
    {
 
906
        foreach (GLTexture *t, backgroundTextures)
 
907
            if (t->target () == GL_TEXTURE_2D)
 
908
            {
 
909
                glBindTexture (t->target (), t->name ());
 
910
                glTexParameteri (t->target (), GL_TEXTURE_WRAP_S, GL_REPEAT);
 
911
                glTexParameteri (t->target (), GL_TEXTURE_WRAP_T, GL_REPEAT);
 
912
                glBindTexture (t->target (), 0);
 
913
            }
 
914
    }
1628
915
}
1629
916
 
1630
917
void
1631
918
GLScreen::setTexEnvMode (GLenum mode)
1632
919
{
1633
 
    #ifndef USE_GLES
1634
920
    if (priv->lighting)
1635
921
        glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1636
922
    else
1637
923
        glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
1638
 
    #endif
1639
924
}
1640
925
 
1641
926
void
1642
927
GLScreen::setLighting (bool lighting)
1643
928
{
1644
 
    #ifndef USE_GLES
1645
929
    if (priv->lighting != lighting)
1646
930
    {
1647
931
        if (!priv->optionGetLighting ())
1662
946
 
1663
947
        setTexEnvMode (GL_REPLACE);
1664
948
    }
1665
 
    #endif
1666
949
}
1667
950
 
1668
951
bool
1698
981
GLScreenInterface::glDisableOutputClipping ()
1699
982
    WRAPABLE_DEF (glDisableOutputClipping)
1700
983
 
1701
 
GLMatrix *
1702
 
GLScreenInterface::projectionMatrix ()
1703
 
    WRAPABLE_DEF (projectionMatrix)
1704
 
 
1705
 
void
1706
 
GLScreenInterface::glPaintCompositedOutput (const CompRegion    &region,
1707
 
                                            GLFramebufferObject *fbo,
1708
 
                                            unsigned int         mask)
1709
 
    WRAPABLE_DEF (glPaintCompositedOutput, region, fbo, mask)
1710
 
 
1711
 
void
1712
 
GLScreenInterface::glBufferStencil(const GLMatrix &matrix,
1713
 
                                   GLVertexBuffer &vertexBuffer,
1714
 
                                   CompOutput *output)
1715
 
    WRAPABLE_DEF (glBufferStencil, matrix, vertexBuffer, output)
1716
 
 
1717
 
GLMatrix *
1718
 
GLScreen::projectionMatrix ()
1719
 
{
1720
 
    WRAPABLE_HND_FUNCTN_RETURN (GLMatrix *, projectionMatrix)
1721
 
 
1722
 
    return priv->projection;
1723
 
}
1724
 
 
1725
984
void
1726
985
GLScreen::updateBackground ()
1727
986
{
1752
1011
    priv->filter[num] = filter;
1753
1012
}
1754
1013
 
1755
 
#ifndef USE_GLES
 
1014
GLFragment::Storage *
 
1015
GLScreen::fragmentStorage ()
 
1016
{
 
1017
    return &priv->fragmentStorage;
 
1018
}
 
1019
 
1756
1020
GLFBConfig*
1757
1021
GLScreen::glxPixmapFBConfig (unsigned int depth)
1758
1022
{
1759
1023
    return &priv->glxPixmapFBConfigs[depth];
1760
1024
}
1761
 
#endif
1762
1025
 
1763
1026
void
1764
1027
GLScreen::clearOutput (CompOutput   *output,
1771
1034
        pBox->x2 != (int) screen->width () ||
1772
1035
        pBox->y2 != (int) screen->height ())
1773
1036
    {
 
1037
        glPushAttrib (GL_SCISSOR_BIT);
 
1038
 
1774
1039
        glEnable (GL_SCISSOR_TEST);
1775
1040
        glScissor (pBox->x1,
1776
1041
                   screen->height () - pBox->y2,
1777
1042
                   pBox->x2 - pBox->x1,
1778
1043
                   pBox->y2 - pBox->y1);
1779
1044
        glClear (mask);
1780
 
        glDisable (GL_SCISSOR_TEST);
 
1045
 
 
1046
        glPopAttrib ();
1781
1047
    }
1782
1048
    else
1783
1049
    {
1800
1066
                priv->lastViewport.height);
1801
1067
}
1802
1068
 
1803
 
#ifdef USE_GLES
1804
 
EGLContext
1805
 
GLScreen::getEGLContext ()
1806
 
{
1807
 
    return priv->ctx;
1808
 
}
1809
 
#endif
1810
 
 
1811
 
GLProgram *
1812
 
GLScreen::getProgram (std::list<const GLShaderData*> shaders)
1813
 
{
1814
 
    return (*priv->programCache)(shaders);
1815
 
}
1816
 
 
1817
 
const GLShaderData *
1818
 
GLScreen::getShaderData (GLShaderParameters &params)
1819
 
{
1820
 
    return &priv->shaderCache.getShaderData(params);
1821
 
}
1822
 
 
1823
 
GLDoubleBuffer::GLDoubleBuffer (Display                                             *d,
1824
 
                                const CompSize                                      &s,
1825
 
                                const compiz::opengl::impl::GLXSwapIntervalEXTFunc  &swapIntervalFunc,
1826
 
                                const compiz::opengl::impl::GLXWaitVideoSyncSGIFunc &waitVideoSyncFunc) :
1827
 
    compiz::opengl::DoubleBuffer (swapIntervalFunc, waitVideoSyncFunc),
1828
 
    mDpy (d),
1829
 
    mSize (s)
1830
 
{
1831
 
}
1832
 
 
1833
 
#ifndef USE_GLES
1834
 
 
1835
 
void
1836
 
GLXDoubleBuffer::copyFrontToBack() const
1837
 
{
1838
 
    int w = screen->width ();
1839
 
    int h = screen->height ();
1840
 
 
1841
 
    glMatrixMode (GL_PROJECTION);
1842
 
    glPushMatrix ();
1843
 
    glLoadIdentity ();
1844
 
    glOrtho (0, w, 0, h, -1.0, 1.0);
1845
 
    glMatrixMode (GL_MODELVIEW);
1846
 
    glPushMatrix ();
1847
 
    glLoadIdentity ();
1848
 
 
1849
 
    glReadBuffer (GL_FRONT);
1850
 
    glRasterPos2i (0, 0);
1851
 
    glCopyPixels (0, 0, w, h, GL_COLOR);
1852
 
    glReadBuffer (GL_BACK);
1853
 
 
1854
 
    glPopMatrix ();
1855
 
    glMatrixMode (GL_PROJECTION);
1856
 
    glPopMatrix ();
1857
 
    glMatrixMode (GL_MODELVIEW);
1858
 
}
1859
 
 
1860
 
GLXDoubleBuffer::GLXDoubleBuffer (Display        *d,
1861
 
                                  const CompSize &s,
1862
 
                                  Window         output) :
1863
 
    GLDoubleBuffer (d, s,
1864
 
                    boost::bind (compiz::opengl::swapIntervalGLX, d, _1),
1865
 
                    boost::bind (compiz::opengl::waitVSyncGLX, _1, _2, _3)),
1866
 
    mOutput (output)
1867
 
{
1868
 
}
1869
 
 
1870
 
void
1871
 
GLXDoubleBuffer::swap () const
1872
 
{
1873
 
    glXSwapBuffers (mDpy, mOutput);
1874
 
}
1875
 
 
1876
 
bool
1877
 
GLXDoubleBuffer::blitAvailable () const
1878
 
{
1879
 
    return GL::copySubBuffer ? true : false;
1880
 
}
1881
 
 
1882
 
void
1883
 
GLXDoubleBuffer::blit (const CompRegion &region) const
1884
 
{
1885
 
    const CompRect::vector &blitRects (region.rects ());
1886
 
 
1887
 
    foreach (const CompRect &r, blitRects)
1888
 
    {
1889
 
        int y = mSize.height () - r.y2 ();
1890
 
        (*GL::copySubBuffer) (screen->dpy (), mOutput,
1891
 
                              r.x1 (), y, r.width (), r.height ());
1892
 
    }
1893
 
}
1894
 
 
1895
 
bool
1896
 
GLXDoubleBuffer::fallbackBlitAvailable () const
1897
 
{
1898
 
    return true;
1899
 
}
1900
 
 
1901
 
void
1902
 
GLXDoubleBuffer::fallbackBlit (const CompRegion &region) const
1903
 
{
1904
 
    const CompRect::vector &blitRects (region.rects ());
1905
 
    int w = screen->width ();
1906
 
    int h = screen->height ();
1907
 
 
1908
 
    glMatrixMode (GL_PROJECTION);
1909
 
    glPushMatrix ();
1910
 
    glLoadIdentity ();
1911
 
    glOrtho (0, w, 0, h, -1.0, 1.0);
1912
 
    glMatrixMode (GL_MODELVIEW);
1913
 
    glPushMatrix ();
1914
 
    glLoadIdentity ();
1915
 
 
1916
 
    glDrawBuffer (GL_FRONT);
1917
 
    foreach (const CompRect &r, blitRects)
1918
 
    {
1919
 
        int x = r.x1 ();
1920
 
        int y = h - r.y2();
1921
 
        glRasterPos2i (x, y);
1922
 
        glCopyPixels (x, y, w, h, GL_COLOR);
1923
 
    }
1924
 
    glDrawBuffer (GL_BACK);
1925
 
 
1926
 
    glPopMatrix ();
1927
 
    glMatrixMode (GL_PROJECTION);
1928
 
    glPopMatrix ();
1929
 
    glMatrixMode (GL_MODELVIEW);
1930
 
 
1931
 
    glFlush ();
1932
 
 
1933
 
}
1934
 
 
1935
 
#else
1936
 
 
1937
 
EGLDoubleBuffer::EGLDoubleBuffer (Display          *d,
1938
 
                                  const CompSize   &s,
1939
 
                                  EGLSurface const &surface) :
1940
 
    GLDoubleBuffer (d, s,
1941
 
                    boost::bind (compiz::opengl::swapIntervalEGL, d, _1),
1942
 
                    boost::bind (compiz::opengl::waitVSyncEGL, _1, _2, _3)),
1943
 
    mSurface (surface)
1944
 
{
1945
 
}
1946
 
 
1947
 
void
1948
 
EGLDoubleBuffer::swap () const
1949
 
{
1950
 
    eglSwapBuffers (eglGetDisplay (mDpy), mSurface);
1951
 
}
1952
 
 
1953
 
bool
1954
 
EGLDoubleBuffer::blitAvailable () const
1955
 
{
1956
 
    return GL::postSubBuffer ? true : false;
1957
 
}
1958
 
 
1959
 
void
1960
 
EGLDoubleBuffer::blit (const CompRegion &region) const
1961
 
{
1962
 
    CompRect::vector blitRects (region.rects ());
1963
 
    int              y = 0;
1964
 
 
1965
 
    foreach (const CompRect &r, blitRects)
1966
 
    {
1967
 
        y = mSize.height () - r.y2 ();
1968
 
 
1969
 
        (*GL::postSubBuffer) (eglGetDisplay (screen->dpy ()),
1970
 
                              mSurface,
1971
 
                              r.x1 (), y,
1972
 
                              r.width (),
1973
 
                              r.height ());
1974
 
    }
1975
 
}
1976
 
 
1977
 
bool
1978
 
EGLDoubleBuffer::fallbackBlitAvailable () const
1979
 
{
1980
 
    return false;
1981
 
}
1982
 
 
1983
 
void
1984
 
EGLDoubleBuffer::fallbackBlit (const CompRegion &region) const
1985
 
{
1986
 
}
1987
 
 
1988
 
void
1989
 
EGLDoubleBuffer::copyFrontToBack() const
1990
 
{
1991
 
}
1992
 
 
1993
 
#endif
 
1069
namespace GL
 
1070
{
 
1071
 
 
1072
void
 
1073
waitForVideoSync ()
 
1074
{
 
1075
    GL::unthrottledFrames++;
 
1076
    if (GL::waitVideoSync)
 
1077
    {
 
1078
        // Don't wait twice. Just in case.
 
1079
        if (GL::swapInterval)
 
1080
            (*GL::swapInterval) (0);
 
1081
 
 
1082
        /*
 
1083
         * While glXSwapBuffers/glXCopySubBufferMESA are meant to do a
 
1084
         * flush before they blit, it is best to not let that happen.
 
1085
         * Because that flush would occur after GL::waitVideoSync, causing
 
1086
         * a delay and the final blit to be slightly out of sync resulting
 
1087
         * in tearing. So we need to do a glFinish before we wait for
 
1088
         * vsync, to absolutely minimize tearing.
 
1089
         */
 
1090
        glFinish ();
 
1091
 
 
1092
        // Docs: http://www.opengl.org/registry/specs/SGI/video_sync.txt
 
1093
        unsigned int oldCount = GL::vsyncCount;
 
1094
        (*GL::waitVideoSync) (1, 0, &GL::vsyncCount);
 
1095
 
 
1096
        if (GL::vsyncCount != oldCount)
 
1097
            GL::unthrottledFrames = 0;
 
1098
    }
 
1099
}
 
1100
 
 
1101
void
 
1102
controlSwapVideoSync (bool sync)
 
1103
{
 
1104
    // Docs: http://www.opengl.org/registry/specs/SGI/swap_control.txt
 
1105
    if (GL::swapInterval)
 
1106
    {
 
1107
        (*GL::swapInterval) (sync ? 1 : 0);
 
1108
        GL::unthrottledFrames++;
 
1109
    }
 
1110
    else if (sync)
 
1111
        waitForVideoSync ();
 
1112
}
 
1113
 
 
1114
} // namespace GL
 
1115
 
 
1116
void
 
1117
PrivateGLScreen::waitForVideoSync ()
 
1118
{
 
1119
    if (optionGetSyncToVblank ())
 
1120
        GL::waitForVideoSync ();
 
1121
}
1994
1122
 
1995
1123
void
1996
1124
PrivateGLScreen::paintOutputs (CompOutput::ptrList &outputs,
1997
1125
                               unsigned int        mask,
1998
1126
                               const CompRegion    &region)
1999
1127
{
 
1128
    XRectangle r;
 
1129
 
2000
1130
    if (clearBuffers)
2001
1131
    {
2002
1132
        if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
2003
1133
            glClear (GL_COLOR_BUFFER_BIT);
2004
1134
    }
2005
1135
 
2006
 
    // Disable everything that we don't usually need and could slow us down
2007
 
    glDisable (GL_BLEND);
2008
 
    glDisable (GL_STENCIL_TEST);
2009
 
    glDisable (GL_DEPTH_TEST);
2010
 
    glDepthMask (GL_FALSE);
2011
 
    glStencilMask (0);
2012
 
 
2013
 
    GLFramebufferObject *oldFbo = NULL;
2014
 
    bool useFbo = false;
2015
 
 
2016
 
    /* Clear the color buffer where appropriate */
2017
 
    if (GL::fboEnabled && scratchFbo)
2018
 
    {
2019
 
        oldFbo = scratchFbo->bind ();
2020
 
        useFbo = scratchFbo->checkStatus () && scratchFbo->tex ();
2021
 
        if (!useFbo)
2022
 
            GLFramebufferObject::rebind (oldFbo);
2023
 
    }
2024
 
 
2025
 
#ifdef UNSAFE_ARM_SGX_FIXME
2026
 
    refreshSubBuffer = ((lastMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
2027
 
                        !(mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
2028
 
                        (mask & COMPOSITE_SCREEN_DAMAGE_REGION_MASK));
2029
 
 
2030
 
    if (refreshSubBuffer)
2031
 
    {
2032
 
        // FIXME: We shouldn't have to substract a 1X1 pixel region here !!
2033
 
        // This is an ugly workaround for what appears to be a bug in the SGX
2034
 
        // X11 driver (e.g. on Pandaboard OMAP4 platform).
2035
 
        // Posting a fullscreen damage region to the SGX seems to reset the
2036
 
        // framebuffer, causing the screen to blackout.
2037
 
        cScreen->damageRegion (CompRegion (screen->fullscreenOutput ()) -
2038
 
                               CompRegion (CompRect(0, 0, 1, 1)));
2039
 
    }
2040
 
#endif
2041
 
 
2042
 
    CompRegion tmpRegion = (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) ?
2043
 
                           screen->region () : region;
 
1136
    CompRegion tmpRegion (region);
2044
1137
 
2045
1138
    foreach (CompOutput *output, outputs)
2046
1139
    {
2047
 
        XRectangle r;
2048
1140
        targetOutput = output;
2049
1141
 
2050
1142
        r.x      = output->x1 ();
2075
1167
        {
2076
1168
            GLMatrix identity;
2077
1169
 
2078
 
#ifdef UNSAFE_ARM_SGX_FIXME
2079
 
            /*
2080
 
             * FIXME:
2081
 
             * This code is unsafe and causes Unity bug 1036520.
2082
 
             * So it probably needs to be replaced with something else
2083
 
             * on platforms where it is required.
2084
 
             *
2085
 
             * We should NEVER be extending tmpRegion, because that's
2086
 
             * telling windows/plugins it is OK to paint outside the
2087
 
             * damaged region.
2088
 
             */
2089
 
            if (refreshSubBuffer)
2090
 
                tmpRegion = CompRegion (*output);
2091
 
#endif
2092
 
 
2093
1170
            outputRegion = tmpRegion & CompRegion (*output);
2094
1171
 
2095
1172
            if (!gScreen->glPaintOutput (defaultScreenPaintAttrib,
2105
1182
                                        PAINT_SCREEN_FULL_MASK);
2106
1183
 
2107
1184
                tmpRegion += *output;
 
1185
 
2108
1186
            }
2109
1187
        }
2110
1188
    }
2111
1189
 
2112
1190
    targetOutput = &screen->outputDevs ()[0];
2113
1191
 
2114
 
    glViewport (0, 0, screen->width (), screen->height ());
2115
 
 
2116
 
    if (useFbo)
2117
 
    {
2118
 
        GLFramebufferObject::rebind (oldFbo);
2119
 
 
2120
 
        // FIXME: does not work if screen dimensions exceed max texture size
2121
 
        //        We should try to use glBlitFramebuffer instead.
2122
 
        gScreen->glPaintCompositedOutput (screen->region (), scratchFbo, mask);
2123
 
    }
2124
 
 
2125
 
    if (cScreen->outputWindowChanged ())
 
1192
    if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
2126
1193
    {
2127
1194
        /*
2128
 
         * Changes to the composite output window seem to take a whole frame
2129
 
         * to take effect. So to avoid a visible flicker, we skip this frame
2130
 
         * and do a full redraw next time.
 
1195
         * controlSwapVideoSync is much faster than waitForVideoSync because
 
1196
         * it won't block the CPU. The waiting is offloaded to the GPU.
 
1197
         * Unfortunately it only works with glXSwapBuffers in most drivers.
2131
1198
         */
2132
 
        cScreen->damageScreen ();
2133
 
        return;
2134
 
    }
2135
 
 
2136
 
    bool alwaysSwap = optionGetAlwaysSwapBuffers ();
2137
 
    bool fullscreen = useFbo ||
2138
 
                      alwaysSwap ||
2139
 
                      ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
2140
 
                       commonFrontbuffer);
2141
 
 
2142
 
    doubleBuffer.set (DoubleBuffer::VSYNC, optionGetSyncToVblank ());
2143
 
    doubleBuffer.set (DoubleBuffer::HAVE_PERSISTENT_BACK_BUFFER, useFbo);
2144
 
    doubleBuffer.set (DoubleBuffer::NEED_PERSISTENT_BACK_BUFFER, alwaysSwap);
2145
 
    doubleBuffer.render (tmpRegion, fullscreen);
2146
 
 
2147
 
    lastMask = mask;
 
1199
        GL::controlSwapVideoSync (optionGetSyncToVblank ());
 
1200
        glXSwapBuffers (screen->dpy (), cScreen->output ());
 
1201
    }
 
1202
    else
 
1203
    {
 
1204
        BoxPtr pBox = const_cast <Region> (tmpRegion.handle ())->rects;
 
1205
        int    nBox = const_cast <Region> (tmpRegion.handle ())->numRects;
 
1206
        int    y;
 
1207
 
 
1208
        waitForVideoSync ();
 
1209
 
 
1210
        if (GL::copySubBuffer)
 
1211
        {
 
1212
            while (nBox--)
 
1213
            {
 
1214
                y = screen->height () - pBox->y2;
 
1215
 
 
1216
                (*GL::copySubBuffer) (screen->dpy (), cScreen->output (),
 
1217
                                      pBox->x1, y,
 
1218
                                      pBox->x2 - pBox->x1,
 
1219
                                      pBox->y2 - pBox->y1);
 
1220
 
 
1221
                pBox++;
 
1222
            }
 
1223
        }
 
1224
        else
 
1225
        {
 
1226
            glEnable (GL_SCISSOR_TEST);
 
1227
            glDrawBuffer (GL_FRONT);
 
1228
 
 
1229
            while (nBox--)
 
1230
            {
 
1231
                y = screen->height () - pBox->y2;
 
1232
 
 
1233
                glBitmap (0, 0, 0, 0,
 
1234
                          pBox->x1 - rasterPos.x (),
 
1235
                          y - rasterPos.y (),
 
1236
                          NULL);
 
1237
 
 
1238
                rasterPos = CompPoint (pBox->x1, y);
 
1239
 
 
1240
                glScissor (pBox->x1, y,
 
1241
                           pBox->x2 - pBox->x1,
 
1242
                           pBox->y2 - pBox->y1);
 
1243
 
 
1244
                glCopyPixels (pBox->x1, y,
 
1245
                              pBox->x2 - pBox->x1,
 
1246
                              pBox->y2 - pBox->y1,
 
1247
                              GL_COLOR);
 
1248
 
 
1249
                pBox++;
 
1250
            }
 
1251
 
 
1252
            glDrawBuffer (GL_BACK);
 
1253
            glDisable (GL_SCISSOR_TEST);
 
1254
            glFlush ();
 
1255
        }
 
1256
    }
2148
1257
}
2149
1258
 
2150
1259
bool
2151
1260
PrivateGLScreen::hasVSync ()
2152
1261
{
2153
 
    #ifdef USE_GLES
2154
 
    return false;
2155
 
    #else
2156
1262
    return GL::waitVideoSync && optionGetSyncToVblank () && 
2157
 
           doubleBuffer.hardwareVSyncFunctional ();
2158
 
    #endif
2159
 
}
2160
 
 
2161
 
bool
2162
 
PrivateGLScreen::requiredForcedRefreshRate ()
2163
 
{
2164
 
    return incorrectRefreshRate;
 
1263
           GL::unthrottledFrames < 5;
2165
1264
}
2166
1265
 
2167
1266
bool
2171
1270
}
2172
1271
 
2173
1272
void
2174
 
PrivateGLScreen::updateRenderMode ()
2175
 
{
2176
 
#ifndef USE_GLES
2177
 
    GL::fboEnabled = GL::fboSupported && optionGetFramebufferObject ();
2178
 
    GL::vboEnabled = GL::vboSupported && optionGetVertexBufferObject ();
2179
 
#endif
2180
 
}
2181
 
 
2182
 
void
2183
1273
PrivateGLScreen::prepareDrawing ()
2184
1274
{
2185
 
    bool wasFboEnabled = GL::fboEnabled;
2186
 
    updateRenderMode ();
2187
 
    if (wasFboEnabled != GL::fboEnabled)
2188
 
        CompositeScreen::get (screen)->damageScreen ();
2189
 
}
2190
 
 
2191
 
bool
2192
 
PrivateGLScreen::driverIsBlacklisted (const char *regex) const
2193
 
{
2194
 
    /*
2195
 
     * regex matching is VERY expensive, so only do it when the result might
2196
 
     * be different to last time. The gl* variables never change value...
2197
 
     */
2198
 
    if (prevRegex != regex)
2199
 
    {
2200
 
        prevBlacklisted = blacklisted (regex, glVendor, glRenderer, glVersion);
2201
 
        prevRegex = regex;
2202
 
    }
2203
 
    return prevBlacklisted;
2204
1275
}
2205
1276
 
2206
1277
GLTexture::BindPixmapHandle
2228
1299
    }
2229
1300
}
2230
1301
 
2231
 
GLFramebufferObject *
2232
 
GLScreen::fbo ()
2233
 
{
2234
 
    return priv->scratchFbo;
2235
 
}
2236
 
 
2237
1302
GLTexture *
2238
1303
GLScreen::defaultIcon ()
2239
1304
{
2266
1331
void
2267
1332
GLScreen::resetRasterPos ()
2268
1333
{
2269
 
    #ifndef USE_GLES
2270
1334
    glRasterPos2f (0, 0);
2271
 
    #endif
2272
1335
    priv->rasterPos.setX (0);
2273
1336
    priv->rasterPos.setY (0);
2274
1337
}
2275
1338
 
 
1339
const float *
 
1340
GLScreen::projectionMatrix ()
 
1341
{
 
1342
    return priv->projection;
 
1343
}