xdl_int XdevLOpenGLWGL::create(XdevLWindow* window) {

		if(window == NULL) {
			XDEVL_MODULE_ERROR("Parameter invalid.\n");
			return ERR_ERROR;
		}

		m_window = window;
		m_wnd = static_cast<HWND>(m_window->getInternal(XdevLInternalName("WIN32_HWND")));
		if ( m_wnd == NULL) {
			XDEVL_MODULE_ERROR("Get WIN32_HWND failed.\n");
			return ERR_ERROR;
		}

		if (initOpenGL() == ERR_ERROR) {
			XDEVL_MODULE_ERROR("Failed to initialize OpenGL.\n");
			return ERR_ERROR;
		}

		// Set vertical syncronisation.
		setVSync(getVSync());

		// TODO: This shouldn't be done maybe because it changes the initial state of the OpenGL context.
		glClearColor(1.0, 0.0, 0.0, 1.0);
		glClear(GL_COLOR_BUFFER_BIT);
		SwapBuffers(m_DC);

		return ERR_OK;
	}
	xdl_int XdevLBluetoothMacOSXImpl::readInfoFromXMLFile() {
		if(getMediator()->getXmlFilename() == NULL)
			return ERR_ERROR;

		TiXmlDocument xmlDocument;
		if(!xmlDocument.LoadFile(getMediator()->getXmlFilename())) {
			XDEVL_MODULE_ERROR("Could not parse xml file: " << getMediator()->getXmlFilename() << std::endl);
			return ERR_ERROR;
		}

		TiXmlHandle docHandle(&xmlDocument);
		TiXmlElement* root = docHandle.FirstChild(XdevLCorePropertiesName.c_str()).FirstChildElement("XdevLBluetooth").ToElement();
		if (!root) {
			XDEVL_MODULE_WARNING("<XdevLBluetooth> section not found. Using default values for the device.\n");
			return ERR_OK;
		}
		while(root != NULL) {
			if(root->Attribute("id")) {
				XdevLID id(root->Attribute("id"));
				if(getID() == id) {
					if (root->Attribute("device")) {
						m_deviceName = root->Attribute("device");
					}
				}
				root = root->NextSiblingElement();
			} else
				XDEVL_MODULE_ERROR("No 'id' attribute specified. Using default values for the device\n");
		}
		return ERR_OK;
	}
xdl_int XdevLCudaImpl::readModuleInformation(TiXmlDocument* document) {
	TiXmlHandle docHandle(document);
	TiXmlElement* root = docHandle.FirstChild(XdevLCorePropertiesName.c_str()).FirstChildElement("XdevLOpenGL").ToElement();

	if (!root) {
		XDEVL_MODULE_INFO("<XdevLCuda> section not found, skipping proccess.\n");
		return ERR_OK;
	}

	if(root->Attribute("id")){
		XdevLModuleId id(root->Attribute("id"));
		if(*getId() != id){
			return ERR_OK;
		}		
	}else{
		XDEVL_MODULE_ERROR("No 'id' attribute specified.");
		return ERR_ERROR;
	}

//	if (root->Attribute("framebuffer_depth")){
//		m_ColorDepth = xstd::from_string<xdl_int>(root->Attribute("framebuffer_depth"));
//		XDEVL_MODULE_INFO("Framebuffer depth request: " << m_ColorDepth << std::endl);
//	}

	return ERR_OK;
}
	xdl_int XdevLWindowWayland::createAnonymousFile(off_t size) {
		static const char tmp[] = "/weston-shared-XXXXXX";
		const char *path;
		char *name;
		int fd;

		path = getenv("XDG_RUNTIME_DIR");
		if(!path) {
			XDEVL_MODULE_ERROR("XDG_RUNTIME_DIR environment variable not found.\n");
			return -1;
		}

		name = (char*)malloc(strlen(path) + sizeof(tmp));
		if(!name) {
			return -1;
		}
		strcpy(name, path);
		strcat(name, tmp);

		fd = createTmpFileCloExec(name);

		free(name);

		if(fd < 0)
			return -1;

		if(ftruncate(fd, size) < 0) {
			close(fd);
			return -1;
		}

		return fd;
	}
	xdl_int XdevLOpenGLWGL::makeCurrent(XdevLWindow* window) {
		// Try To Activate The Rendering Context
		if (wglMakeCurrent(m_DC, m_RC) != TRUE) {
			XDEVL_MODULE_ERROR("wglMakeCurrent failed.\n");
			return ERR_ERROR;
		}
		return ERR_OK;
	}
	xdl_int XdevLOpenGLWGL::shutdown() {
		if (m_RC) {
			if (!wglMakeCurrent(NULL, NULL)) {
				XDEVL_MODULE_ERROR("wglMakeCurrent() failed.\n");
				return ERR_ERROR;
			}
			if (!wglDeleteContext( m_RC)) {
				XDEVL_MODULE_ERROR("wglDeleteContext() failed.\n");
				return ERR_ERROR;
			}
		}
		m_RC = NULL;
		if ( m_DC && !ReleaseDC( m_wnd, m_DC)) {
			XDEVL_MODULE_ERROR("ReleaseDC() failed.\n");
			return ERR_ERROR;
		}
		m_DC = NULL;
		return ERR_OK;
	}
	int XdevLOpenGLContextGLX::create(XdevLWindow* window, XdevLOpenGLContext* shareContext) {
		XDEVL_ASSERT(m_display == nullptr, "XdevLOpenGLContextGLX already created.");

		if(nullptr != shareContext) {
			m_shareContext = static_cast<XdevLOpenGLContextGLX*>(shareContext);
		}

		window->getDescriptor().registerDependency(this);

		m_display = static_cast<Display*>(window->getInternal(XdevLInternalName("X11_DISPLAY")));
		if(nullptr == m_display) {
			XDEVL_MODULE_ERROR("Could not get native X11 display information.\n");
			return RET_FAILED;
		}

		m_window = (Window)(window->getInternal(XdevLInternalName("X11_WINDOW")));
		if(None == m_window) {
			XDEVL_MODULE_ERROR("Could not get native X11 window information.\n");
			return RET_FAILED;
		}

		if(glXQueryVersion(m_display, &m_glxMajorVersion, &m_glxMinorVersion) == False) {
			XDEVL_MODULE_ERROR("glXQueryVersion failed.\n");
			return RET_FAILED;
		}

		if(initOpenGL(m_display, m_window) == RET_FAILED) {
			XDEVL_MODULE_ERROR("Failed to initialize OpenGL.\n");
			return RET_FAILED;
		}

		if(glXIsDirect(m_display, m_glxContext)) {
			XDEVL_MODULE_INFO("Direct Rendering supported.\n");

		} else {
			XDEVL_MODULE_WARNING("Direct Rendering not supported.\n");
		}

		setVSync(getVSync());

		return RET_SUCCESS;
	}
	xdl_int XdevLWindowWayland::createBuffer() {

		// Couldn't create anonymous file.
		m_fd = createAnonymousFile(getWidth() * getHeight() * 4);
		if(-1 == m_fd) {
			XDEVL_MODULE_ERROR("mmap failed\n");
			return ERR_ERROR;
		}

		// Couldn't map memory.
		m_shm_data = (xdl_uint8*)mmap(NULL, getWidth() * getHeight() * 4, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);
		if(m_shm_data == MAP_FAILED) {
			XDEVL_MODULE_ERROR("mmap failed\n");
			close(m_fd);
			return ERR_ERROR;
		}

		m_pool = wl_shm_create_pool(m_sharedMemory, m_fd, getWidth() * getHeight() * 4);
		m_buffer = wl_shm_pool_create_buffer(m_pool, 0, getWidth(), getHeight(), getWidth() * 4, WL_SHM_FORMAT_XRGB8888);
		wl_shm_pool_destroy(m_pool);

		return ERR_OK;
	}
xdl_int XdevLCudaImpl::init() {
	TiXmlDocument xmlDocument;

	if (!xmlDocument.LoadFile(getMediator()->getXmlFilename())) {
		XDEVL_MODULE_ERROR("Could not parse xml file: " << getMediator()->getXmlFilename() << std::endl);
		return ERR_ERROR;
	}

	if (readModuleInformation(&xmlDocument) != ERR_OK)
		return ERR_ERROR;


	cudaGetDevice(&m_devID);
  cudaGetDeviceProperties(&m_prop, m_devID);
	
	return ERR_OK;
}
Beispiel #10
0
	xdl_int XdevLFTDI::readInfoFromXMLFile() {
		if(getMediator()->getXmlFilename() == nullptr)
			return RET_FAILED;

		TiXmlDocument xmlDocument;
		if(!xmlDocument.LoadFile(getMediator()->getXmlFilename())) {
			XDEVL_MODULE_ERROR("Could not parse xml file: " << getMediator()->getXmlFilename() << std::endl);
			return RET_FAILED;
		}

		TiXmlHandle docHandle(&xmlDocument);
		TiXmlElement* root = docHandle.FirstChild(XdevLCorePropertiesName.c_str()).FirstChildElement("XdevLSerial").ToElement();
		if(!root) {
			XDEVL_MODULE_WARNING("<XdevLSerial> section not found. Using default values for the device.\n");
			return RET_SUCCESS;
		}

		while(root != nullptr) {
			if(root->Attribute("id")) {
				XdevLID id(root->Attribute("id"));
				if(getID() == id) {
					if(root->Attribute("device")) {
						m_deviceName = XdevLString(root->Attribute("device"));
					}
					if(root->Attribute("usb_in_size")) {
						std::istringstream ss(root->Attribute("usb_in_size"));
						ss >> m_usbInSize;
					}
					if(root->Attribute("usb_out_size")) {
						std::istringstream ss(root->Attribute("usb_out_size"));
						ss >> m_usbOutSize;
					}
					if(root->Attribute("latency_timer")) {
						std::istringstream ss(root->Attribute("latency_timer"));
						ss >> m_latencyTimer;
					}
	xdl_int XdevLOpenGLWGL::initOpenGL() {
		m_DC = GetDC(m_wnd);
		if(m_DC == NULL) {
			XDEVL_MODULE_ERROR("GetDC() failed.");
			return ERR_ERROR;
		}

		PIXELFORMATDESCRIPTOR pfd;
		memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
		pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
		pfd.nVersion = 1;
		pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
		pfd.iPixelType = PFD_TYPE_RGBA;
		pfd.cColorBits = m_attributes.color_buffer_size;
		pfd.cDepthBits = m_attributes.depth_size;
		pfd.cStencilBits = m_attributes.stencil_size;
		pfd.cRedBits = m_attributes.red_size;
		pfd.cGreenBits = m_attributes.green_size;
		pfd.cBlueBits = m_attributes.blue_size;
		pfd.cAlphaBits = m_attributes.alpha_size;
		pfd.iLayerType = PFD_MAIN_PLANE;

		int iPixelFormat = ChoosePixelFormat(m_DC, &pfd);
		if (FALSE == iPixelFormat) {
			XDEVL_MODULE_ERROR("ChoosePixelFormat failed.\n");
			return ERR_ERROR;
		}

		if (SetPixelFormat(m_DC, iPixelFormat, &pfd) != TRUE) {
			XDEVL_MODULE_ERROR("SetPixelFormat failed.\n");
			return ERR_ERROR;
		}

		// Create the old style context (OpenGL 2.1 and before)
		HGLRC hRC = wglCreateContext(m_DC);
		wglMakeCurrent(m_DC, hRC);

		wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
		wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
		wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");

		wglMakeCurrent(nullptr, nullptr);
		wglDeleteContext(hRC);

		if (wglCreateContextAttribsARB) {
			const int iPixelFormatAttribList[] = {
				WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
				WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
				WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
				WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
				WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
				WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB,
				WGL_COLOR_BITS_ARB, 32,
				WGL_DEPTH_BITS_ARB, 24,
				WGL_STENCIL_BITS_ARB, 8,
				WGL_ACCUM_BITS_ARB, 0,
				WGL_RED_BITS_ARB, m_attributes.red_size,
				WGL_GREEN_BITS_ARB, m_attributes.green_size,
				WGL_BLUE_BITS_ARB, m_attributes.blue_size,
				WGL_ALPHA_BITS_ARB, m_attributes.alpha_size,
				0 // End of attributes list
			};

			int iPixelFormat, iNumFormats;
			if (wglChoosePixelFormatARB(m_DC, iPixelFormatAttribList, NULL, 1, &iPixelFormat, (UINT*)&iNumFormats) != TRUE) {
				XDEVL_MODULE_ERROR("wglChoosePixelFormatARB failed.\n");
				return ERR_ERROR;
			}

			// PFD seems to be only redundant parameter now
			if (SetPixelFormat(m_DC, iPixelFormat, &pfd) != TRUE) {
				XDEVL_MODULE_ERROR("SetPixelFormat failed.\n");
				return ERR_ERROR;
			}


			//
			// Set the core profile attributes.
			//
			std::vector<xdl_int> contextAttributes;
			contextAttributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
			contextAttributes.push_back(m_attributes.context_major_version);
			contextAttributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
			contextAttributes.push_back(m_attributes.context_minor_version);

			contextAttributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
			if (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_CORE_PROFILE) {
				contextAttributes.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB);
			} else if (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_COMPATIBILITY) {
				contextAttributes.push_back(WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
			} else if (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_ES1) {
				XDEVL_MODULE_ERROR("Not supported WGL_CONTEXT_PROFILE_MASK_ARB .\n");
				return ERR_ERROR;
			} else if (m_attributes.context_profile_mask == XDEVL_OPENGL_CONTEXT_ES2) {
				XDEVL_MODULE_ERROR("Not supported WGL_CONTEXT_PROFILE_MASK_ARB .\n");
				return ERR_ERROR;
			} else {
				XDEVL_MODULE_ERROR("Not supported WGL_CONTEXT_PROFILE_MASK_ARB .\n");
				return ERR_ERROR;
			}

			//
			// Set the WGL_CONTEXT_FLAGS_ARB
			//
			if (m_attributes.context_flags != XDEVL_OPENGL_CONTEXT_FLAGS_NONE || (m_debugMode == xdl_true)) {
				contextAttributes.push_back(WGL_CONTEXT_FLAGS_ARB);
				if (m_debugMode == xdl_true) {
					contextAttributes.push_back(WGL_CONTEXT_DEBUG_BIT_ARB);
				}
				if (m_attributes.context_flags == XDEVL_OPENGL_CONTEXT_FLAGS_FORWARD_COMPATIBLE_BIT) {
					contextAttributes.push_back(WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
				}
			}

			contextAttributes.push_back(0);


			m_RC = wglCreateContextAttribsARB(m_DC, 0, contextAttributes.data());
			if (nullptr == m_RC) {
				XDEVL_MODULE_ERROR("wglCreateContextAttribsARB failed.\n");
				return ERR_ERROR;
			}
			// If everything went OK
			if (wglMakeCurrent(m_DC, m_RC) != TRUE) {
				XDEVL_MODULE_ERROR("wglMakeCurrent failed.\n");
				return ERR_ERROR;
			}

		} else {
			// Are We Able To Get A Rendering Context?
			m_RC = wglCreateContext(m_DC);
			if (nullptr == m_RC) {
				XDEVL_MODULE_ERROR("Could not create GL context.\n");
				return ERR_ERROR;
			}
		}
		return ERR_OK;
	}
	xdl_int XdevLWindowWayland::initializeEGL() {

		static const EGLint context_attribs[] = {
			EGL_CONTEXT_CLIENT_VERSION, 2,
			EGL_NONE
		};
		const char *extensions;

		EGLint config_attribs[] = {
			EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
			EGL_RED_SIZE, 1,
			EGL_GREEN_SIZE, 1,
			EGL_BLUE_SIZE, 1,
			EGL_ALPHA_SIZE, 1,
			EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
			EGL_NONE
		};

		EGLint major, minor, n, count, i, size;


		m_egl.m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)display);
		if(m_egl.m_eglDisplay == EGL_NO_DISPLAY) {
			XDEVL_MODULE_ERROR("Can't create egl display\n");
			return ERR_ERROR;
		} else {
			XDEVL_MODULE_SUCCESS("Created egl display\n");
		}

		EGLBoolean ret = eglInitialize(m_egl.m_eglDisplay, &major, &minor);
		if(ret != EGL_TRUE) {
			XDEVL_MODULE_ERROR("Can't initialize egl display\n");
			return ERR_ERROR;
		}

		ret = eglBindAPI(EGL_OPENGL_ES_API);
		if(ret != EGL_TRUE) {
			XDEVL_MODULE_ERROR("Can't bind egl API to EGL_OPENGL_ES_API\n");
			return ERR_ERROR;
		}

		if(!eglGetConfigs(m_egl.m_eglDisplay, nullptr, 0, &count) || count < 1) {
			return ERR_ERROR;
		}

		EGLConfig* configs = new EGLConfig[count];

		ret = eglChooseConfig(m_egl.m_eglDisplay, config_attribs, configs, count, &n);
		if(ret != EGL_TRUE) {
			return ERR_ERROR;
		}

		// TODO This is at the moment for only test purpose. As you can see only the first
		// config is used.
		for(i = 0; i < n; i++) {
			eglGetConfigAttrib(m_egl.m_eglDisplay, configs[i], EGL_BUFFER_SIZE, &size);
			printf("Buffer size for config %d is %d\n", i, size);
			// For now just use the first one.
			m_egl.m_eglConfig = configs[0];

		}
		delete [] configs;

		// If we do not found any configs stop here.
		if(m_egl.m_eglConfig == nullptr) {
			return ERR_ERROR;
		}

		m_egl.m_eglContext = eglCreateContext(m_egl.m_eglDisplay, m_egl.m_eglConfig, EGL_NO_CONTEXT, context_attribs);
		if(m_egl.m_eglContext == nullptr) {
			return ERR_ERROR;
		}
	}
	xdl_int XdevLWindowWayland::init() {

		XdevLWindowImpl::init();

		wl_display_roundtrip(display);

		if(m_compositor == nullptr) {
			XDEVL_MODULE_ERROR("Wayland compositor object not received.\n");
			return ERR_ERROR;
		} else {
			XDEVL_MODULE_SUCCESS("Received Wayland compositor object proxy\n");
		}

		if(m_shell == nullptr) {
			XDEVL_MODULE_ERROR("Wayland shell object not received.\n");
			return ERR_ERROR;
		} else {
			XDEVL_MODULE_SUCCESS("Received Wayland shell object proxy\n");
		}

		if(m_sharedMemory == nullptr) {
			XDEVL_MODULE_ERROR("Wayland shared memory object not received.\n");
			return ERR_ERROR;
		} else {
			XDEVL_MODULE_SUCCESS("Received Wayland shared memory object proxy\n");
		}
		//
		// Now we create the surface we can see on the screen.
		//
		m_surface = wl_compositor_create_surface(m_compositor);
		if(m_surface == nullptr) {
			XDEVL_MODULE_ERROR("Can't create Wayland surface\n");
			return ERR_ERROR;
		} else {
			XDEVL_MODULE_SUCCESS("Created surface\n");
		}
		wl_surface_set_user_data(m_surface, this);

		m_shellSurface = wl_shell_get_shell_surface(m_shell, m_surface);
		if(m_shellSurface == nullptr) {
			XDEVL_MODULE_ERROR("Can't create Wayland shell surface\n");
			return ERR_ERROR;
		} else {
			XDEVL_MODULE_SUCCESS("Created shell surface\n");
		}
		wl_shell_surface_add_listener(m_shellSurface, &shell_surface_listener, this);

		// Bring the surface to the front.
		wl_shell_surface_set_toplevel(m_shellSurface);


//		m_frameCallback = wl_surface_frame(m_surface);
//		wl_callback_add_listener(m_frameCallback, &frame_listener, this);

		createOpaqueRegion(m_attribute.position.x, m_attribute.position.y, m_attribute.size.width, m_attribute.size.height);

		xdl_int ret = initializeEGL();
		if(ret == ERR_ERROR) {
			XDEVL_MODULE_ERROR("Initializing EGL failed.\n");
			return ERR_ERROR;
		}

		m_egl.m_eglWindow = wl_egl_window_create(m_surface, getWidth(), getHeight());
		if(m_egl.m_eglWindow == EGL_NO_SURFACE) {
			XDEVL_MODULE_ERROR("Can't create egl window\n");
			return ERR_ERROR;
		} else {
			XDEVL_MODULE_SUCCESS("Created egl window\n");
		}

		m_egl.m_eglSurface = eglCreateWindowSurface(m_egl.m_eglDisplay, m_egl.m_eglConfig, m_egl.m_eglWindow, nullptr);

		if(!eglMakeCurrent(m_egl.m_eglDisplay, m_egl.m_eglSurface, m_egl.m_eglSurface, m_egl.m_eglContext)) {
			XDEVL_MODULE_ERROR("eglMakeCurrent failed\n");
		}
		glClearColor((1.0f/255.0)*m_backgroundColor[0], (1.0f/255.0)*m_backgroundColor[1], (1.0f/255.0)*m_backgroundColor[2], (1.0f/255.0)*m_backgroundColor[3]);
		glClear(GL_COLOR_BUFFER_BIT);
		glFlush();

		if(!eglSwapBuffers(m_egl.m_eglDisplay, m_egl.m_eglSurface)) {
			XDEVL_MODULE_ERROR("eglSwapBuffers failed\n");
		}

		wl_display_flush(display);

		return ERR_OK;
	}
	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;
	}