ROOT logo
// @(#)root/gl:$Id$
// Author: Timur Pocheptsov (TX11GLManager) / Valeriy Onuchin (TX11GL)

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <deque>
#include <map>
#include <stdlib.h>
#include <string.h>

#include "TVirtualViewer3D.h"
#include "TVirtualX.h"
#include "TGLViewer.h"
#include "TGLManip.h"
#include "TX11GL.h"
#include "TError.h"
#include "TROOT.h"

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TX11GLManager                                                        //
//                                                                      //
// The TX11GLManager is X11 implementation of TGLManager.               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

struct TX11GLManager::TGLContext_t {
   //these are numbers returned by gVirtualX->AddWindow and gVirtualX->AddPixmap
   TGLContext_t() : fWindowIndex(-1), fPixmapIndex(-1), fX11Pixmap(0), fW(0),
                  fH(0), fX(0), fY(0), fGLXContext(0), fDirect(kFALSE),
                  fXImage(0), fNextFreeContext(0), fDirectGC(0), fPixmapGC(0)
   {
   }//FIXME
   Int_t                fWindowIndex;
   Int_t                fPixmapIndex;
   //X11 pixmap
   Pixmap               fX11Pixmap;
   //
   UInt_t               fW;
   UInt_t               fH;
   //
   Int_t                fX;
   Int_t                fY;
   //
   GLXContext           fGLXContext;
   Bool_t               fDirect;
   //GL buffer is read into XImage
   XImage              *fXImage;
   std::vector<UChar_t> fBUBuffer;//gl buffer is read from bottom to top.
   //
   TGLContext_t        *fNextFreeContext;
   GC                   fDirectGC;
   GC                   fPixmapGC;
};

namespace {

   typedef std::deque<TX11GLManager::TGLContext_t> DeviceTable_t;
   typedef DeviceTable_t::size_type SizeType_t;
   typedef std::map<Int_t, XVisualInfo *> WinTable_t;
   XSetWindowAttributes dummyAttr;

   //RAII class for Pixmap
   class TX11PixGuard {
   private:
      Display *fDpy;
      Pixmap   fPix;

   public:
      TX11PixGuard(Display *dpy, Pixmap pix) : fDpy(dpy), fPix(pix) {}
      ~TX11PixGuard(){if (fPix) XFreePixmap(fDpy, fPix);}
      void Stop(){fPix = 0;}

   private:
      TX11PixGuard(const TX11PixGuard &);
      TX11PixGuard &operator = (const TX11PixGuard &);
   };

   //RAII class for GLXContext
   class TGLXCtxGuard {
   private:
      Display    *fDpy;
      GLXContext  fCtx;

   public:
      TGLXCtxGuard(Display *dpy, GLXContext ctx) : fDpy(dpy), fCtx(ctx) {}
      ~TGLXCtxGuard(){if (fCtx) glXDestroyContext(fDpy, fCtx);}
      void Stop(){fCtx = 0;}

   private:
      TGLXCtxGuard(const TGLXCtxGuard &);
      TGLXCtxGuard &operator = (const TGLXCtxGuard &);
   };

   // RAII class for XImage.
   class TXImageGuard {
   private:
      XImage *fImage;

      TXImageGuard(const TXImageGuard &);
      TXImageGuard &operator = (const TXImageGuard &);

   public:
      explicit TXImageGuard(XImage *im) : fImage(im) {}
      ~TXImageGuard(){if (fImage) XDestroyImage(fImage);}
      void Stop(){fImage = 0;}
   };

}

// Attriblist for glXChooseVisual (double-buffered visual).
const Int_t dblBuff[] =
   {
      GLX_DOUBLEBUFFER,
      GLX_RGBA,
      GLX_DEPTH_SIZE, 16,
      GLX_STENCIL_SIZE, 8,
      GLX_RED_SIZE, 1,
      GLX_GREEN_SIZE, 1,
      GLX_BLUE_SIZE, 1,
      None
   };

// Attriblist for glxChooseVisual (single-buffered visual).
const Int_t *snglBuff = dblBuff + 1;

class TX11GLManager::TX11GLImpl {
public:
   TX11GLImpl();
   ~TX11GLImpl();

   WinTable_t      fGLWindows;
   DeviceTable_t   fGLContexts;
   Display        *fDpy;
   TGLContext_t     *fNextFreeContext;

private:
   TX11GLImpl(const TX11GLImpl &);
   TX11GLImpl &operator = (const TX11GLImpl &);
};


ClassImp(TX11GLManager)


//______________________________________________________________________________
TX11GLManager::TX11GLImpl::TX11GLImpl() : fDpy(0), fNextFreeContext(0)
{
   // Constructor.

   fDpy = reinterpret_cast<Display *>(gVirtualX->GetDisplay());
}


//______________________________________________________________________________
TX11GLManager::TX11GLImpl::~TX11GLImpl()
{
   // Destructor.
   // Destroys only GL contexts and XImages pixmaps and windows must be
   // closed through gVirtualX

   for (SizeType_t i = 0,  e = fGLContexts.size(); i < e; ++i) {
      TGLContext_t &ctx = fGLContexts[i];

      if (ctx.fGLXContext) {
         ::Warning("TX11GLManager::~TX11GLManager", "opengl device with index %ld was not destroyed", (Long_t)i);
         glXDestroyContext(fDpy, ctx.fGLXContext);

         if (ctx.fPixmapIndex != -1) {
            gVirtualX->SelectWindow(ctx.fPixmapIndex);
            gVirtualX->ClosePixmap();
            if (ctx.fXImage)
               XDestroyImage(ctx.fXImage);
         }
      }
   }
}


//______________________________________________________________________________
TX11GLManager::TX11GLManager() : fPimpl(new TX11GLImpl)
{
   // Constructor.

   gGLManager = this;
   gROOT->GetListOfSpecials()->Add(this);
}


//______________________________________________________________________________
TX11GLManager::~TX11GLManager()
{
   // Destructor.

   delete fPimpl;
}


//______________________________________________________________________________
Int_t TX11GLManager::InitGLWindow(Window_t winID)
{
   // Try to find correct visual.

   XVisualInfo *visInfo = glXChooseVisual(
                                          fPimpl->fDpy, DefaultScreen(fPimpl->fDpy),
                                          const_cast<Int_t *>(dblBuff)
                                         );

   if (!visInfo) {
      Error("InitGLWindow", "No good visual found!\n");
      return -1;
   }

   Int_t  x = 0, y = 0;
   UInt_t w = 0, h = 0, b = 0, d = 0;
   Window root = 0;
   XGetGeometry(fPimpl->fDpy, winID, &root, &x, &y, &w, &h, &b, &d);

   XSetWindowAttributes attr(dummyAttr);
   attr.colormap = XCreateColormap(fPimpl->fDpy, root, visInfo->visual, AllocNone); // ???
   attr.event_mask = NoEventMask;
   attr.backing_store = Always;
   attr.bit_gravity = NorthWestGravity;

   ULong_t mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWBackingStore | CWBitGravity;

   // Create window with specific visual.
   Window glWin = XCreateWindow(
                                fPimpl->fDpy, winID,
                                x, y, w, h,
                                0, visInfo->depth, InputOutput,
                                visInfo->visual, mask, &attr
                               );

   // Check results.
   XMapWindow(fPimpl->fDpy, glWin);

   // Register window for gVirtualX.
   Int_t x11Ind = gVirtualX->AddWindow(glWin,  w, h);

   // Register this window for GL manager.
   fPimpl->fGLWindows[x11Ind] = visInfo;

   return x11Ind;
}


//______________________________________________________________________________
Int_t TX11GLManager::CreateGLContext(Int_t winInd)
{
   // Context creation requires Display * and XVisualInfo
   // (was saved for such winInd).
   GLXContext glxCtx = glXCreateContext(fPimpl->fDpy, fPimpl->fGLWindows[winInd], None, True);

   if (!glxCtx) {
      Error("CreateContext", "glXCreateContext failed\n");
      return -1;
   }

   // Register new context now.
   if (TGLContext_t *ctx = fPimpl->fNextFreeContext) {
      Int_t ind = ctx->fWindowIndex;
      ctx->fWindowIndex = winInd;
      ctx->fGLXContext = glxCtx;
      fPimpl->fNextFreeContext = fPimpl->fNextFreeContext->fNextFreeContext;
      return ind;
   } else {
      TGLXCtxGuard glxCtxGuard(fPimpl->fDpy, glxCtx);
      TGLContext_t newDev;
      newDev.fWindowIndex = winInd;
      newDev.fGLXContext = glxCtx;

      fPimpl->fGLContexts.push_back(newDev);
      glxCtxGuard.Stop();

      return Int_t(fPimpl->fGLContexts.size()) - 1;
   }
}


//______________________________________________________________________________
Bool_t TX11GLManager::MakeCurrent(Int_t ctxInd)
{
   // Make GL context current.
   TGLContext_t &ctx = fPimpl->fGLContexts[ctxInd];
   return glXMakeCurrent(fPimpl->fDpy, gVirtualX->GetWindowID(ctx.fWindowIndex), ctx.fGLXContext);
}


//______________________________________________________________________________
void TX11GLManager::Flush(Int_t ctxInd)
{
   // Swaps buffers or copy pixmap.

   TGLContext_t &ctx = fPimpl->fGLContexts[ctxInd];
   Window winID = gVirtualX->GetWindowID(ctx.fWindowIndex);

   if (ctx.fPixmapIndex == -1)
      glXSwapBuffers(fPimpl->fDpy, winID);
   else if (ctx.fXImage && ctx.fDirect) {
      if (!ctx.fDirectGC)
         ctx.fDirectGC = XCreateGC(fPimpl->fDpy, winID, 0, 0);

      if (!ctx.fDirectGC) {
         Error("Flush", "XCreateGC failed while copying pixmap\n");
         ctx.fDirect = kFALSE;
         return;
      }

      XCopyArea(fPimpl->fDpy, ctx.fX11Pixmap, winID, ctx.fDirectGC, 0, 0, ctx.fW, ctx.fH, ctx.fX, ctx.fY);
   }
}


//______________________________________________________________________________
Bool_t TX11GLManager::CreateGLPixmap(TGLContext_t &ctx)
{
   // Create GL pixmap.

   // Create new x11 pixmap and XImage.
   Pixmap x11Pix = XCreatePixmap(fPimpl->fDpy, gVirtualX->GetWindowID(ctx.fWindowIndex), ctx.fW,
                                 ctx.fH, fPimpl->fGLWindows[ctx.fWindowIndex]->depth);

   if (!x11Pix) {
      Error("CreateGLPixmap", "XCreatePixmap failed\n");
      return kFALSE;
   }

   TX11PixGuard pixGuard(fPimpl->fDpy, x11Pix);

   // XImage part here.
   XVisualInfo *visInfo = fPimpl->fGLWindows[ctx.fWindowIndex];
   XImage *testIm = XCreateImage(fPimpl->fDpy, visInfo->visual, visInfo->depth, ZPixmap, 0, 0, ctx.fW, ctx.fH, 32, 0);

   if (testIm) {
      TXImageGuard imGuard(testIm);
      testIm->data = static_cast<Char_t *>(malloc(testIm->bytes_per_line * testIm->height));

      if (!testIm->data) {
         Error("CreateGLPixmap", "Cannot malloc XImage data\n");
         return kFALSE;
      }

      if (XInitImage(testIm)) {
         ctx.fPixmapIndex = gVirtualX->AddPixmap(x11Pix, ctx.fW, ctx.fH);
         ctx.fBUBuffer.resize(testIm->bytes_per_line * testIm->height);
         ctx.fX11Pixmap = x11Pix;
         ctx.fXImage = testIm;
         pixGuard.Stop();
         imGuard.Stop();
         return kTRUE;
      } else
         Error("CreateGLPixmap", "XInitImage error!\n");
   } else
      Error("CreateGLPixmap", "XCreateImage error!\n");

   return kFALSE;
}


//______________________________________________________________________________
Bool_t TX11GLManager::AttachOffScreenDevice(Int_t ctxInd, Int_t x, Int_t y, UInt_t w, UInt_t h)
{
   // Attach off screen device.

   // Create pixmap and XImage for GL context ctxInd.
   TGLContext_t &ctx = fPimpl->fGLContexts[ctxInd];
   TGLContext_t newCtx;
   newCtx.fWindowIndex = ctx.fWindowIndex;
   newCtx.fW = w, newCtx.fH = h, newCtx.fX = x, newCtx.fY = y;
   newCtx.fGLXContext = ctx.fGLXContext;

   if (CreateGLPixmap(newCtx)) {
      ctx.fPixmapIndex = newCtx.fPixmapIndex;
      ctx.fX11Pixmap = newCtx.fX11Pixmap;
      ctx.fW = w, ctx.fH = h, ctx.fX = x, ctx.fY = y;
      ctx.fDirect = kFALSE;
      ctx.fXImage = newCtx.fXImage;
      ctx.fBUBuffer.swap(newCtx.fBUBuffer);
      return kTRUE;
   }

   return kFALSE;
}


//______________________________________________________________________________
Bool_t TX11GLManager::ResizeOffScreenDevice(Int_t ctxInd, Int_t x, Int_t y, UInt_t w, UInt_t h)
{
   // Resize off screen devive.

   // Create a new pixmap and a new XImage if needed.
   TGLContext_t &ctx = fPimpl->fGLContexts[ctxInd];

   if (ctx.fPixmapIndex != -1) {
      if (TMath::Abs(Int_t(w) - Int_t(ctx.fW)) > 1 || TMath::Abs(Int_t(h) - Int_t(ctx.fH)) > 1) {
         TGLContext_t newCtx;
         newCtx.fWindowIndex = ctx.fWindowIndex;
         newCtx.fW = w, newCtx.fH = h, newCtx.fX = x, newCtx.fY = y;
         newCtx.fGLXContext = ctx.fGLXContext;

         if (CreateGLPixmap(newCtx)) {
            gVirtualX->SelectWindow(ctx.fPixmapIndex);
            gVirtualX->ClosePixmap();
            ctx.fPixmapIndex = newCtx.fPixmapIndex;
            ctx.fX11Pixmap = newCtx.fX11Pixmap;
            ctx.fW = w, ctx.fH = h, ctx.fX = x, ctx.fY = y;
            ctx.fDirect = kFALSE;
            if (ctx.fXImage) XDestroyImage(ctx.fXImage);
            ctx.fXImage = newCtx.fXImage;
            ctx.fBUBuffer.swap(newCtx.fBUBuffer);
            return kTRUE;
         } else
            Error("ResizeOffScreenDevice", "Resize failed\n");
      } else {
         ctx.fX = x;
         ctx.fY = y;
      }
   }

   return kFALSE;
}


//______________________________________________________________________________
void TX11GLManager::SelectOffScreenDevice(Int_t ctxInd)
{
   // Selects off-screen device to make it accessible by gVirtualX.

   gVirtualX->SelectWindow(fPimpl->fGLContexts[ctxInd].fPixmapIndex);
}


//______________________________________________________________________________
void TX11GLManager::MarkForDirectCopy(Int_t ctxInd, Bool_t dir)
{
   // Selection-rotation support for TPad/TCanvas.

   if (fPimpl->fGLContexts[ctxInd].fPixmapIndex != -1)
      fPimpl->fGLContexts[ctxInd].fDirect = dir;
}


//______________________________________________________________________________
void TX11GLManager::ReadGLBuffer(Int_t ctxInd)
{
   // GL buffer is read info buffer, after that lines are reordered
   // into XImage, XImage copied into pixmap.

   TGLContext_t &ctx = fPimpl->fGLContexts[ctxInd];

   if (ctx.fPixmapIndex != -1 && ctx.fXImage) {
      // Read GL buffer.
      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
      glReadBuffer(GL_BACK);
      glReadPixels(0, 0, ctx.fW, ctx.fH, GL_BGRA, GL_UNSIGNED_BYTE, &ctx.fBUBuffer[0]);

      if (!ctx.fPixmapGC)
         ctx.fPixmapGC = XCreateGC(fPimpl->fDpy, ctx.fX11Pixmap, 0, 0);
      if (ctx.fPixmapGC) {
         // GL buffer read operation gives bottom-up order of pixels, but XImage
         // require top-down. So, change RGB lines first.
         char *dest = ctx.fXImage->data;
         const UChar_t *src = &ctx.fBUBuffer[ctx.fW * 4 * (ctx.fH - 1)];
         for (UInt_t i = 0, e = ctx.fH; i < e; ++i) {
            memcpy(dest, src, ctx.fW * 4);
            dest += ctx.fW * 4;
            src -= ctx.fW * 4;
         }
         XPutImage(fPimpl->fDpy, ctx.fX11Pixmap, ctx.fPixmapGC, ctx.fXImage, 0, 0, 0, 0, ctx.fW, ctx.fH);
      } else
         Error("ReadGLBuffer", "XCreateGC error while attempt to copy XImage\n");
   }
}


//______________________________________________________________________________
void TX11GLManager::DeleteGLContext(Int_t ctxInd)
{
   // Deletes GLX context and frees pixmap and image (if any).

   TGLContext_t &ctx = fPimpl->fGLContexts[ctxInd];

   // Free GL context.
   glXDestroyContext(fPimpl->fDpy, ctx.fGLXContext);
   ctx.fGLXContext = 0;

   // If the pixmap exists it is destroyed.
   if (ctx.fPixmapIndex != -1) {
      gVirtualX->SelectWindow(ctx.fPixmapIndex);
      gVirtualX->ClosePixmap();
      ctx.fPixmapIndex = -1;
      if(ctx.fXImage) {
         XDestroyImage(ctx.fXImage);
         ctx.fXImage = 0;
      }
      if (ctx.fDirectGC)
         XFreeGC(fPimpl->fDpy, ctx.fDirectGC), ctx.fDirectGC = 0;
      if (ctx.fPixmapGC)
         XFreeGC(fPimpl->fDpy, ctx.fPixmapGC), ctx.fPixmapGC = 0;
   }

   ctx.fNextFreeContext = fPimpl->fNextFreeContext;
   fPimpl->fNextFreeContext = &ctx;
   ctx.fWindowIndex = ctxInd;
}


//______________________________________________________________________________
Int_t TX11GLManager::GetVirtualXInd(Int_t ctxInd)
{
   // Returns an index suitable for gVirtualX.

   return fPimpl->fGLContexts[ctxInd].fPixmapIndex;
}


//______________________________________________________________________________
void TX11GLManager::ExtractViewport(Int_t ctxInd, Int_t *viewport)
{
   // Returns the current dimensions of a GL pixmap.

   TGLContext_t &ctx = fPimpl->fGLContexts[ctxInd];

   if (ctx.fPixmapIndex != -1) {
      viewport[0] = 0;
      viewport[1] = 0;
      viewport[2] = ctx.fW;
      viewport[3] = ctx.fH;
   }
}


//______________________________________________________________________________
void TX11GLManager::PaintSingleObject(TVirtualGLPainter *p)
{
   // Paint a single object.

   p->Paint();
}


//______________________________________________________________________________
void TX11GLManager::PrintViewer(TVirtualViewer3D *vv)
{
   // Print viewer.

   vv->PrintObjects();
}

//______________________________________________________________________________
Bool_t TX11GLManager::SelectManip(TVirtualGLManip *manip, const TGLCamera * camera, const TGLRect * rect, const TGLBoundingBox * sceneBox)
{
   // Select manipulator.

   return manip->Select(*camera, *rect, *sceneBox);
}


//______________________________________________________________________________
void TX11GLManager::PanObject(TVirtualGLPainter *o, Int_t x, Int_t y)
{
   // Pan objects.

   return o->Pan(x, y);
}

//______________________________________________________________________________
Bool_t TX11GLManager::PlotSelected(TVirtualGLPainter *plot, Int_t px, Int_t py)
{
   //Analog of TObject::DistancetoPrimitive
   return plot->PlotSelected(px, py);
}

//______________________________________________________________________________
char *TX11GLManager::GetPlotInfo(TVirtualGLPainter *plot, Int_t px, Int_t py)
{
   //Analog of TObject::GetObjectInfo
   return plot->GetPlotInfo(px, py);
}
 TX11GL.cxx:1
 TX11GL.cxx:2
 TX11GL.cxx:3
 TX11GL.cxx:4
 TX11GL.cxx:5
 TX11GL.cxx:6
 TX11GL.cxx:7
 TX11GL.cxx:8
 TX11GL.cxx:9
 TX11GL.cxx:10
 TX11GL.cxx:11
 TX11GL.cxx:12
 TX11GL.cxx:13
 TX11GL.cxx:14
 TX11GL.cxx:15
 TX11GL.cxx:16
 TX11GL.cxx:17
 TX11GL.cxx:18
 TX11GL.cxx:19
 TX11GL.cxx:20
 TX11GL.cxx:21
 TX11GL.cxx:22
 TX11GL.cxx:23
 TX11GL.cxx:24
 TX11GL.cxx:25
 TX11GL.cxx:26
 TX11GL.cxx:27
 TX11GL.cxx:28
 TX11GL.cxx:29
 TX11GL.cxx:30
 TX11GL.cxx:31
 TX11GL.cxx:32
 TX11GL.cxx:33
 TX11GL.cxx:34
 TX11GL.cxx:35
 TX11GL.cxx:36
 TX11GL.cxx:37
 TX11GL.cxx:38
 TX11GL.cxx:39
 TX11GL.cxx:40
 TX11GL.cxx:41
 TX11GL.cxx:42
 TX11GL.cxx:43
 TX11GL.cxx:44
 TX11GL.cxx:45
 TX11GL.cxx:46
 TX11GL.cxx:47
 TX11GL.cxx:48
 TX11GL.cxx:49
 TX11GL.cxx:50
 TX11GL.cxx:51
 TX11GL.cxx:52
 TX11GL.cxx:53
 TX11GL.cxx:54
 TX11GL.cxx:55
 TX11GL.cxx:56
 TX11GL.cxx:57
 TX11GL.cxx:58
 TX11GL.cxx:59
 TX11GL.cxx:60
 TX11GL.cxx:61
 TX11GL.cxx:62
 TX11GL.cxx:63
 TX11GL.cxx:64
 TX11GL.cxx:65
 TX11GL.cxx:66
 TX11GL.cxx:67
 TX11GL.cxx:68
 TX11GL.cxx:69
 TX11GL.cxx:70
 TX11GL.cxx:71
 TX11GL.cxx:72
 TX11GL.cxx:73
 TX11GL.cxx:74
 TX11GL.cxx:75
 TX11GL.cxx:76
 TX11GL.cxx:77
 TX11GL.cxx:78
 TX11GL.cxx:79
 TX11GL.cxx:80
 TX11GL.cxx:81
 TX11GL.cxx:82
 TX11GL.cxx:83
 TX11GL.cxx:84
 TX11GL.cxx:85
 TX11GL.cxx:86
 TX11GL.cxx:87
 TX11GL.cxx:88
 TX11GL.cxx:89
 TX11GL.cxx:90
 TX11GL.cxx:91
 TX11GL.cxx:92
 TX11GL.cxx:93
 TX11GL.cxx:94
 TX11GL.cxx:95
 TX11GL.cxx:96
 TX11GL.cxx:97
 TX11GL.cxx:98
 TX11GL.cxx:99
 TX11GL.cxx:100
 TX11GL.cxx:101
 TX11GL.cxx:102
 TX11GL.cxx:103
 TX11GL.cxx:104
 TX11GL.cxx:105
 TX11GL.cxx:106
 TX11GL.cxx:107
 TX11GL.cxx:108
 TX11GL.cxx:109
 TX11GL.cxx:110
 TX11GL.cxx:111
 TX11GL.cxx:112
 TX11GL.cxx:113
 TX11GL.cxx:114
 TX11GL.cxx:115
 TX11GL.cxx:116
 TX11GL.cxx:117
 TX11GL.cxx:118
 TX11GL.cxx:119
 TX11GL.cxx:120
 TX11GL.cxx:121
 TX11GL.cxx:122
 TX11GL.cxx:123
 TX11GL.cxx:124
 TX11GL.cxx:125
 TX11GL.cxx:126
 TX11GL.cxx:127
 TX11GL.cxx:128
 TX11GL.cxx:129
 TX11GL.cxx:130
 TX11GL.cxx:131
 TX11GL.cxx:132
 TX11GL.cxx:133
 TX11GL.cxx:134
 TX11GL.cxx:135
 TX11GL.cxx:136
 TX11GL.cxx:137
 TX11GL.cxx:138
 TX11GL.cxx:139
 TX11GL.cxx:140
 TX11GL.cxx:141
 TX11GL.cxx:142
 TX11GL.cxx:143
 TX11GL.cxx:144
 TX11GL.cxx:145
 TX11GL.cxx:146
 TX11GL.cxx:147
 TX11GL.cxx:148
 TX11GL.cxx:149
 TX11GL.cxx:150
 TX11GL.cxx:151
 TX11GL.cxx:152
 TX11GL.cxx:153
 TX11GL.cxx:154
 TX11GL.cxx:155
 TX11GL.cxx:156
 TX11GL.cxx:157
 TX11GL.cxx:158
 TX11GL.cxx:159
 TX11GL.cxx:160
 TX11GL.cxx:161
 TX11GL.cxx:162
 TX11GL.cxx:163
 TX11GL.cxx:164
 TX11GL.cxx:165
 TX11GL.cxx:166
 TX11GL.cxx:167
 TX11GL.cxx:168
 TX11GL.cxx:169
 TX11GL.cxx:170
 TX11GL.cxx:171
 TX11GL.cxx:172
 TX11GL.cxx:173
 TX11GL.cxx:174
 TX11GL.cxx:175
 TX11GL.cxx:176
 TX11GL.cxx:177
 TX11GL.cxx:178
 TX11GL.cxx:179
 TX11GL.cxx:180
 TX11GL.cxx:181
 TX11GL.cxx:182
 TX11GL.cxx:183
 TX11GL.cxx:184
 TX11GL.cxx:185
 TX11GL.cxx:186
 TX11GL.cxx:187
 TX11GL.cxx:188
 TX11GL.cxx:189
 TX11GL.cxx:190
 TX11GL.cxx:191
 TX11GL.cxx:192
 TX11GL.cxx:193
 TX11GL.cxx:194
 TX11GL.cxx:195
 TX11GL.cxx:196
 TX11GL.cxx:197
 TX11GL.cxx:198
 TX11GL.cxx:199
 TX11GL.cxx:200
 TX11GL.cxx:201
 TX11GL.cxx:202
 TX11GL.cxx:203
 TX11GL.cxx:204
 TX11GL.cxx:205
 TX11GL.cxx:206
 TX11GL.cxx:207
 TX11GL.cxx:208
 TX11GL.cxx:209
 TX11GL.cxx:210
 TX11GL.cxx:211
 TX11GL.cxx:212
 TX11GL.cxx:213
 TX11GL.cxx:214
 TX11GL.cxx:215
 TX11GL.cxx:216
 TX11GL.cxx:217
 TX11GL.cxx:218
 TX11GL.cxx:219
 TX11GL.cxx:220
 TX11GL.cxx:221
 TX11GL.cxx:222
 TX11GL.cxx:223
 TX11GL.cxx:224
 TX11GL.cxx:225
 TX11GL.cxx:226
 TX11GL.cxx:227
 TX11GL.cxx:228
 TX11GL.cxx:229
 TX11GL.cxx:230
 TX11GL.cxx:231
 TX11GL.cxx:232
 TX11GL.cxx:233
 TX11GL.cxx:234
 TX11GL.cxx:235
 TX11GL.cxx:236
 TX11GL.cxx:237
 TX11GL.cxx:238
 TX11GL.cxx:239
 TX11GL.cxx:240
 TX11GL.cxx:241
 TX11GL.cxx:242
 TX11GL.cxx:243
 TX11GL.cxx:244
 TX11GL.cxx:245
 TX11GL.cxx:246
 TX11GL.cxx:247
 TX11GL.cxx:248
 TX11GL.cxx:249
 TX11GL.cxx:250
 TX11GL.cxx:251
 TX11GL.cxx:252
 TX11GL.cxx:253
 TX11GL.cxx:254
 TX11GL.cxx:255
 TX11GL.cxx:256
 TX11GL.cxx:257
 TX11GL.cxx:258
 TX11GL.cxx:259
 TX11GL.cxx:260
 TX11GL.cxx:261
 TX11GL.cxx:262
 TX11GL.cxx:263
 TX11GL.cxx:264
 TX11GL.cxx:265
 TX11GL.cxx:266
 TX11GL.cxx:267
 TX11GL.cxx:268
 TX11GL.cxx:269
 TX11GL.cxx:270
 TX11GL.cxx:271
 TX11GL.cxx:272
 TX11GL.cxx:273
 TX11GL.cxx:274
 TX11GL.cxx:275
 TX11GL.cxx:276
 TX11GL.cxx:277
 TX11GL.cxx:278
 TX11GL.cxx:279
 TX11GL.cxx:280
 TX11GL.cxx:281
 TX11GL.cxx:282
 TX11GL.cxx:283
 TX11GL.cxx:284
 TX11GL.cxx:285
 TX11GL.cxx:286
 TX11GL.cxx:287
 TX11GL.cxx:288
 TX11GL.cxx:289
 TX11GL.cxx:290
 TX11GL.cxx:291
 TX11GL.cxx:292
 TX11GL.cxx:293
 TX11GL.cxx:294
 TX11GL.cxx:295
 TX11GL.cxx:296
 TX11GL.cxx:297
 TX11GL.cxx:298
 TX11GL.cxx:299
 TX11GL.cxx:300
 TX11GL.cxx:301
 TX11GL.cxx:302
 TX11GL.cxx:303
 TX11GL.cxx:304
 TX11GL.cxx:305
 TX11GL.cxx:306
 TX11GL.cxx:307
 TX11GL.cxx:308
 TX11GL.cxx:309
 TX11GL.cxx:310
 TX11GL.cxx:311
 TX11GL.cxx:312
 TX11GL.cxx:313
 TX11GL.cxx:314
 TX11GL.cxx:315
 TX11GL.cxx:316
 TX11GL.cxx:317
 TX11GL.cxx:318
 TX11GL.cxx:319
 TX11GL.cxx:320
 TX11GL.cxx:321
 TX11GL.cxx:322
 TX11GL.cxx:323
 TX11GL.cxx:324
 TX11GL.cxx:325
 TX11GL.cxx:326
 TX11GL.cxx:327
 TX11GL.cxx:328
 TX11GL.cxx:329
 TX11GL.cxx:330
 TX11GL.cxx:331
 TX11GL.cxx:332
 TX11GL.cxx:333
 TX11GL.cxx:334
 TX11GL.cxx:335
 TX11GL.cxx:336
 TX11GL.cxx:337
 TX11GL.cxx:338
 TX11GL.cxx:339
 TX11GL.cxx:340
 TX11GL.cxx:341
 TX11GL.cxx:342
 TX11GL.cxx:343
 TX11GL.cxx:344
 TX11GL.cxx:345
 TX11GL.cxx:346
 TX11GL.cxx:347
 TX11GL.cxx:348
 TX11GL.cxx:349
 TX11GL.cxx:350
 TX11GL.cxx:351
 TX11GL.cxx:352
 TX11GL.cxx:353
 TX11GL.cxx:354
 TX11GL.cxx:355
 TX11GL.cxx:356
 TX11GL.cxx:357
 TX11GL.cxx:358
 TX11GL.cxx:359
 TX11GL.cxx:360
 TX11GL.cxx:361
 TX11GL.cxx:362
 TX11GL.cxx:363
 TX11GL.cxx:364
 TX11GL.cxx:365
 TX11GL.cxx:366
 TX11GL.cxx:367
 TX11GL.cxx:368
 TX11GL.cxx:369
 TX11GL.cxx:370
 TX11GL.cxx:371
 TX11GL.cxx:372
 TX11GL.cxx:373
 TX11GL.cxx:374
 TX11GL.cxx:375
 TX11GL.cxx:376
 TX11GL.cxx:377
 TX11GL.cxx:378
 TX11GL.cxx:379
 TX11GL.cxx:380
 TX11GL.cxx:381
 TX11GL.cxx:382
 TX11GL.cxx:383
 TX11GL.cxx:384
 TX11GL.cxx:385
 TX11GL.cxx:386
 TX11GL.cxx:387
 TX11GL.cxx:388
 TX11GL.cxx:389
 TX11GL.cxx:390
 TX11GL.cxx:391
 TX11GL.cxx:392
 TX11GL.cxx:393
 TX11GL.cxx:394
 TX11GL.cxx:395
 TX11GL.cxx:396
 TX11GL.cxx:397
 TX11GL.cxx:398
 TX11GL.cxx:399
 TX11GL.cxx:400
 TX11GL.cxx:401
 TX11GL.cxx:402
 TX11GL.cxx:403
 TX11GL.cxx:404
 TX11GL.cxx:405
 TX11GL.cxx:406
 TX11GL.cxx:407
 TX11GL.cxx:408
 TX11GL.cxx:409
 TX11GL.cxx:410
 TX11GL.cxx:411
 TX11GL.cxx:412
 TX11GL.cxx:413
 TX11GL.cxx:414
 TX11GL.cxx:415
 TX11GL.cxx:416
 TX11GL.cxx:417
 TX11GL.cxx:418
 TX11GL.cxx:419
 TX11GL.cxx:420
 TX11GL.cxx:421
 TX11GL.cxx:422
 TX11GL.cxx:423
 TX11GL.cxx:424
 TX11GL.cxx:425
 TX11GL.cxx:426
 TX11GL.cxx:427
 TX11GL.cxx:428
 TX11GL.cxx:429
 TX11GL.cxx:430
 TX11GL.cxx:431
 TX11GL.cxx:432
 TX11GL.cxx:433
 TX11GL.cxx:434
 TX11GL.cxx:435
 TX11GL.cxx:436
 TX11GL.cxx:437
 TX11GL.cxx:438
 TX11GL.cxx:439
 TX11GL.cxx:440
 TX11GL.cxx:441
 TX11GL.cxx:442
 TX11GL.cxx:443
 TX11GL.cxx:444
 TX11GL.cxx:445
 TX11GL.cxx:446
 TX11GL.cxx:447
 TX11GL.cxx:448
 TX11GL.cxx:449
 TX11GL.cxx:450
 TX11GL.cxx:451
 TX11GL.cxx:452
 TX11GL.cxx:453
 TX11GL.cxx:454
 TX11GL.cxx:455
 TX11GL.cxx:456
 TX11GL.cxx:457
 TX11GL.cxx:458
 TX11GL.cxx:459
 TX11GL.cxx:460
 TX11GL.cxx:461
 TX11GL.cxx:462
 TX11GL.cxx:463
 TX11GL.cxx:464
 TX11GL.cxx:465
 TX11GL.cxx:466
 TX11GL.cxx:467
 TX11GL.cxx:468
 TX11GL.cxx:469
 TX11GL.cxx:470
 TX11GL.cxx:471
 TX11GL.cxx:472
 TX11GL.cxx:473
 TX11GL.cxx:474
 TX11GL.cxx:475
 TX11GL.cxx:476
 TX11GL.cxx:477
 TX11GL.cxx:478
 TX11GL.cxx:479
 TX11GL.cxx:480
 TX11GL.cxx:481
 TX11GL.cxx:482
 TX11GL.cxx:483
 TX11GL.cxx:484
 TX11GL.cxx:485
 TX11GL.cxx:486
 TX11GL.cxx:487
 TX11GL.cxx:488
 TX11GL.cxx:489
 TX11GL.cxx:490
 TX11GL.cxx:491
 TX11GL.cxx:492
 TX11GL.cxx:493
 TX11GL.cxx:494
 TX11GL.cxx:495
 TX11GL.cxx:496
 TX11GL.cxx:497
 TX11GL.cxx:498
 TX11GL.cxx:499
 TX11GL.cxx:500
 TX11GL.cxx:501
 TX11GL.cxx:502
 TX11GL.cxx:503
 TX11GL.cxx:504
 TX11GL.cxx:505
 TX11GL.cxx:506
 TX11GL.cxx:507
 TX11GL.cxx:508
 TX11GL.cxx:509
 TX11GL.cxx:510
 TX11GL.cxx:511
 TX11GL.cxx:512
 TX11GL.cxx:513
 TX11GL.cxx:514
 TX11GL.cxx:515
 TX11GL.cxx:516
 TX11GL.cxx:517
 TX11GL.cxx:518
 TX11GL.cxx:519
 TX11GL.cxx:520
 TX11GL.cxx:521
 TX11GL.cxx:522
 TX11GL.cxx:523
 TX11GL.cxx:524
 TX11GL.cxx:525
 TX11GL.cxx:526
 TX11GL.cxx:527
 TX11GL.cxx:528
 TX11GL.cxx:529
 TX11GL.cxx:530
 TX11GL.cxx:531
 TX11GL.cxx:532
 TX11GL.cxx:533
 TX11GL.cxx:534
 TX11GL.cxx:535
 TX11GL.cxx:536
 TX11GL.cxx:537
 TX11GL.cxx:538
 TX11GL.cxx:539
 TX11GL.cxx:540
 TX11GL.cxx:541
 TX11GL.cxx:542
 TX11GL.cxx:543
 TX11GL.cxx:544
 TX11GL.cxx:545
 TX11GL.cxx:546
 TX11GL.cxx:547
 TX11GL.cxx:548
 TX11GL.cxx:549
 TX11GL.cxx:550
 TX11GL.cxx:551
 TX11GL.cxx:552
 TX11GL.cxx:553
 TX11GL.cxx:554
 TX11GL.cxx:555
 TX11GL.cxx:556
 TX11GL.cxx:557
 TX11GL.cxx:558
 TX11GL.cxx:559
 TX11GL.cxx:560
 TX11GL.cxx:561
 TX11GL.cxx:562
 TX11GL.cxx:563
 TX11GL.cxx:564
 TX11GL.cxx:565
 TX11GL.cxx:566
 TX11GL.cxx:567
 TX11GL.cxx:568
 TX11GL.cxx:569
 TX11GL.cxx:570
 TX11GL.cxx:571
 TX11GL.cxx:572
 TX11GL.cxx:573
 TX11GL.cxx:574
 TX11GL.cxx:575
 TX11GL.cxx:576
 TX11GL.cxx:577
 TX11GL.cxx:578
 TX11GL.cxx:579
 TX11GL.cxx:580
 TX11GL.cxx:581
 TX11GL.cxx:582
 TX11GL.cxx:583
 TX11GL.cxx:584
 TX11GL.cxx:585
 TX11GL.cxx:586