Example #1
0
void GlxBackend::present()
{
    if (lastDamage().isEmpty())
        return;

    const QSize &screenSize = screens()->size();
    const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height());
    const bool fullRepaint = supportsBufferAge() || (lastDamage() == displayRegion);

    if (fullRepaint) {
        if (m_haveINTELSwapEvent)
            Compositor::self()->aboutToSwapBuffers();

        if (haveSwapInterval) {
            if (gs_tripleBufferNeedsDetection) {
                glXWaitGL();
                m_swapProfiler.begin();
            }
            glXSwapBuffers(display(), glxWindow);
            if (gs_tripleBufferNeedsDetection) {
                glXWaitGL();
                if (char result = m_swapProfiler.end()) {
                    gs_tripleBufferUndetected = gs_tripleBufferNeedsDetection = false;
                    if (result == 'd' && GLPlatform::instance()->driver() == Driver_NVidia) {
                        // TODO this is a workaround, we should get __GL_YIELD set before libGL checks it
                        if (qstrcmp(qgetenv("__GL_YIELD"), "USLEEP")) {
                            options->setGlPreferBufferSwap(0);
                            setSwapInterval(0);
                            result = 0; // hint proper behavior
                            qCWarning(KWIN_CORE) << "\nIt seems you are using the nvidia driver without triple buffering\n"
                                              "You must export __GL_YIELD=\"USLEEP\" to prevent large CPU overhead on synced swaps\n"
                                              "Preferably, enable the TripleBuffer Option in the xorg.conf Device\n"
                                              "For this reason, the tearing prevention has been disabled.\n"
                                              "See https://bugs.kde.org/show_bug.cgi?id=322060\n";
                        }
                    }
                    setBlocksForRetrace(result == 'd');
                }
            } else if (blocksForRetrace()) {
                // at least the nvidia blob manages to swap async, ie. return immediately on double
                // buffering - what messes our timing calculation and leads to laggy behavior #346275
                glXWaitGL();
            }
        } else {
            waitSync();
            glXSwapBuffers(display(), glxWindow);
        }
        if (supportsBufferAge()) {
            glXQueryDrawable(display(), glxWindow, GLX_BACK_BUFFER_AGE_EXT, (GLuint *) &m_bufferAge);
        }
    } else if (m_haveMESACopySubBuffer) {
        foreach (const QRect & r, lastDamage().rects()) {
            // convert to OpenGL coordinates
            int y = screenSize.height() - r.y() - r.height();
            glXCopySubBufferMESA(display(), glxWindow, r.x(), y, r.width(), r.height());
        }
    } else { // Copy Pixels (horribly slow on Mesa)
Example #2
0
void GlxBackend::present()
{
    if (lastDamage().isEmpty())
        return;

    const QRegion displayRegion(0, 0, displayWidth(), displayHeight());
    const bool fullRepaint = supportsBufferAge() || (lastDamage() == displayRegion);

    if (fullRepaint) {
        if (haveSwapInterval) {
            if (gs_tripleBufferNeedsDetection) {
                glXWaitGL();
                m_swapProfiler.begin();
            }
            glXSwapBuffers(display(), glxWindow);
            if (gs_tripleBufferNeedsDetection) {
                glXWaitGL();
                if (char result = m_swapProfiler.end()) {
                    gs_tripleBufferUndetected = gs_tripleBufferNeedsDetection = false;
                    if (result == 'd' && GLPlatform::instance()->driver() == Driver_NVidia) {
                        // TODO this is a workaround, we should get __GL_YIELD set before libGL checks it
                        if (qstrcmp(qgetenv("__GL_YIELD"), "USLEEP")) {
                            options->setGlPreferBufferSwap(0);
                            setSwapInterval(0);
                            qWarning() << "\nIt seems you are using the nvidia driver without triple buffering\n"
                                              "You must export __GL_YIELD=\"USLEEP\" to prevent large CPU overhead on synced swaps\n"
                                              "Preferably, enable the TripleBuffer Option in the xorg.conf Device\n"
                                              "For this reason, the tearing prevention has been disabled.\n"
                                              "See https://bugs.kde.org/show_bug.cgi?id=322060\n";
                        }
                    }
                    setBlocksForRetrace(result == 'd');
                }
            }
        } else {
            waitSync();
            glXSwapBuffers(display(), glxWindow);
        }
        if (supportsBufferAge()) {
            glXQueryDrawable(display(), glxWindow, GLX_BACK_BUFFER_AGE_EXT, (GLuint *) &m_bufferAge);
        }
    } else if (glXCopySubBuffer) {
        foreach (const QRect & r, lastDamage().rects()) {
            // convert to OpenGL coordinates
            int y = displayHeight() - r.y() - r.height();
            glXCopySubBuffer(display(), glxWindow, r.x(), y, r.width(), r.height());
        }
    } else { // Copy Pixels (horribly slow on Mesa)
Example #3
0
    void
    resize(int w, int h) {
        if (w == width && h == height) {
            return;
        }

        glXWaitGL();

        // We need to ensure that pending events are processed here, and XSync
        // with discard = True guarantees that, but it appears the limited
        // event processing we do so far is sufficient
        //XSync(display, True);

        Drawable::resize(w, h);

        // Tell the window manager to respect the requested size
        XSizeHints size_hints;
        size_hints.max_width  = size_hints.min_width  = w;
        size_hints.max_height = size_hints.min_height = h;
        size_hints.flags = PMinSize | PMaxSize;
        XSetWMNormalHints(display, window, &size_hints);

        XResizeWindow(display, window, w, h);

        waitForEvent(ConfigureNotify);

        glXWaitX();
    }
Example #4
0
void
_gdk_gl_pixmap_destroy (GdkGLPixmap *glpixmap)
{
  GdkGLPixmapImplX11 *impl = GDK_GL_PIXMAP_IMPL_X11 (glpixmap);
  Display *xdisplay;

  GDK_GL_NOTE_FUNC_PRIVATE ();

  if (impl->is_destroyed)
    return;

  xdisplay = GDK_GL_CONFIG_XDISPLAY (impl->glconfig);

  if (impl->glxpixmap == glXGetCurrentDrawable ())
    {
      glXWaitGL ();

      GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent");
      glXMakeCurrent (xdisplay, None, NULL);
    }

  GDK_GL_NOTE_FUNC_IMPL ("glXDestroyGLXPixmap");
  glXDestroyGLXPixmap (xdisplay, impl->glxpixmap);

  impl->glxpixmap = None;

  impl->is_destroyed = TRUE;
}
Example #5
0
void gl_finish()
{
    glFlush();
#ifndef _WIN32
    glXWaitGL();
#endif
}
Example #6
0
void
_gdk_gl_window_destroy (GdkGLWindow *glwindow)
{
  GdkGLWindowImplX11 *impl = GDK_GL_WINDOW_IMPL_X11 (glwindow);
  Display *xdisplay;
  GdkGL_GLX_MESA_release_buffers *mesa_ext;

  GDK_GL_NOTE_FUNC_PRIVATE ();

  if (impl->is_destroyed)
    return;

  xdisplay = GDK_GL_CONFIG_XDISPLAY (impl->glconfig);

  if (impl->glxwindow == glXGetCurrentDrawable ())
    {
      glXWaitGL ();

      GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent");
      glXMakeCurrent (xdisplay, None, NULL);
    }

  /* If GLX_MESA_release_buffers is supported. */
  mesa_ext = gdk_gl_get_GLX_MESA_release_buffers (impl->glconfig);
  if (mesa_ext)
    {
      GDK_GL_NOTE_FUNC_IMPL ("glXReleaseBuffersMESA");
      mesa_ext->glXReleaseBuffersMESA (xdisplay, impl->glxwindow);
    }

  impl->glxwindow = None;

  impl->is_destroyed = TRUE;
}
Example #7
0
Word NewGameWindow(Word NewVidSize)
{
	XSizeHints sizehints;
		
	if (NewVidSize == VidSize)
		return VidSize;
	
	if (NewVidSize < 4) {
		w = VidXs[NewVidSize];
		h = VidYs[NewVidSize];
		v = VidVs[NewVidSize];
	} else {
		fprintf(stderr, "Invalid Vid size: %d\n", NewVidSize);
		exit(EXIT_FAILURE);
	}

	sizehints.min_width =  w;
	sizehints.min_height = h;
	sizehints.flags = PMinSize;
	XSetWMNormalHints(dpy, win, &sizehints);
	XResizeWindow(dpy, win, w, h);
	
	SetAPalette(rBlackPal);
	ClearTheScreen(BLACK);
	BlastScreen();
	
	VidSize = NewVidSize;
	
	XSync(dpy, False);
	glXWaitGL();
	glXWaitX();
	HandleEvents();
	
	return VidSize;
}
Example #8
0
JNIEXPORT void JNICALL GLX_NATIVE(glXWaitGL)
	(JNIEnv *env, jclass that)
{
	GLX_NATIVE_ENTER(env, that, glXWaitGL_FUNC);
	glXWaitGL();
	GLX_NATIVE_EXIT(env, that, glXWaitGL_FUNC);
}
Example #9
0
File: main.c Project: czaber/ogwm
void draw() {
	int i;
	GLfloat width, height;
	glXWaitX(); check_gl(__LINE__);
	//XGrabServer(dpy);
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT); check_gl(__LINE__);
	
	draw_background();

	for (i=0; i<MAX_CLIENTS; i++) {
		if (workspace == NULL || workspace[i].window == 0)
			break;
		Client client = workspace[i];
		width = (GLfloat) client.geom.width;
		height = (GLfloat) client.geom.height;
		//info("Drawing %d window => 0x%x, %g x %g\n", i, client.window, width, height);
		if(client.geom.depth == 32) {
            info("Using blending\n");
			glEnable(GL_BLEND);
			glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // X windows are premultiplied
		} else
            glDisable(GL_BLEND);

        	
 	   	glEnable(client.target); check_gl(__LINE__); 
		glBindTexture(client.target, client.texture); check_gl(__LINE__); 
		glXBindTexImageProc(dpy, client.glxpixmap, GLX_FRONT_LEFT_EXT, NULL); 
		check_gl(__LINE__);
		glTexParameterf(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
		glTexParameterf(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
		check_gl(__LINE__);
		glBegin(GL_QUADS);
			glColor3d(1.0, 1.0, 1.0);
			glTexCoord2f(left*width,  bottom*height);   glVertex3f(0.00f, 0.000f, 1.0f);
			glTexCoord2f(left*width,     top*height);	glVertex3f(0.00f, height, 1.0f);
			glTexCoord2f(right*width,    top*height);	glVertex3f(width, height, 1.0f);
			glTexCoord2f(right*width, bottom*height);	glVertex3f(width, 0.000f, 1.0f);
		glEnd();
		check_gl(__LINE__);
		glBindTexture(client.target, 0); check_gl(__LINE__); 
		glDisable(client.target); check_gl(__LINE__); 
		glXReleaseTexImageProc(dpy, client.glxpixmap, GLX_FRONT_LEFT_EXT); 
		check_gl(__LINE__);
	}
    glXWaitGL(); check_gl(__LINE__); 
	glXSwapBuffers(dpy, canvas); check_gl(__LINE__); 
	usleep(2000);  // 50Hz
	XEvent ev;
	ev.type = ClientMessage;
	ev.xclient.display = dpy;
	ev.xclient.window = root;
	ev.xclient.format = 8;
	XSendEvent(dpy, overlay, False, SubstructureNotifyMask, &ev);
	XFlush(dpy);
	//XUngrabServer(dpy);
}
Example #10
0
//================================================================
  void*  GLB_Create () {
//================================================================
/// GLB_Create            create opengl-window (used by GUI_gl__)
 
  GtkWidget   *area;
  int         xscreen, i1;
  GdkScreen   *screen;
  GdkVisual   *visual;
  Window      root;
  XVisualInfo *xvisual;
  Colormap    xcolormap;
  int         attributes[] = {
                GLX_RGBA,
                GLX_RED_SIZE, 1,
                GLX_GREEN_SIZE, 1,
                GLX_BLUE_SIZE, 1,
                GLX_DOUBLEBUFFER, True,
                GLX_DEPTH_SIZE, 24,
                None };

  GLB_x_id = 0;   // reset

  area = gtk_drawing_area_new ();
  gtk_widget_set_double_buffered (area, FALSE);

  GLB_display = gdk_x11_get_default_xdisplay ();
  xscreen = DefaultScreen (GLB_display);
  screen = gdk_screen_get_default ();
    // printf(" screenNr = %d\n",gdk_screen_get_number(screen));

  xvisual = glXChooseVisual (GLB_display, xscreen, attributes);
    // printf(" xvisualid=%d\n",xvisual->visualid);

  visual = gdk_x11_screen_lookup_visual (screen, xvisual->visualid);

  root = RootWindow (GLB_display, xscreen);
  xcolormap = XCreateColormap (GLB_display, root, xvisual->visual, AllocNone);

  glXGetConfig (GLB_display, xvisual, GLX_RED_SIZE, &i1);
    printf(" GLX_RED_SIZE=%d\n",i1);
  glXGetConfig (GLB_display, xvisual, GLX_DEPTH_SIZE, &i1);
    printf(" GLX_DEPTH_SIZE=%d\n",i1);

// Gtk2 only:
  //colormap = gdk_x11_colormap_foreign_new (visual, xcolormap);
  //gtk_widget_set_colormap (area, colormap);

  GLB_x_context = glXCreateContext (GLB_display, xvisual, NULL, TRUE);
  // free (xvisual);

  glXWaitX();
  glXWaitGL();

  return area;

}
Example #11
0
    void show(void) {
        if (visible) {
            return;
        }

        glXWaitGL();

        showWindow(window);

        glXWaitX();

        Drawable::show();
    }
Example #12
0
    void show(void) override {
        if (!window ||
            visible) {
            return;
        }

        glXWaitGL();

        showWindow(window);

        glXWaitX();

        Drawable::show();
    }
Example #13
0
    void show(void) {
        if (visible) {
            return;
        }

        glXWaitGL();

        XMapWindow(display, window);

        waitForEvent(MapNotify);

        glXWaitX();

        Drawable::show();
    }
Example #14
0
void color_resultbg()
{
  float redcol, greencol, bluecol;

   redcol = (float)mr/255.0;
   greencol = (float)mg/255.0;
   bluecol = (float)mb/255.0;

   glXWaitX();
   glXMakeCurrent(dpy,bgwindowid,bg_context);
   glClearColor(redcol,greencol,bluecol,1.0);
   glClear(GL_COLOR_BUFFER_BIT);
   if (doubleBuffer == GL_TRUE) glXSwapBuffers(dpy, bgwindowid);
   glClear(GL_COLOR_BUFFER_BIT);
   if (doubleBuffer == GL_TRUE) glXSwapBuffers(dpy, bgwindowid);
   glXWaitGL();
}
	int XdevLOpenGLContextGLX::makeCurrent(XdevLWindow* window) {

//		Display* xdisplay = static_cast<Display*>(window->getInternal(XdevLInternalName("X11_DISPLAY")));
//		if(nullptr == xdisplay) {
//			return RET_FAILED;
//		}
//
//		Window xwindow = (Window)(window->getInternal(XdevLInternalName("X11_WINDOW")));
//		if(None == xdisplay) {
//			return RET_FAILED;
//		}

		glXWaitGL();
		if(glXMakeCurrent(m_display, m_window, m_glxContext) == True) {
			return RET_SUCCESS;
		}
		return RET_FAILED;
	}
Example #16
0
static void
clutter_backend_glx_redraw (ClutterBackend *backend,
                            ClutterStage   *stage)
{
  ClutterStageGLX *stage_glx;
  ClutterStageX11 *stage_x11;
  ClutterStageWindow *impl;

  impl = _clutter_stage_get_window (stage);
  if (G_UNLIKELY (impl == NULL))
    {
      CLUTTER_NOTE (BACKEND, "Stage [%p] has no implementation", stage);
      return;
    }

  g_assert (CLUTTER_IS_STAGE_GLX (impl));

  stage_x11 = CLUTTER_STAGE_X11 (impl);
  stage_glx = CLUTTER_STAGE_GLX (impl);

  /* this will cause the stage implementation to be painted */
  clutter_actor_paint (CLUTTER_ACTOR (stage));
  cogl_flush ();

  if (stage_x11->xwin != None)
    {
      /* wait for the next vblank */
      CLUTTER_NOTE (BACKEND, "Waiting for vblank");
      glx_wait_for_vblank (CLUTTER_BACKEND_GLX (backend));

      /* push on the screen */
      CLUTTER_NOTE (BACKEND, "glXSwapBuffers (display: %p, window: 0x%lx)",
                    stage_x11->xdpy,
                    (unsigned long) stage_x11->xwin);
      glXSwapBuffers (stage_x11->xdpy, stage_x11->xwin);
    }
  else
    {
      /* offscreen */
      glXWaitGL ();

      CLUTTER_GLERR ();
    }
}
Example #17
0
    void
    resize(int w, int h) {
        if (w == width && h == height) {
            return;
        }

        glXWaitGL();

        // We need to ensure that pending events are processed here, and XSync
        // with discard = True guarantees that, but it appears the limited
        // event processing we do so far is sufficient
        //XSync(display, True);

        Drawable::resize(w, h);

        resizeWindow(window, w, h);

        glXWaitX();
    }
Example #18
0
static DFBResult
update_screen( DFBX11 *x11, const DFBRectangle *clip, CoreSurfaceBufferLock *lock, XWindow *xw )
{
     void                  *dst;
     void                  *src;
     unsigned int           offset = 0;
     XImage                *ximage;
     CoreSurface           *surface;
     CoreSurfaceAllocation *allocation;
     DFBX11Shared          *shared;
     DFBRectangle           rect;
     bool                   direct = false;

     D_ASSERT( x11 != NULL );
     DFB_RECTANGLE_ASSERT( clip );

     D_DEBUG_AT( X11_Update, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( clip ) );

     CORE_SURFACE_BUFFER_LOCK_ASSERT( lock );

     shared = x11->shared;
     D_ASSERT( shared != NULL );

     XLockDisplay( x11->display );

     if (!xw) {
          XUnlockDisplay( x11->display );
          return DFB_OK;
     }

     allocation = lock->allocation;
     CORE_SURFACE_ALLOCATION_ASSERT( allocation );

     surface = allocation->surface;
     D_ASSERT( surface != NULL );


     rect.x = rect.y = 0;
     rect.w = xw->width;
     rect.h = xw->height;

     if (!dfb_rectangle_intersect( &rect, clip )) {
          XUnlockDisplay( x11->display );
          return DFB_OK;
     }

     D_DEBUG_AT( X11_Update, "  -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( &rect ) );

#ifdef USE_GLX
     /* Check for GLX allocation... */
     if (allocation->pool == shared->glx_pool && lock->handle) {
          LocalPixmap *pixmap = lock->handle;

          D_MAGIC_ASSERT( pixmap, LocalPixmap );

          /* ...and just call SwapBuffers... */
          //D_DEBUG_AT( X11_Update, "  -> Calling glXSwapBuffers( 0x%lx )...\n", alloc->drawable );
          //glXSwapBuffers( x11->display, alloc->drawable );


          D_DEBUG_AT( X11_Update, "  -> Copying from GLXPixmap...\n" );

          glXWaitGL();

          XCopyArea( x11->display, pixmap->pixmap, xw->window, xw->gc,
                     rect.x, rect.y, rect.w, rect.h, rect.x, rect.y );

          glXWaitX();

          XUnlockDisplay( x11->display );

          return DFB_OK;
     }
#endif

     /* Check for our special native allocation... */
     if (allocation->pool == shared->x11image_pool && lock->handle) {
          x11Image *image = lock->handle;

          D_MAGIC_ASSERT( image, x11Image );

          /* ...and directly XShmPutImage from that. */
          ximage = image->ximage;

          direct = true;
     }
     else {
          /* ...or copy or convert into XShmImage or XImage allocated with the XWindow. */
          ximage = xw->ximage;
          offset = xw->ximage_offset;

          xw->ximage_offset = (offset ? 0 : ximage->height / 2);

          /* make sure the 16-bit input formats are properly 2-pixel-clipped */
          switch (surface->config.format) {
               case DSPF_I420:
               case DSPF_YV12:
               case DSPF_NV12:
               case DSPF_NV21:
                    if (rect.y & 1) {
                         rect.y--;
                         rect.h++;
                    }
                    /* fall through */
               case DSPF_YUY2:
               case DSPF_UYVY:
               case DSPF_NV16:
                    if (rect.x & 1) {
                         rect.x--;
                         rect.w++;
                    }
               default: /* no action */
                    break;
          }

          dst = xw->virtualscreen + rect.x * xw->bpp + (rect.y + offset) * ximage->bytes_per_line;
          src = lock->addr + DFB_BYTES_PER_LINE( surface->config.format, rect.x ) + rect.y * lock->pitch;

          switch (xw->depth) {
               case 32:
                    dfb_convert_to_argb( surface->config.format, src, lock->pitch,
                                         surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    break;

               case 24:
                    dfb_convert_to_rgb32( surface->config.format, src, lock->pitch,
                                          surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    break;

               case 16:
                    if (surface->config.format == DSPF_LUT8) {
                         int width = rect.w; int height = rect.h;
                         const u8    *src8    = src;
                         u16         *dst16   = dst;
                         CorePalette *palette = surface->palette;
                         int          x;
                         while (height--) {

                              for (x=0; x<width; x++) {
                                   DFBColor color = palette->entries[src8[x]];
                                   dst16[x] = PIXEL_RGB16( color.r, color.g, color.b );
                              }

                              src8  += lock->pitch;
                              dst16 += ximage->bytes_per_line / 2;
                         }
                    }
                    else {
                    dfb_convert_to_rgb16( surface->config.format, src, lock->pitch,
                                          surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    }
                    break;

               case 15:
                    dfb_convert_to_rgb555( surface->config.format, src, lock->pitch,
                                           surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    break;

               default:
                    D_ONCE( "unsupported depth %d", xw->depth );
          }
     }

     D_ASSERT( ximage != NULL );


     /* Wait for previous data to be processed... */
     XSync( x11->display, False );

     /* ...and immediately queue or send the next! */
     if (x11->use_shm) {
          /* Just queue the command, it's XShm :) */
          XShmPutImage( xw->display, xw->window, xw->gc, ximage,
                        rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h, False );

          /* Make sure the queue has really happened! */
          XFlush( x11->display );
     }
     else
          /* Initiate transfer of buffer... */
          XPutImage( xw->display, xw->window, xw->gc, ximage,
                     rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h );

     /* Wait for display if single buffered and not converted... */
     if (direct && !(surface->config.caps & DSCAPS_FLIPPING))
          XSync( x11->display, False );

     XUnlockDisplay( x11->display );

     return DFB_OK;
}
DECLEXPORT(EGLBoolean) eglWaitClient(void)
{
    glXWaitGL();
    return clearEGLError();
}
	xdl_int XdevLOpenGLContextGLX::initOpenGL(Display* display, Window window) {

		//
		// Get all supported extensions.
		//
		std::string tmp(glXQueryExtensionsString(display, DefaultScreen(display)));
		std::vector<std::string> exlist;
		xstd::tokenize(tmp, exlist, " ");
		for(auto extension : exlist) {
			extensionsList.push_back(XdevLString(extension));
		}


		std::vector<int> attribute_list;
		// ---------------------------------------------------------------------------
		// Prepare the attribute values for the glXChooseVisual function
		//

		attribute_list.push_back(GLX_X_RENDERABLE);
		attribute_list.push_back(True);

		// We are going to use the normal RGBA color type, not the color index type.
		attribute_list.push_back(GLX_RENDER_TYPE);
		attribute_list.push_back(GLX_RGBA_BIT);

		// This window is going to use only Window type, that means we can't use PBuffers.
		// Valid values are GLX WINDOW BIT, GLX PIXMAP BIT, GLX PBUFFER BIT. All can be used at the same time.
		attribute_list.push_back(GLX_DRAWABLE_TYPE);
		attribute_list.push_back(GLX_WINDOW_BIT);

		if(m_attributes.red_size > 0) {
			attribute_list.push_back(GLX_RED_SIZE);
			attribute_list.push_back(m_attributes.red_size);
		}

		if(m_attributes.green_size > 0) {
			attribute_list.push_back(GLX_GREEN_SIZE);
			attribute_list.push_back(m_attributes.green_size);
		}

		if(m_attributes.blue_size > 0) {
			attribute_list.push_back(GLX_BLUE_SIZE);
			attribute_list.push_back(m_attributes.blue_size);
		}

		if(m_attributes.alpha_size > 0) {
			attribute_list.push_back(GLX_ALPHA_SIZE);
			attribute_list.push_back(m_attributes.alpha_size);
		}

		if((m_attributes.red_size > 0) ||
		    (m_attributes.green_size > 0) ||
		    (m_attributes.blue_size > 0) ||
		    (m_attributes.alpha_size > 0)
		  ) {
			attribute_list.push_back(GLX_BUFFER_SIZE);
			attribute_list.push_back(m_attributes.color_buffer_size);
		}

		attribute_list.push_back(GLX_DEPTH_SIZE);
		attribute_list.push_back(m_attributes.depth_size);

		attribute_list.push_back(GLX_STENCIL_SIZE);
		attribute_list.push_back(m_attributes.stencil_size);

//		attribute_list.push_back(GLX_ACCUM_RED_SIZE);
//		attribute_list.push_back(m_attributes.accum_red_size);
//
//		attribute_list.push_back(GLX_ACCUM_GREEN_SIZE);
//		attribute_list.push_back(m_attributes.accum_green_size);
//
//		attribute_list.push_back(GLX_ACCUM_BLUE_SIZE);
//		attribute_list.push_back(m_attributes.accum_blue_size);
//
//		attribute_list.push_back(GLX_ACCUM_ALPHA_SIZE);
//		attribute_list.push_back(m_attributes.accum_alpha_size);

		if(m_attributes.stereo > 0) {
			attribute_list.push_back(GLX_STEREO);
			attribute_list.push_back(True);
		}

		if(m_attributes.multisample_buffers > 0) {
			attribute_list.push_back(GLX_SAMPLE_BUFFERS);
			attribute_list.push_back(GL_TRUE);
			attribute_list.push_back(GLX_SAMPLES);
			attribute_list.push_back(m_attributes.multisample_samples);
		}

		if(m_attributes.double_buffer > 0) {
			attribute_list.push_back(GLX_DOUBLEBUFFER);
			attribute_list.push_back(GL_TRUE);
		}

		attribute_list.push_back(None);

		//
		// Get all supported visual configurations.
		//
		xdl_int numberOfConfigs;
		GLXFBConfig *fbcfg = glXChooseFBConfig(display, DefaultScreen(display), attribute_list.data(), &numberOfConfigs);
		if(!fbcfg) {
			XDEVL_MODULE_ERROR("glXChooseFBConfig failed\n");
			return RET_FAILED;
		}

		//
		// Retrieve the X Visual associated with a GLXFBConfig
		//
		int best_fbc = -1;
		int worst_fbc = -1;
		int best_num_samples = -1;
		int worst_num_samples = 999;

		for(auto i = 0; i < numberOfConfigs; i++) {
			XVisualInfo* vi = glXGetVisualFromFBConfig(display, fbcfg[i]);
			if(nullptr != vi) {

				int sample_buffer, samples;
				glXGetFBConfigAttrib(display, fbcfg[i], GLX_SAMPLE_BUFFERS, &sample_buffer);
				glXGetFBConfigAttrib(display, fbcfg[i], GLX_SAMPLES, &samples);

				if(best_fbc < 0 || (sample_buffer && samples) > best_num_samples) {
					best_fbc = i;
					best_num_samples = samples;
				}
				if(worst_fbc < 0 || (!sample_buffer && samples) < worst_num_samples) {
					worst_fbc = i;
					worst_num_samples = samples;
				}
			}
			XFree(vi);
		}

		/// Now get the GLXFBConfig for the best match.
		GLXFBConfig bestFbc = fbcfg[best_fbc];
		XFree(fbcfg);

		XDEVL_MODULEX_INFO(XdevLOpenGLContextGLX, "--- GLXFBConfig ---\n");
		dumpConfigInfo(bestFbc);
		XDEVL_MODULEX_INFO(XdevLOpenGLContextGLX, "-------------------\n");

		m_visualInfo = glXGetVisualFromFBConfig(display, bestFbc);

		// Change the windows color map.
		XSetWindowAttributes swa;
		swa.colormap = XCreateColormap(display, RootWindow(display, m_visualInfo->screen), m_visualInfo->visual, AllocNone);
		XChangeWindowAttributes(display, window, CWColormap, &swa);
		glXWaitGL();

		// TODO: This is the easiest way to create a visual for X11. You should do that in a better way cengiz.
//		m_visualInfo = glXChooseVisual(display, DefaultScreen(display), attribute_list.data());
//		if(nullptr == m_visualInfo) {
//			XDEVL_MODULE_ERROR("glXChooseVisual failed. Please try different framebuffer, depthbuffer, stencilbuffer values.\n");
//			return RET_FAILED;
//		}


		//
		// Set OpenGL 3.0 > attributes.
		//
		std::vector<int> opengl_profile_attribute_list;
		opengl_profile_attribute_list.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB);
		opengl_profile_attribute_list.push_back(m_attributes.context_major_version);
		opengl_profile_attribute_list.push_back(GLX_CONTEXT_MINOR_VERSION_ARB);
		opengl_profile_attribute_list.push_back(m_attributes.context_minor_version);

		if((m_attributes.context_flags & XDEVL_OPENGL_CONTEXT_FLAGS_DEBUG_BIT) || (m_attributes.context_flags & XDEVL_OPENGL_CONTEXT_FLAGS_FORWARD_COMPATIBLE_BIT)) {
			opengl_profile_attribute_list.push_back(GLX_CONTEXT_FLAGS_ARB);

			if(m_attributes.context_flags == XDEVL_OPENGL_CONTEXT_FLAGS_DEBUG_BIT) {
				opengl_profile_attribute_list.push_back(GLX_CONTEXT_DEBUG_BIT_ARB);
			} else if(m_attributes.context_flags == XDEVL_OPENGL_CONTEXT_FLAGS_FORWARD_COMPATIBLE_BIT) {
				opengl_profile_attribute_list.push_back(GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
			}
		}

		if((m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_CORE_PROFILE) || (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_COMPATIBILITY)) {
			opengl_profile_attribute_list.push_back(GLX_CONTEXT_PROFILE_MASK_ARB);
			if(m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_CORE_PROFILE) {
				opengl_profile_attribute_list.push_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB);
			} else if(m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_COMPATIBILITY) {
				opengl_profile_attribute_list.push_back(GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
			}
		}
		opengl_profile_attribute_list.push_back(None);
		XDEVL_MODULEX_INFO(XdevLOpenGLContextGLX, "OpenGL: " << m_attributes.context_major_version << "." << m_attributes.context_minor_version << std::endl);

		//
		// Try to use new ARB_create_context and ARB_create_context_profile
		//
		auto sharedContext = m_shareContext ? m_shareContext->getNativeContext() : nullptr;
		if(nullptr != glXCreateContextAttribs) {
			//
			// Create the context.
			//
			m_glxContext = glXCreateContextAttribs(display, bestFbc, sharedContext, True, opengl_profile_attribute_list.data());
			if(nullptr == m_glxContext) {
				XDEVL_MODULEX_ERROR(XdevLOpenGLContextGLX, "glXCreateContext failed.\n");
				return RET_FAILED;
			}

			//
			// Check for other erros.
			//
			glXWaitGL();
			if(xdl_true == contextErrorOccured) {
				//
				m_glxContext = glXCreateContext(display, m_visualInfo, sharedContext, GL_TRUE);
			}

		} else {
			//
			// OK, not supported, let's use old function.
			//
			m_glxContext = glXCreateContext(display, m_visualInfo, sharedContext, GL_TRUE);
			if(nullptr == m_glxContext) {
				XDEVL_MODULEX_ERROR(XdevLOpenGLContextGLX, "glXCreateContext failed.\n");
				return RET_FAILED;
			}
		}


//		setEnableFSAA(xdl_true);

		//
		// Make it current.
		//
//		GLXWindow glxWindow = glXCreateWindow(display, bestFbc, window, nullptr);
//		GLXDrawable drawable = glxWindow;
//		glXMakeContextCurrent(display, drawable, drawable, m_glxContext);

		if(glXMakeCurrent(display, window, m_glxContext) == False) {
			return RET_FAILED;
		}

		return RET_SUCCESS;
	}