2
* Copyright © 2008 Dennis Kasprzyk
3
* Copyright © 2007 Novell, Inc.
5
* Permission to use, copy, modify, distribute, and sell this software
6
* and its documentation for any purpose is hereby granted without
7
* fee, provided that the above copyright notice appear in all copies
8
* and that both that copyright notice and this permission notice
9
* appear in supporting documentation, and that the name of
10
* Dennis Kasprzyk not be used in advertising or publicity pertaining to
11
* distribution of the software without specific, written prior permission.
12
* Dennis Kasprzyk makes no representations about the suitability of this
13
* software for any purpose. It is provided "as is" without express or
16
* DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
18
* NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
20
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
21
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
22
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
* Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>
25
* David Reveman <davidr@novell.com>
34
GLXBindTexImageProc bindTexImage = 0;
35
GLXReleaseTexImageProc releaseTexImage = 0;
36
GLXQueryDrawableProc queryDrawable = 0;
37
GLXCopySubBufferProc copySubBuffer = 0;
38
GLXGetVideoSyncProc getVideoSync = 0;
39
GLXWaitVideoSyncProc waitVideoSync = 0;
40
GLXGetFBConfigsProc getFBConfigs = 0;
41
GLXGetFBConfigAttribProc getFBConfigAttrib = 0;
42
GLXCreatePixmapProc createPixmap = 0;
44
GLActiveTextureProc activeTexture = 0;
45
GLClientActiveTextureProc clientActiveTexture = 0;
46
GLMultiTexCoord2fProc multiTexCoord2f = 0;
48
GLGenProgramsProc genPrograms = 0;
49
GLDeleteProgramsProc deletePrograms = 0;
50
GLBindProgramProc bindProgram = 0;
51
GLProgramStringProc programString = 0;
52
GLProgramParameter4fProc programEnvParameter4f = 0;
53
GLProgramParameter4fProc programLocalParameter4f = 0;
54
GLGetProgramivProc getProgramiv = 0;
56
GLGenFramebuffersProc genFramebuffers = 0;
57
GLDeleteFramebuffersProc deleteFramebuffers = 0;
58
GLBindFramebufferProc bindFramebuffer = 0;
59
GLCheckFramebufferStatusProc checkFramebufferStatus = 0;
60
GLFramebufferTexture2DProc framebufferTexture2D = 0;
61
GLGenerateMipmapProc generateMipmap = 0;
63
bool textureFromPixmap = true;
64
bool textureRectangle = false;
65
bool textureNonPowerOfTwo = false;
66
bool textureEnvCombine = false;
67
bool textureEnvCrossbar = false;
68
bool textureBorderClamp = false;
69
bool textureCompression = false;
70
GLint maxTextureSize = 0;
72
bool fragmentProgram = false;
73
GLint maxTextureUnits = 1;
75
bool canDoSaturated = false;
76
bool canDoSlightlySaturated = false;
79
CompOutput *targetOutput = NULL;
81
GLScreen::GLScreen (CompScreen *s) :
82
PrivateHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI> (s),
83
priv (new PrivateGLScreen (this))
85
Display *dpy = s->dpy ();
88
GLXFBConfig *fbConfigs;
89
int defaultDepth, nvisinfo, nElements, value, i;
90
const char *glxExtensions, *glExtensions;
91
GLfloat globalAmbient[] = { 0.1f, 0.1f, 0.1f, 0.1f };
92
GLfloat ambientLight[] = { 0.0f, 0.0f, 0.0f, 0.0f };
93
GLfloat diffuseLight[] = { 0.9f, 0.9f, 0.9f, 0.9f };
94
GLfloat light0Position[] = { -0.5f, 0.5f, -9.0f, 1.0f };
95
XWindowAttributes attr;
97
if (indirectRendering)
99
/* force Mesa libGL into indirect rendering mode, because
100
glXQueryExtensionsString is context-independant */
101
setenv ("LIBGL_ALWAYS_INDIRECT", "1", True);
104
if (!openglVTable->getMetadata ()->initOptions (glOptionInfo, GL_OPTION_NUM,
111
if (!XGetWindowAttributes (dpy, s->root (), &attr))
117
templ.visualid = XVisualIDFromVisual (attr.visual);
119
visinfo = XGetVisualInfo (dpy, VisualIDMask, &templ, &nvisinfo);
122
compLogMessage ("opengl", CompLogLevelFatal,
123
"Couldn't get visual info for default visual");
128
defaultDepth = visinfo->depth;
130
glXGetConfig (dpy, visinfo, GLX_USE_GL, &value);
133
compLogMessage ("opengl", CompLogLevelFatal,
134
"Root visual is not a GL visual");
140
glXGetConfig (dpy, visinfo, GLX_DOUBLEBUFFER, &value);
143
compLogMessage ("opengl", CompLogLevelFatal,
144
"Root visual is not a double buffered GL visual");
150
priv->ctx = glXCreateContext (dpy, visinfo, NULL, !indirectRendering);
153
compLogMessage ("opengl", CompLogLevelFatal,
154
"glXCreateContext failed");
162
glxExtensions = glXQueryExtensionsString (dpy, s->screenNum ());
164
if (!strstr (glxExtensions, "GLX_SGIX_fbconfig"))
166
compLogMessage ("opengl", CompLogLevelFatal,
167
"GLX_SGIX_fbconfig is missing");
172
priv->getProcAddress = (GL::GLXGetProcAddressProc)
173
getProcAddress ("glXGetProcAddressARB");
174
GL::bindTexImage = (GL::GLXBindTexImageProc)
175
getProcAddress ("glXBindTexImageEXT");
176
GL::releaseTexImage = (GL::GLXReleaseTexImageProc)
177
getProcAddress ("glXReleaseTexImageEXT");
178
GL::queryDrawable = (GL::GLXQueryDrawableProc)
179
getProcAddress ("glXQueryDrawable");
180
GL::getFBConfigs = (GL::GLXGetFBConfigsProc)
181
getProcAddress ("glXGetFBConfigs");
182
GL::getFBConfigAttrib = (GL::GLXGetFBConfigAttribProc)
183
getProcAddress ("glXGetFBConfigAttrib");
184
GL::createPixmap = (GL::GLXCreatePixmapProc)
185
getProcAddress ("glXCreatePixmap");
188
if (!strstr (glxExtensions, "GLX_EXT_texture_from_pixmap") ||
189
!GL::bindTexImage || !GL::releaseTexImage)
191
compLogMessage ("opengl", CompLogLevelFatal,
192
"GLX_EXT_texture_from_pixmap is missing");
193
GL::textureFromPixmap = false;
196
GL::textureFromPixmap = true;
198
if (!GL::queryDrawable ||
200
!GL::getFBConfigAttrib ||
203
compLogMessage ("opengl", CompLogLevelFatal,
204
"fbconfig functions missing");
209
if (strstr (glxExtensions, "GLX_MESA_copy_sub_buffer"))
210
GL::copySubBuffer = (GL::GLXCopySubBufferProc)
211
getProcAddress ("glXCopySubBufferMESA");
213
if (strstr (glxExtensions, "GLX_SGI_video_sync"))
215
GL::getVideoSync = (GL::GLXGetVideoSyncProc)
216
getProcAddress ("glXGetVideoSyncSGI");
218
GL::waitVideoSync = (GL::GLXWaitVideoSyncProc)
219
getProcAddress ("glXWaitVideoSyncSGI");
222
glXMakeCurrent (dpy, CompositeScreen::get (s)->output (), priv->ctx);
224
glExtensions = (const char *) glGetString (GL_EXTENSIONS);
227
compLogMessage ("opengl", CompLogLevelFatal,
228
"No valid GL extensions string found.");
233
if (strstr (glExtensions, "GL_ARB_texture_non_power_of_two"))
234
GL::textureNonPowerOfTwo = true;
236
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &GL::maxTextureSize);
238
if (strstr (glExtensions, "GL_NV_texture_rectangle") ||
239
strstr (glExtensions, "GL_EXT_texture_rectangle") ||
240
strstr (glExtensions, "GL_ARB_texture_rectangle"))
242
GL::textureRectangle = true;
244
if (!GL::textureNonPowerOfTwo)
246
GLint maxTextureSize;
248
glGetIntegerv (GL_MAX_RECTANGLE_TEXTURE_SIZE_NV, &maxTextureSize);
249
if (maxTextureSize > GL::maxTextureSize)
250
GL::maxTextureSize = maxTextureSize;
254
if (!(GL::textureRectangle || GL::textureNonPowerOfTwo))
256
compLogMessage ("opengl", CompLogLevelFatal,
257
"Support for non power of two textures missing");
262
if (strstr (glExtensions, "GL_ARB_texture_env_combine"))
264
GL::textureEnvCombine = true;
266
/* XXX: GL_NV_texture_env_combine4 need special code but it seams to
267
be working anyway for now... */
268
if (strstr (glExtensions, "GL_ARB_texture_env_crossbar") ||
269
strstr (glExtensions, "GL_NV_texture_env_combine4"))
270
GL::textureEnvCrossbar = true;
273
if (strstr (glExtensions, "GL_ARB_texture_border_clamp") ||
274
strstr (glExtensions, "GL_SGIS_texture_border_clamp"))
275
GL::textureBorderClamp = true;
277
GL::maxTextureUnits = 1;
278
if (strstr (glExtensions, "GL_ARB_multitexture"))
280
GL::activeTexture = (GL::GLActiveTextureProc)
281
getProcAddress ("glActiveTexture");
282
GL::clientActiveTexture = (GL::GLClientActiveTextureProc)
283
getProcAddress ("glClientActiveTexture");
284
GL::multiTexCoord2f = (GL::GLMultiTexCoord2fProc)
285
getProcAddress ("glMultiTexCoord2f");
287
if (GL::activeTexture && GL::clientActiveTexture && GL::multiTexCoord2f)
288
glGetIntegerv (GL_MAX_TEXTURE_UNITS_ARB, &GL::maxTextureUnits);
291
if (strstr (glExtensions, "GL_ARB_fragment_program"))
293
GL::genPrograms = (GL::GLGenProgramsProc)
294
getProcAddress ("glGenProgramsARB");
295
GL::deletePrograms = (GL::GLDeleteProgramsProc)
296
getProcAddress ("glDeleteProgramsARB");
297
GL::bindProgram = (GL::GLBindProgramProc)
298
getProcAddress ("glBindProgramARB");
299
GL::programString = (GL::GLProgramStringProc)
300
getProcAddress ("glProgramStringARB");
301
GL::programEnvParameter4f = (GL::GLProgramParameter4fProc)
302
getProcAddress ("glProgramEnvParameter4fARB");
303
GL::programLocalParameter4f = (GL::GLProgramParameter4fProc)
304
getProcAddress ("glProgramLocalParameter4fARB");
305
GL::getProgramiv = (GL::GLGetProgramivProc)
306
getProcAddress ("glGetProgramivARB");
308
if (GL::genPrograms &&
309
GL::deletePrograms &&
312
GL::programEnvParameter4f &&
313
GL::programLocalParameter4f &&
315
GL::fragmentProgram = true;
318
if (strstr (glExtensions, "GL_EXT_framebuffer_object"))
320
GL::genFramebuffers = (GL::GLGenFramebuffersProc)
321
getProcAddress ("glGenFramebuffersEXT");
322
GL::deleteFramebuffers = (GL::GLDeleteFramebuffersProc)
323
getProcAddress ("glDeleteFramebuffersEXT");
324
GL::bindFramebuffer = (GL::GLBindFramebufferProc)
325
getProcAddress ("glBindFramebufferEXT");
326
GL::checkFramebufferStatus = (GL::GLCheckFramebufferStatusProc)
327
getProcAddress ("glCheckFramebufferStatusEXT");
328
GL::framebufferTexture2D = (GL::GLFramebufferTexture2DProc)
329
getProcAddress ("glFramebufferTexture2DEXT");
330
GL::generateMipmap = (GL::GLGenerateMipmapProc)
331
getProcAddress ("glGenerateMipmapEXT");
333
if (GL::genFramebuffers &&
334
GL::deleteFramebuffers &&
335
GL::bindFramebuffer &&
336
GL::checkFramebufferStatus &&
337
GL::framebufferTexture2D &&
342
if (strstr (glExtensions, "GL_ARB_texture_compression"))
343
GL::textureCompression = true;
345
fbConfigs = (*GL::getFBConfigs) (dpy, s->screenNum (), &nElements);
347
for (i = 0; i <= MAX_DEPTH; i++)
349
int j, db, stencil, depth, alpha, mipmap, rgba;
351
priv->glxPixmapFBConfigs[i].fbConfig = NULL;
352
priv->glxPixmapFBConfigs[i].mipmap = 0;
353
priv->glxPixmapFBConfigs[i].yInverted = 0;
354
priv->glxPixmapFBConfigs[i].textureFormat = 0;
355
priv->glxPixmapFBConfigs[i].textureTargets = 0;
363
for (j = 0; j < nElements; j++)
368
vi = glXGetVisualFromFBConfig (dpy, fbConfigs[j]);
372
visualDepth = vi->depth;
376
if (visualDepth != i)
379
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
380
GLX_ALPHA_SIZE, &alpha);
381
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
382
GLX_BUFFER_SIZE, &value);
383
if (value != i && (value - alpha) != i)
389
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
390
GLX_BIND_TO_TEXTURE_RGBA_EXT, &value);
396
priv->glxPixmapFBConfigs[i].textureFormat =
397
GLX_TEXTURE_FORMAT_RGBA_EXT;
406
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
407
GLX_BIND_TO_TEXTURE_RGB_EXT, &value);
411
priv->glxPixmapFBConfigs[i].textureFormat =
412
GLX_TEXTURE_FORMAT_RGB_EXT;
415
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
416
GLX_DOUBLEBUFFER, &value);
422
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
423
GLX_STENCIL_SIZE, &value);
429
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
430
GLX_DEPTH_SIZE, &value);
438
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
439
GLX_BIND_TO_MIPMAP_TEXTURE_EXT,
447
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
448
GLX_Y_INVERTED_EXT, &value);
450
priv->glxPixmapFBConfigs[i].yInverted = value;
452
(*GL::getFBConfigAttrib) (dpy, fbConfigs[j],
453
GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value);
455
priv->glxPixmapFBConfigs[i].textureTargets = value;
457
priv->glxPixmapFBConfigs[i].fbConfig = fbConfigs[j];
458
priv->glxPixmapFBConfigs[i].mipmap = mipmap;
465
if (!priv->glxPixmapFBConfigs[defaultDepth].fbConfig)
467
compLogMessage ("opengl", CompLogLevelFatal,
468
"No GLXFBConfig for default depth, "
469
"this isn't going to work.");
474
glClearColor (0.0, 0.0, 0.0, 1.0);
475
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
476
glEnable (GL_CULL_FACE);
477
glDisable (GL_BLEND);
478
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
479
glColor4usv (defaultColor);
480
glEnableClientState (GL_VERTEX_ARRAY);
481
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
483
if (GL::textureEnvCombine && GL::maxTextureUnits >= 2)
485
GL::canDoSaturated = true;
486
if (GL::textureEnvCrossbar && GL::maxTextureUnits >= 4)
487
GL::canDoSlightlySaturated = true;
492
glLightModelfv (GL_LIGHT_MODEL_AMBIENT, globalAmbient);
494
glEnable (GL_LIGHT0);
495
glLightfv (GL_LIGHT0, GL_AMBIENT, ambientLight);
496
glLightfv (GL_LIGHT0, GL_DIFFUSE, diffuseLight);
497
glLightfv (GL_LIGHT0, GL_POSITION, light0Position);
499
glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
501
glNormal3f (0.0f, 0.0f, -1.0f);
503
priv->lighting = false;
506
priv->filter[NOTHING_TRANS_FILTER] = GLTexture::Fast;
507
priv->filter[SCREEN_TRANS_FILTER] = GLTexture::Good;
508
priv->filter[WINDOW_TRANS_FILTER] = GLTexture::Good;
510
if (GL::textureFromPixmap)
511
registerBindPixmap (TfpTexture::bindPixmapToTexture);
515
GLScreen::~GLScreen ()
517
if (priv->hasCompositing)
518
CompositeScreen::get (screen)->unregisterPaintHandler ();
519
glXDestroyContext (screen->dpy (), priv->ctx);
523
PrivateGLScreen::PrivateGLScreen (GLScreen *gs) :
525
cScreen (CompositeScreen::get (screen)),
526
textureFilter (GL_LINEAR),
527
backgroundTextures (),
528
backgroundLoaded (false),
535
pendingCommands (false),
537
hasCompositing (false)
539
ScreenInterface::setHandler (screen);
542
PrivateGLScreen::~PrivateGLScreen ()
546
GLushort defaultColor[4] = { 0xffff, 0xffff, 0xffff, 0xffff };
551
GLScreen::textureFilter ()
553
return priv->textureFilter;
557
GLScreen::setTextureFilter (GLenum filter)
559
priv->textureFilter = filter;
563
PrivateGLScreen::handleEvent (XEvent *event)
567
screen->handleEvent (event);
569
switch (event->type) {
571
if (event->xproperty.atom == Atoms::xBackground[0] ||
572
event->xproperty.atom == Atoms::xBackground[1])
574
if (event->xproperty.window == screen->root ())
575
gScreen->updateBackground ();
577
else if (event->xproperty.atom == Atoms::winOpacity ||
578
event->xproperty.atom == Atoms::winBrightness ||
579
event->xproperty.atom == Atoms::winSaturation)
581
w = screen->findWindow (event->xproperty.window);
583
GLWindow::get (w)->updatePaintAttribs ();
585
else if (event->xproperty.atom == Atoms::wmIcon)
587
w = screen->findWindow (event->xproperty.window);
589
GLWindow::get (w)->priv->icons.clear ();
594
if (event->type == cScreen->damageEvent () + XDamageNotify)
596
XDamageNotifyEvent *de = (XDamageNotifyEvent *) event;
598
std::map<Damage, TfpTexture*>::iterator it =
599
boundPixmapTex.find (de->damage);
600
if (it != boundPixmapTex.end ())
602
it->second->damaged = true;
610
GLScreen::clearTargetOutput (unsigned int mask)
612
clearOutput (targetOutput, mask);
625
GLfloat x, y, a, b, c, d;
627
x = (2.0 * nearval) / (right - left);
628
y = (2.0 * nearval) / (top - bottom);
629
a = (right + left) / (right - left);
630
b = (top + bottom) / (top - bottom);
631
c = -(farval + nearval) / ( farval - nearval);
632
d = -(2.0 * farval * nearval) / (farval - nearval);
634
#define M(row,col) m[col*4+row]
635
M(0,0) = x; M(0,1) = 0.0f; M(0,2) = a; M(0,3) = 0.0f;
636
M(1,0) = 0.0f; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0f;
637
M(2,0) = 0.0f; M(2,1) = 0.0f; M(2,2) = c; M(2,3) = d;
638
M(3,0) = 0.0f; M(3,1) = 0.0f; M(3,2) = -1.0f; M(3,3) = 0.0f;
644
perspective (GLfloat *m,
650
GLfloat xmin, xmax, ymin, ymax;
652
ymax = zNear * tan (fovy * M_PI / 360.0);
654
xmin = ymin * aspect;
655
xmax = ymax * aspect;
657
frustum (m, xmin, xmax, ymin, ymax, zNear, zFar);
661
PrivateGLScreen::updateView ()
663
glMatrixMode (GL_PROJECTION);
665
glMatrixMode (GL_MODELVIEW);
668
glViewport (-1, -1, 2, 2);
669
glRasterPos2f (0, 0);
671
rasterPos = CompPoint (0, 0);
673
perspective (projection, 60.0f, 1.0f, 0.1f, 100.0f);
675
glMatrixMode (GL_PROJECTION);
677
glMultMatrixf (projection);
678
glMatrixMode (GL_MODELVIEW);
680
CompRegion region (screen->region ());
681
/* remove all output regions from visible screen region */
682
foreach (CompOutput &o, screen->outputDevs ())
685
/* we should clear color buffers before swapping if we have visible
686
regions without output */
687
clearBuffers = !region.isEmpty ();
689
gScreen->setDefaultViewport ();
693
PrivateGLScreen::outputChangeNotify ()
695
screen->outputChangeNotify ();
701
GLScreen::getProcAddress (const char *name)
703
static void *dlhand = NULL;
704
GL::FuncPtr funcPtr = NULL;
706
if (priv->getProcAddress)
707
funcPtr = priv->getProcAddress ((GLubyte *) name);
712
dlhand = dlopen ("libopengl.so", RTLD_LAZY);
717
funcPtr = (GL::FuncPtr) dlsym (dlhand, name);
718
if (dlerror () != NULL)
727
PrivateGLScreen::updateScreenBackground ()
729
Display *dpy = screen->dpy ();
730
Atom pixmapAtom, actualType;
731
int actualFormat, i, status;
732
unsigned int width = 1, height = 1, depth = 0;
733
unsigned long nItems;
734
unsigned long bytesAfter;
738
pixmapAtom = XInternAtom (dpy, "PIXMAP", FALSE);
740
for (i = 0; pixmap == 0 && i < 2; i++)
742
status = XGetWindowProperty (dpy, screen->root (),
743
Atoms::xBackground[i],
744
0, 4, FALSE, AnyPropertyType,
745
&actualType, &actualFormat, &nItems,
748
if (status == Success && nItems && prop)
750
if (actualType == pixmapAtom &&
751
actualFormat == 32 &&
756
memcpy (&p, prop, 4);
764
if (XGetGeometry (dpy, p, &w, &i, &i,
765
&width, &height, &ui, &depth))
767
if ((int) depth == screen->attrib ().depth)
780
GLTexture::bindPixmapToTexture (pixmap, width, height, depth);
781
if (backgroundTextures.empty ())
783
compLogMessage ("core", CompLogLevelWarn,
784
"Couldn't bind background pixmap 0x%x to "
785
"texture", (int) pixmap);
790
backgroundTextures.clear ();
793
if (backgroundTextures.empty () && backgroundImage)
796
CompString fileName (backgroundImage);
798
backgroundTextures = GLTexture::readImageToTexture (fileName, size);
801
if (!backgroundTextures.empty ())
803
foreach (GLTexture *t, backgroundTextures)
804
if (t->target () == GL_TEXTURE_2D)
806
glBindTexture (t->target (), t->name ());
807
glTexParameteri (t->target (), GL_TEXTURE_WRAP_S, GL_REPEAT);
808
glTexParameteri (t->target (), GL_TEXTURE_WRAP_T, GL_REPEAT);
809
glBindTexture (t->target (), 0);
815
GLScreen::setTexEnvMode (GLenum mode)
818
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
820
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
824
GLScreen::setLighting (bool lighting)
826
if (priv->lighting != lighting)
828
if (!priv->opt[GL_OPTION_LIGHTING].value ().b ())
833
glEnable (GL_COLOR_MATERIAL);
834
glEnable (GL_LIGHTING);
838
glDisable (GL_COLOR_MATERIAL);
839
glDisable (GL_LIGHTING);
842
priv->lighting = lighting;
844
setTexEnvMode (GL_REPLACE);
849
GLScreenInterface::glPaintOutput (const GLScreenPaintAttrib &sAttrib,
850
const GLMatrix &transform,
851
const CompRegion ®ion,
854
WRAPABLE_DEF (glPaintOutput, sAttrib, transform, region, output, mask)
857
GLScreenInterface::glPaintTransformedOutput (const GLScreenPaintAttrib &sAttrib,
858
const GLMatrix &transform,
859
const CompRegion ®ion,
862
WRAPABLE_DEF (glPaintTransformedOutput, sAttrib, transform, region,
866
GLScreenInterface::glApplyTransform (const GLScreenPaintAttrib &sAttrib,
869
WRAPABLE_DEF (glApplyTransform, sAttrib, output, transform)
872
GLScreenInterface::glEnableOutputClipping (const GLMatrix &transform,
873
const CompRegion ®ion,
875
WRAPABLE_DEF (glEnableOutputClipping, transform, region, output)
878
GLScreenInterface::glDisableOutputClipping ()
879
WRAPABLE_DEF (glDisableOutputClipping)
882
GLScreen::updateBackground ()
884
priv->backgroundTextures.clear ();
886
if (priv->backgroundLoaded)
888
priv->backgroundLoaded = false;
889
CompositeScreen::get (screen)->damageScreen ();
894
GLScreen::lighting ()
896
return priv->lighting;
900
GLScreen::filter (int filter)
902
return priv->filter[filter];
906
GLScreen::setFilter (int num, GLTexture::Filter filter)
908
priv->filter[num] = filter;
911
GLFragment::Storage *
912
GLScreen::fragmentStorage ()
914
return &priv->fragmentStorage;
918
GLScreen::glxPixmapFBConfig (unsigned int depth)
920
return &priv->glxPixmapFBConfigs[depth];
924
GLScreen::clearOutput (CompOutput *output,
927
BoxPtr pBox = &output->region ()->extents;
931
pBox->x2 != (int) screen->width () ||
932
pBox->y2 != (int) screen->height ())
934
glPushAttrib (GL_SCISSOR_BIT);
936
glEnable (GL_SCISSOR_TEST);
938
screen->height () - pBox->y2,
940
pBox->y2 - pBox->y1);
952
GLScreen::setDefaultViewport ()
954
priv->lastViewport.x = screen->outputDevs ()[0].x1 ();
955
priv->lastViewport.y = screen->height () -
956
screen->outputDevs ()[0].y2 ();
957
priv->lastViewport.width = screen->outputDevs ()[0].width ();
958
priv->lastViewport.height = screen->outputDevs ()[0].height ();
960
glViewport (priv->lastViewport.x,
961
priv->lastViewport.y,
962
priv->lastViewport.width,
963
priv->lastViewport.height);
967
PrivateGLScreen::waitForVideoSync ()
971
if (!opt[GL_OPTION_SYNC_TO_VBLANK].value ().b ())
974
if (GL::getVideoSync)
978
(*GL::getVideoSync) (&sync);
979
(*GL::waitVideoSync) (2, (sync + 1) % 2, &sync);
984
GLScreen::getOption (const char *name)
986
CompOption *o = CompOption::findOption (priv->opt, name);
991
PrivateGLScreen::paintOutputs (CompOutput::ptrList &outputs,
993
const CompRegion ®ion)
999
if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
1000
glClear (GL_COLOR_BUFFER_BIT);
1003
CompRegion tmpRegion (region);
1005
foreach (CompOutput *output, outputs)
1007
targetOutput = output;
1009
r.x = output->x1 ();
1010
r.y = screen->height () - output->y2 ();
1011
r.width = output->width ();
1012
r.height = output->height ();
1014
if (lastViewport.x != r.x ||
1015
lastViewport.y != r.y ||
1016
lastViewport.width != r.width ||
1017
lastViewport.height != r.height)
1019
glViewport (r.x, r.y, r.width, r.height);
1023
if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
1027
gScreen->glPaintOutput (defaultScreenPaintAttrib,
1029
CompRegion (*output), output,
1030
PAINT_SCREEN_REGION_MASK |
1031
PAINT_SCREEN_FULL_MASK);
1033
else if (mask & COMPOSITE_SCREEN_DAMAGE_REGION_MASK)
1037
outputRegion = tmpRegion & CompRegion (*output);
1039
if (!gScreen->glPaintOutput (defaultScreenPaintAttrib,
1041
outputRegion, output,
1042
PAINT_SCREEN_REGION_MASK))
1046
gScreen->glPaintOutput (defaultScreenPaintAttrib,
1048
CompRegion (*output), output,
1049
PAINT_SCREEN_FULL_MASK);
1051
tmpRegion += *output;
1057
targetOutput = &screen->outputDevs ()[0];
1059
waitForVideoSync ();
1061
if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
1063
glXSwapBuffers (screen->dpy (), cScreen->output ());
1070
pBox = const_cast <Region> (tmpRegion.handle ())->rects;
1071
nBox = const_cast <Region> (tmpRegion.handle ())->numRects;
1073
if (GL::copySubBuffer)
1077
y = screen->height () - pBox->y2;
1079
(*GL::copySubBuffer) (screen->dpy (), cScreen->output (),
1081
pBox->x2 - pBox->x1,
1082
pBox->y2 - pBox->y1);
1089
glEnable (GL_SCISSOR_TEST);
1090
glDrawBuffer (GL_FRONT);
1094
y = screen->height () - pBox->y2;
1096
glBitmap (0, 0, 0, 0,
1097
pBox->x1 - rasterPos.x (),
1101
rasterPos = CompPoint (pBox->x1, y);
1103
glScissor (pBox->x1, y,
1104
pBox->x2 - pBox->x1,
1105
pBox->y2 - pBox->y1);
1107
glCopyPixels (pBox->x1, y,
1108
pBox->x2 - pBox->x1,
1109
pBox->y2 - pBox->y1,
1115
glDrawBuffer (GL_BACK);
1116
glDisable (GL_SCISSOR_TEST);
1123
PrivateGLScreen::hasVSync ()
1125
return (GL::getVideoSync &&
1126
opt[GL_OPTION_SYNC_TO_VBLANK].value ().b ());
1130
PrivateGLScreen::prepareDrawing ()
1132
if (pendingCommands)
1135
pendingCommands = false;
1139
GLTexture::BindPixmapHandle
1140
GLScreen::registerBindPixmap (GLTexture::BindPixmapProc proc)
1142
priv->bindPixmap.push_back (proc);
1143
if (!priv->hasCompositing &&
1144
CompositeScreen::get (screen)->registerPaintHandler (priv))
1145
priv->hasCompositing = true;
1146
return priv->bindPixmap.size () - 1;
1150
GLScreen::unregisterBindPixmap (GLTexture::BindPixmapHandle hnd)
1153
priv->bindPixmap[hnd].clear ();
1154
for (unsigned int i = 0; i < priv->bindPixmap.size (); i++)
1155
if (!priv->bindPixmap[i].empty ())
1157
if (!hasBP && priv->hasCompositing)
1159
CompositeScreen::get (screen)->unregisterPaintHandler ();
1160
priv->hasCompositing = false;
1165
GLScreen::defaultIcon ()
1167
CompIcon *i = screen->defaultIcon ();
1173
if (!i->width () || !i->height ())
1176
if (priv->defaultIcon.icon == i)
1177
return priv->defaultIcon.textures[0];
1179
priv->defaultIcon.textures =
1180
GLTexture::imageBufferToTexture ((char *) i->data (), *i);
1182
if (priv->defaultIcon.textures.size () == 1)
1183
priv->defaultIcon.icon = i;
1186
priv->defaultIcon.icon = NULL;
1187
priv->defaultIcon.textures.clear ();
1190
return priv->defaultIcon.textures[0];
1194
GLScreen::resetRasterPos ()
1196
glRasterPos2f (0, 0);
1197
priv->rasterPos.setX (0);
1198
priv->rasterPos.setY (0);
1202
GLScreen::projectionMatrix ()
1204
return priv->projection;