void SWRenderDisplayWindowProvider::create(DisplayWindowSite *new_site, const DisplayWindowDescription &description)
{
	site = new_site;
	flip_timer_set = false;

	refresh_rate = description.get_refresh_rate();
	if (!refresh_rate)	// Default the refresh rate to 100 if not defined
		refresh_rate = 100;
	swap_interval = description.get_swap_interval();

#ifdef WIN32
	window.create(site, description);
#elif !defined(__APPLE__)
	::Display *disp = window.get_display();

	int bpp = 24;
	XVisualInfo visual_info;
	int screen =  DefaultScreen(disp); //RootWindow(disp,  0);

	if (XMatchVisualInfo(disp, screen, 24, TrueColor, &visual_info)) {bpp = 24;} 
	else if (XMatchVisualInfo(disp, screen, 16, TrueColor, &visual_info)) {bpp = 16;}
	else if (XMatchVisualInfo(disp, screen, 15, TrueColor, &visual_info)) {bpp = 15;}
	else if (XMatchVisualInfo(disp, screen, 32, TrueColor, &visual_info)) {bpp = 32;}
	else if (XMatchVisualInfo(disp, screen, 8, PseudoColor, &visual_info)) {bpp = 8;}
	else if (XMatchVisualInfo(disp, screen, 8, GrayScale, &visual_info)) {bpp = 8;}
	else if (XMatchVisualInfo(disp, screen, 8, StaticGray, &visual_info)) {bpp = 8;}
	else if (XMatchVisualInfo(disp, screen, 1, StaticGray, &visual_info)) {bpp = 1;}
	else { throw Exception("Cannot match visual info"); }

	window.create(&visual_info, site, description);
#endif
	gc = GraphicContext(new SWRenderGraphicContextProvider(this));
}
	void OpenGLWindowProvider::create(DisplayWindowSite *new_site, const DisplayWindowDescription &desc)
	{
		window_handle = desc.get_handle();
		if (window_handle.window == nullptr)
			throw Exception("Window handle must exist in the display description");

		ANativeWindow *window = window_handle.window;

		const EGLint attribs[] = {
			EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
			EGL_BLUE_SIZE, 8,
			EGL_GREEN_SIZE, 8,
			EGL_RED_SIZE, 8,
			EGL_NONE
		};
		EGLint format;
		EGLint numConfigs;
		EGLConfig config;

		display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

		eglInitialize(display, 0, 0);

		/* Here, the application chooses the configuration it desires. In this
		* sample, we have a very simplified selection process, where we pick
		* the first EGLConfig that matches our criteria */
		if (!eglChooseConfig(display, attribs, &config, 1, &numConfigs))
			throw Exception("eglChooseConfig failed");
		if (numConfigs < 1)
			throw Exception("Found configs failed");

		/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
		* guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
		* As soon as we picked a EGLConfig, we can safely reconfigure the
		* ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
		eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);

		ANativeWindow_setBuffersGeometry(window, 0, 0, format);

		surface = eglCreateWindowSurface(display, config, window, NULL);
		if (surface == EGL_NO_SURFACE)
			throw Exception("eglCreateWindowSurface failed");

		context = eglCreateContext(display, config, NULL, NULL);
		if (context == EGL_NO_CONTEXT)
			throw Exception("eglCreateWindowSurface failed");

		if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
		{
			throw Exception("Unable to eglMakeCurrent");
		}
		bool use_gl3;
		int desc_version_major = opengl_desc.get_version_major();
		int desc_version_minor = opengl_desc.get_version_minor();

		// Do not attempt GL3, if not requested that version
		if (desc_version_major < 3)
		{
			use_gl3 = false;
		}
		else if (!opengl_desc.get_allow_lower_versions())	// Else, if we do not allow lower versions, only attempt GL3
		{
			use_gl3 = true;
		}
		else
		{
			// Choose the target depending on the current opengl version
			int gl_version_major;
			int gl_version_minor;
			get_opengl_version(gl_version_major, gl_version_minor);
			if (gl_version_major < 3)
			{
				use_gl3 = false;
			}
			else
			{
				use_gl3 = true;
			}

		}

		if (use_gl3)
		{
			using_gl3 = true;
			gc = GraphicContext(new GL3GraphicContextProvider(this));
		}
		else
		{
			using_gl3 = false;
			gc = GraphicContext(new GL1GraphicContextProvider(this));
		}
		swap_interval = desc.get_swap_interval();
		if (swap_interval != -1)
			eglSwapInterval(display, swap_interval);

	}
	void OpenGLWindowProvider::create(DisplayWindowSite *new_site, const DisplayWindowDescription &desc)
	{
		site = new_site;
		fullscreen = desc.is_fullscreen();

		win32_window.create(site, desc);

		if (!opengl_context)
		{
			HWND handle = win32_window.get_hwnd();
			dwm_layered = false;

			if (desc.is_layered() && !DwmFunctions::is_composition_enabled())
			{
				create_shadow_window(handle);
			}
			else
			{
				if (desc.is_layered())
					dwm_layered = true;
			}

			desc.is_layered() ? double_buffered = false : double_buffered = true;	// Only can use Layered windows that are single buffered with OpenGL (via shadow window) ( PFD_DOUBLEBUFFER_DONTCARE set in OpenGLCreationHelper::set_multisampling_pixel_format)

			device_context = GetDC(handle);

			HGLRC share_context = get_share_context();

			OpenGLCreationHelper helper(handle, device_context);
			helper.set_multisampling_pixel_format(desc);

			int gl_major = opengl_desc.get_version_major();
			int gl_minor = opengl_desc.get_version_minor();
			if (opengl_desc.get_allow_lower_versions() == false)
			{
				opengl_context = helper.create_opengl3_context(share_context, gl_major, gl_minor, opengl_desc);
				if (!opengl_context)
					throw Exception(string_format("This application requires OpenGL %1.%2 or above. Try updating your drivers, or upgrade to a newer graphics card.", gl_major, gl_minor));
			}
			else
			{
				static const char opengl_version_list[] =
				{
					// Clanlib supported version pairs
					4, 5,
					4, 4,
					4, 3,
					4, 2,
					4, 1,
					4, 0,
					3, 3,
					3, 2,
					3, 1,
					3, 0,
					0, 0,	// End of list
				};

				const char *opengl_version_list_ptr = opengl_version_list;
				do
				{
					int major = *(opengl_version_list_ptr++);
					if (major == 0)
						break;

					int minor = *(opengl_version_list_ptr++);

					// Find the appropriate version in the list
					if (major > gl_major)
						continue;

					if (major == gl_major)
					{
						if (minor > gl_minor)
							continue;
					}

					opengl_context = helper.create_opengl3_context(share_context, major, minor, opengl_desc);
				} while (!opengl_context);

				if (!opengl_context)
					opengl_context = helper.create_opengl2_context(share_context);

				if (!opengl_context)
					throw Exception("This application requires OpenGL. Try updating your drivers, or upgrade to a newer graphics card.");

			}

			bool use_gl3;
			int desc_version_major = opengl_desc.get_version_major();
			int desc_version_minor = opengl_desc.get_version_minor();

			// Do not attempt GL3, if not requested that version
			if (desc_version_major < 3)
			{
				use_gl3 = false;
			}
			else if (!opengl_desc.get_allow_lower_versions())	// Else, if we do not allow lower versions, only attempt GL3
			{
				use_gl3 = true;
			}
			else
			{
				// Choose the target depending on the current opengl version
				int gl_version_major;
				int gl_version_minor;
				get_opengl_version(gl_version_major, gl_version_minor);
				if (gl_version_major < 3)
				{
					use_gl3 = false;
				}
				else
				{
					use_gl3 = true;
				}

			}

			if (use_gl3)
			{
				using_gl3 = true;
				gc = GraphicContext(new GL3GraphicContextProvider(this));
			}
			else
			{
				using_gl3 = false;
				gc = GraphicContext(new GL1GraphicContextProvider(this));
			}
		}

		wglSwapIntervalEXT = (ptr_wglSwapIntervalEXT)OpenGL::get_proc_address("wglSwapIntervalEXT");
		swap_interval = desc.get_swap_interval();
		if (wglSwapIntervalEXT && swap_interval != -1)
			wglSwapIntervalEXT(swap_interval);
	}