~azzar1/nux/fix-916088

« back to all changes in this revision

Viewing changes to NuxGraphics/GraphicsDisplayX11.cpp

  • Committer: Jay Taoko
  • Date: 2011-11-21 19:10:06 UTC
  • mfrom: (518.1.7 nux-fix-makecheck)
  • Revision ID: jay.taoko@canonical.com-20111121191006-cv93lu1vwk2wibkc
* Added requirement for XTest
* Fixed crash in GraphicsDisplay at program termination.
* Added Automated test Framework
* Added Testing framework
* Added empty program test
* Added Button test through XTest
* Added macros nuxOkMsg to NuxCore

Show diffs side-by-side

added added

removed removed

Lines of Context:
69
69
    , _x11_minor(0)
70
70
    , _glx_major(0)
71
71
    , _glx_minor(0)
72
 
    , _has_glx_13(false)
73
72
    , m_X11RepeatKey(true)
74
73
    , m_ViewportSize(Size(0,0))
75
74
    , m_WindowSize(Size(0,0))
103
102
  {
104
103
    inlSetThreadLocalStorage(_TLS_GraphicsDisplay, this);
105
104
 
 
105
    m_X11Display = NULL;
106
106
    m_GLCtx = 0;
107
107
    m_X11LastEvent.type = -1;
 
108
    _has_glx_13 = false;
 
109
    glx_window_ = 0;
108
110
 
109
111
    m_pEvent = new Event();
110
112
 
120
122
    NUX_SAFE_DELETE( m_DeviceFactory );
121
123
 
122
124
    if (m_CreatedFromForeignWindow == false)
 
125
    {
123
126
      DestroyOpenGLWindow();
124
 
 
 
127
    }
 
128
    
125
129
    NUX_SAFE_DELETE( m_pEvent );
126
 
 
127
130
    inlSetThreadLocalStorage(_TLS_GraphicsDisplay, 0);
128
131
  }
129
132
 
 
133
  int GraphicsDisplay::X11ErrorHandler(Display *display, XErrorEvent *error)
 
134
  {
 
135
    if (error->display == NULL)
 
136
      return 0;
 
137
 
 
138
    static char str_buffer[256];
 
139
 
 
140
    XGetErrorText(error->display, error->error_code, str_buffer, 256);
 
141
    nuxDebugMsg("[GraphicsDisplay::X11ErrorHandler] X Error of failed request: %s", str_buffer);
 
142
    nuxDebugMsg("[GraphicsDisplay::X11ErrorHandler] Major opcode of failed request: %s", error->request_code);
 
143
    nuxDebugMsg("[GraphicsDisplay::X11ErrorHandler] Minor opcode of failed request: %s", error->minor_code);
 
144
    nuxDebugMsg("[GraphicsDisplay::X11ErrorHandler] Serial number of failed request: %s", error->serial);
 
145
 
 
146
    return 0;
 
147
  }
 
148
 
130
149
  NString GraphicsDisplay::FindResourceLocation(const char *ResourceFileName, bool ErrorOnFail)
131
150
  {
132
151
    NString path = m_ResourcePathLocation.GetFile(ResourceFileName);
231
250
      return false;
232
251
    }
233
252
 
 
253
    //XSetErrorHandler(X11ErrorHandler);
 
254
 
234
255
    m_X11Screen = DefaultScreen(m_X11Display);
235
256
    XF86VidModeQueryVersion(m_X11Display, &_x11_major, &_x11_minor);
236
257
    XineramaQueryVersion(m_X11Display, &xinerama_major, &xinerama_minor);
319
340
    }
320
341
    else
321
342
    {
322
 
        static int DoubleBufferAttributes[] =
 
343
        int DoubleBufferAttributes[] =
323
344
        {
324
345
          //GLX_X_RENDERABLE, True,
325
346
          GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
326
347
          GLX_RENDER_TYPE,   GLX_RGBA_BIT,
327
 
          //GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
 
348
          GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
328
349
          GLX_DOUBLEBUFFER,  True,
329
350
          GLX_RED_SIZE,      8,     /* the maximum number of bits per component    */
330
351
          GLX_GREEN_SIZE,    8, 
331
352
          GLX_BLUE_SIZE,     8,
332
 
          //GLX_ALPHA_SIZE,    8,
333
 
          //GLX_DEPTH_SIZE,    24,
334
 
          //GLX_STENCIL_SIZE,  8,
 
353
          GLX_ALPHA_SIZE,    8,
 
354
          GLX_DEPTH_SIZE,    24,
 
355
          GLX_STENCIL_SIZE,  8,
335
356
          None
336
357
        };
337
358
 
338
 
        //XSetWindowAttributes  swa;
339
 
        GLXFBConfig           *fbconfigs;
340
 
        //GLXContext            context;
341
 
        //GLXWindow             glxWin;
342
 
        int                   fbcount;
 
359
        GLXFBConfig *fbconfigs = NULL;
 
360
        int         fbcount;
 
361
 
 
362
        #define GET_PROC(proc_type, proc_name, check)       \
 
363
        do                                                  \
 
364
        {                                                   \
 
365
          proc_name = (proc_type) glXGetProcAddress((const GLubyte *) #proc_name); \
 
366
        } while (0)
 
367
 
 
368
        // /* GLX 1.0 */
 
369
        // GET_PROC(GLXCREATECONTEXTPROC,            glXCreateContext, true);
 
370
        // GET_PROC(GLXDESTROYCONTEXTPROC,           glXDestroyContext, true);
 
371
        // GET_PROC(GLXMAKECURRENTPROC,              glXMakeCurrent, true);
 
372
        // GET_PROC(GLXSWAPBUFFERSPROC,              glXSwapBuffers, true);
 
373
        // GET_PROC(GLXCREATEGLXPIXMAPPROC,          glXCreateGLXPixmap, true);
 
374
        // GET_PROC(GLXDESTROYGLXPIXMAPPROC,         glXDestroyGLXPixmap, true);
 
375
        // GET_PROC(GLXQUERYVERSIONPROC,             glXQueryVersion, true);
 
376
        // GET_PROC(GLXGETCONFIGPROC,                glXGetConfig, true);
 
377
        // GET_PROC(GLXWAITGLPROC,                   glXWaitGL, true);
 
378
        // GET_PROC(GLXWAITXPROC,                    glXWaitX, true);
 
379
        
 
380
        // /* GLX 1.1 */
 
381
        // GET_PROC(GLXQUERYEXTENSIONSSTRINGPROC,    glXQueryExtensionsString, true);
 
382
        // GET_PROC(GLXQUERYSERVERSTRINGPROC,        glXQueryServerString, true);
 
383
        // GET_PROC(GLXGETCLIENTSTRINGPROC,          glXGetClientString, true);
 
384
        
 
385
        /* GLX 1.3 */
 
386
        GET_PROC(PFNGLXGETFBCONFIGSPROC,              glXGetFBConfigs, false);
 
387
        GET_PROC(PFNGLXGETFBCONFIGATTRIBPROC,         glXGetFBConfigAttrib, false);
 
388
        GET_PROC(PFNGLXGETVISUALFROMFBCONFIGPROC,     glXGetVisualFromFBConfig, false);
 
389
        GET_PROC(PFNGLXCREATEWINDOWPROC,              glXCreateWindow, false);
 
390
        GET_PROC(PFNGLXDESTROYWINDOWPROC,             glXDestroyWindow, false);
 
391
        GET_PROC(PFNGLXCREATEPIXMAPPROC,              glXCreatePixmap, false);
 
392
        GET_PROC(PFNGLXDESTROYPIXMAPPROC,             glXDestroyPixmap, false);
 
393
        GET_PROC(PFNGLXCREATEPBUFFERPROC,             glXCreatePbuffer, false);
 
394
        GET_PROC(PFNGLXDESTROYPBUFFERPROC,            glXDestroyPbuffer, false);
 
395
        GET_PROC(PFNGLXCREATENEWCONTEXTPROC,          glXCreateNewContext, false);
 
396
        GET_PROC(PFNGLXMAKECONTEXTCURRENTPROC,        glXMakeContextCurrent, false);
 
397
        GET_PROC(PFNGLXCHOOSEFBCONFIGPROC,            glXChooseFBConfig, false);
 
398
        
 
399
        /* GLX_SGIX_pbuffer */
 
400
        GET_PROC(PFNGLXCREATEGLXPBUFFERSGIXPROC,      glXCreateGLXPbufferSGIX, false);
 
401
        GET_PROC(PFNGLXDESTROYGLXPBUFFERSGIXPROC,     glXDestroyGLXPbufferSGIX, false);
 
402
        #undef GET_PROC
 
403
 
343
404
 
344
405
        // Request a double buffer configuration
345
 
        fbconfigs = glXChooseFBConfig(m_X11Display, DefaultScreen(m_X11Display), DoubleBufferAttributes, &fbcount );
 
406
        fbconfigs = glXChooseFBConfig(m_X11Display, DefaultScreen(m_X11Display), DoubleBufferAttributes, &fbcount);
346
407
 
347
408
        if (fbconfigs == NULL)
348
409
        {
350
411
          return false;
351
412
        }
352
413
 
353
 
        // Select the best config
354
 
        int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
355
 
        for (int i = 0; i < fbcount; i++)
 
414
        // Select best multi-sample config.
 
415
        if ((_glx_major >= 1) && (_glx_minor >= 4))
356
416
        {
357
 
          XVisualInfo *vi = glXGetVisualFromFBConfig(m_X11Display, fbconfigs[i]);
358
 
          if (vi)
 
417
          int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999;
 
418
          for (int i = 0; i < fbcount; i++)
359
419
          {
360
 
            int samp_buf, samples;
361
 
            glXGetFBConfigAttrib(m_X11Display, fbconfigs[i], GLX_SAMPLE_BUFFERS, &samp_buf);
362
 
            glXGetFBConfigAttrib(m_X11Display, fbconfigs[i], GLX_SAMPLES       , &samples);
363
 
 
364
 
            nuxDebugMsg("Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d SAMPLES = %d\n", i, vi->visualid, samp_buf, samples);
365
 
 
366
 
            if (((best_fbc < 0) || samp_buf) && (samples > best_num_samp))
367
 
              best_fbc = i, best_num_samp = samples;
368
 
            if ((worst_fbc < 0) || (!samp_buf) || (samples < worst_num_samp))
369
 
              worst_fbc = i, worst_num_samp = samples;
 
420
            XVisualInfo *vi = glXGetVisualFromFBConfig(m_X11Display, fbconfigs[i]);
 
421
            if (vi)
 
422
            {
 
423
              int sample_buf, samples;
 
424
              glXGetFBConfigAttrib(m_X11Display, fbconfigs[i], GLX_SAMPLE_BUFFERS, &sample_buf);
 
425
              glXGetFBConfigAttrib(m_X11Display, fbconfigs[i], GLX_SAMPLES       , &samples);
 
426
 
 
427
              //nuxDebugMsg("Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d SAMPLES = %d\n", i, vi->visualid, sample_buf, samples);
 
428
 
 
429
              if (((best_fbc < 0) || sample_buf) && (samples > best_num_samp))
 
430
              {
 
431
                best_fbc = i;
 
432
                best_num_samp = samples; 
 
433
              }
 
434
 
 
435
              if ((worst_fbc < 0) || (!sample_buf) || (samples < worst_num_samp))
 
436
              {
 
437
                worst_fbc = i;
 
438
                worst_num_samp = samples;
 
439
              }
 
440
            }
 
441
            XFree(vi);
370
442
          }
371
 
          XFree(vi);
372
 
        }
373
 
 
374
 
        _fb_config = fbconfigs[best_fbc];
 
443
 
 
444
          nuxAssertMsg(best_fbc >= 0, "[GraphicsDisplay::CreateOpenGLWindow] Invalid frame buffer config.");
 
445
 
 
446
          _fb_config = fbconfigs[best_fbc];
 
447
        }
 
448
        else
 
449
        {
 
450
          // Choose the first one
 
451
          _fb_config = fbconfigs[0];
 
452
        }
375
453
 
376
454
        XFree(fbconfigs);
377
455
 
542
620
    }
543
621
 
544
622
#ifndef NUX_OPENGLES_20
545
 
    if (0 /*_has_glx_13*/)
 
623
    if (_has_glx_13)
546
624
    {
547
625
      XFree(m_X11VisualInfo);
548
626
      m_X11VisualInfo = 0;
550
628
      /* Create a GLX context for OpenGL rendering */
551
629
      m_GLCtx = glXCreateNewContext(m_X11Display, _fb_config, GLX_RGBA_TYPE, NULL, True);
552
630
 
 
631
      if (m_GLCtx == 0)
 
632
      {
 
633
        nuxDebugMsg("[GraphicsDisplay::CreateOpenGLWindow] m_GLCtx is null");
 
634
      }
 
635
 
553
636
      /* Create a GLX window to associate the frame buffer configuration
554
637
      ** with the created X window */
555
 
      GLXWindow glxWin = glXCreateWindow(m_X11Display, _fb_config, m_X11Window, NULL );
 
638
      glx_window_ = glXCreateWindow(m_X11Display, _fb_config, m_X11Window, NULL);
556
639
      
557
640
      // Map the window to the screen, and wait for it to appear */
558
641
      XMapWindow(m_X11Display, m_X11Window);
560
643
      XIfEvent(m_X11Display, &event, WaitForNotify, (XPointer) m_X11Window);
561
644
 
562
645
      /* Bind the GLX context to the Window */
563
 
      glXMakeContextCurrent(m_X11Display, glxWin, glxWin, m_GLCtx);
 
646
      glXMakeContextCurrent(m_X11Display, glx_window_, glx_window_, m_GLCtx);
564
647
    }
565
648
#else
566
649
    m_GLSurface = eglCreateWindowSurface(dpy, config, (EGLNativeWindowType)m_X11Window, 0);
593
676
    m_DeviceFactory = new GpuDevice(m_ViewportSize.width, m_ViewportSize.height, BITFMT_R8G8B8A8,
594
677
        m_X11Display,
595
678
        m_X11Window,
596
 
        0,
 
679
        _has_glx_13,
597
680
        _fb_config,
598
681
        m_GLCtx,
599
682
        1, 0, false);
932
1015
 
933
1016
  Rect GraphicsDisplay::GetWindowGeometry()
934
1017
  {
935
 
    XWindowAttributes attrib;
936
 
    int status = XGetWindowAttributes(m_X11Display, m_X11Window, &attrib);
937
 
 
938
 
    if (status == 0)
939
 
    {
940
 
      nuxAssert("[GraphicsDisplay::GetWindowGeometry] Failed to get the window attributes.");
941
 
      return Rect(0, 0, 0, 0);
942
 
    }
943
 
 
944
 
    return Rect(attrib.x, attrib.y, attrib.width, attrib.height);
 
1018
    // Window rw;
 
1019
    // int x, y;
 
1020
    // unsigned int w, h, b, d;
 
1021
    // Window child_return;
 
1022
 
 
1023
    // int status = XGetGeometry(m_X11Display, m_X11Window, &rw, &x, &y, &w, &h, &b, &d);
 
1024
    
 
1025
    // if (status == 0)
 
1026
    // {
 
1027
    //   nuxAssert("[GraphicsDisplay::GetWindowGeometry] Failed to get the window attributes.");
 
1028
    //   return Rect(0, 0, 0, 0);
 
1029
    // }    
 
1030
    
 
1031
    // XSync(m_X11Display, False);
 
1032
 
 
1033
    // status = XTranslateCoordinates(m_X11Display, m_X11Window, RootWindow(m_X11Display, 0), x, y, &x, &y, &child_return);
 
1034
    
 
1035
    // if (status == 0)
 
1036
    // {
 
1037
    //   nuxAssert("[GraphicsDisplay::GetWindowGeometry] Failed to get the window attributes.");
 
1038
    //   return Rect(0, 0, 0, 0);
 
1039
    // }    
 
1040
 
 
1041
    // XSync(m_X11Display, False);
 
1042
    return Rect(m_WindowPosition.x, m_WindowPosition.y, m_WindowSize.width, m_WindowSize.height);
945
1043
  }
946
1044
 
947
1045
  Rect GraphicsDisplay::GetNCWindowGeometry()
948
1046
  {
949
 
    XWindowAttributes attrib;
950
 
    int status = XGetWindowAttributes(m_X11Display, m_X11Window, &attrib);
951
 
 
952
 
    if (status == 0)
953
 
    {
954
 
      nuxAssert("[GraphicsDisplay::GetWindowGeometry] Failed to get the window attributes.");
955
 
      return Rect(0, 0, 0, 0);
956
 
    }
957
 
 
958
 
    return Rect(attrib.x, attrib.y, attrib.width, attrib.height);
 
1047
    // XWindowAttributes attrib;
 
1048
    // int status = XGetWindowAttributes(m_X11Display, m_X11Window, &attrib);
 
1049
 
 
1050
    // if (status == 0)
 
1051
    // {
 
1052
    //   nuxAssert("[GraphicsDisplay::GetWindowGeometry] Failed to get the window attributes.");
 
1053
    //   return Rect(0, 0, 0, 0);
 
1054
    // }
 
1055
 
 
1056
    // return Rect(attrib.x, attrib.y, attrib.width, attrib.height);
 
1057
 
 
1058
    return Rect(m_WindowPosition.x, m_WindowPosition.y, m_WindowSize.width, m_WindowSize.height);
959
1059
  }
960
1060
 
961
1061
  void GraphicsDisplay::MakeGLContextCurrent()
962
1062
  {
963
1063
#ifndef NUX_OPENGLES_20
964
 
    if (!glXMakeCurrent(m_X11Display, m_X11Window, m_GLCtx))
 
1064
    if (_has_glx_13)
 
1065
    {
 
1066
      nuxDebugMsg("Has glx 1.3");
 
1067
      if (!glXMakeContextCurrent(m_X11Display, glx_window_, glx_window_, m_GLCtx))
 
1068
      {
 
1069
        nuxDebugMsg("Destroy");
 
1070
        DestroyOpenGLWindow();
 
1071
      }
 
1072
    }
 
1073
    else if (!glXMakeCurrent(m_X11Display, m_X11Window, m_GLCtx))
965
1074
    {
966
1075
      DestroyOpenGLWindow();
967
1076
    }
1005
1114
    if (glswap)
1006
1115
    {
1007
1116
#ifndef NUX_OPENGLES_20
1008
 
      glXSwapBuffers(m_X11Display, m_X11Window);
 
1117
      if (_has_glx_13)
 
1118
        glXSwapBuffers(m_X11Display, glx_window_);
 
1119
      else
 
1120
        glXSwapBuffers(m_X11Display, m_X11Window);
1009
1121
#else
1010
1122
      eglSwapBuffers(eglGetDisplay((EGLNativeDisplayType)m_X11Display), m_GLSurface);
1011
1123
#endif
1037
1149
  {
1038
1150
    if (m_GfxInterfaceCreated == true)
1039
1151
    {
 
1152
      if (m_GLCtx == 0)
 
1153
      {
 
1154
        nuxDebugMsg("[GraphicsDisplay::DestroyOpenGLWindow] m_GLCtx is null");
 
1155
      }
 
1156
 
1040
1157
      if (m_GLCtx)
1041
1158
      {
1042
1159
#ifndef NUX_OPENGLES_20
1069
1186
        XF86VidModeSetViewPort(m_X11Display, m_X11Screen, 0, 0);
1070
1187
      }
1071
1188
 
 
1189
      glXDestroyWindow(m_X11Display, glx_window_);
 
1190
 
 
1191
      XDestroyWindow(m_X11Display, m_X11Window);
 
1192
      XFreeColormap(m_X11Display, m_X11Colormap);
1072
1193
      XCloseDisplay(m_X11Display);
1073
1194
    }
1074
1195
 
1617
1738
        m_pEvent->width =  xevent.xconfigure.width;
1618
1739
        m_pEvent->height = xevent.xconfigure.height;
1619
1740
        m_WindowSize = Size(xevent.xconfigure.width, xevent.xconfigure.height);
1620
 
        m_WindowPosition = Point(xevent.xconfigure.x, xevent.xconfigure.y);
1621
 
 
1622
 
        //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: ConfigureNotify event.");
 
1741
 
 
1742
        Window rw;
 
1743
        int x, y;
 
1744
        unsigned int w, h, b, d;
 
1745
        Window child_return;
 
1746
 
 
1747
        int status = XTranslateCoordinates(m_X11Display, m_X11Window, RootWindow(m_X11Display, 0), 0, 0, &x, &y, &child_return);
 
1748
        m_WindowPosition = Point(x, y);
 
1749
 
 
1750
        //nuxDebugMsg("[GraphicsDisplay::ProcessXEvents]: ConfigureNotify event. %d %d", x, y);
1623
1751
        break;
1624
1752
      }
1625
1753