/*
    This file is part of Mitsuba, a physically based rendering system.

    Copyright (c) 2007-2011 by Wenzel Jakob and others.

    Mitsuba is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License Version 3
    as published by the Free Software Foundation.

    Mitsuba is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <mitsuba/hw/glxdevice.h>

#ifndef GLX_ARB_multisample
#define GLX_ARB_multisample
#define GLX_SAMPLE_BUFFERS_ARB		100000
#define GLX_SAMPLES_ARB				100001
#endif

MTS_NAMESPACE_BEGIN

GLXDevice::GLXDevice(X11Session *session)
 : X11Device(session) {
}

GLXDevice::~GLXDevice() {
	if (m_initialized)
		shutdown();
}

void GLXDevice::flip() {
	Assert(m_initialized);

	Device::flip();

	X11Session *session = static_cast<X11Session *>(getSession());
	glFinish();
	if (m_doubleBuffer) 
		glXSwapBuffers(session->m_display, m_window);
}

XVisualInfo *GLXDevice::createVisual() {
	int attribs[64], i=0;
	X11Session *session = static_cast<X11Session *>(getSession());

	if (!session->m_hasGLX)
        Log(EError, "GLX support is required for hardware rendering!");

	attribs[i++] = GLX_RGBA;
	attribs[i++] = GLX_RED_SIZE; attribs[i++] = m_redBits;
	attribs[i++] = GLX_GREEN_SIZE; attribs[i++] = m_greenBits;
	attribs[i++] = GLX_BLUE_SIZE; attribs[i++] = m_blueBits;
	attribs[i++] = GLX_ALPHA_SIZE; attribs[i++] = m_alphaBits;
	attribs[i++] = GLX_DEPTH_SIZE; attribs[i++] = m_depthBits;
	attribs[i++] = GLX_STENCIL_SIZE; attribs[i++] = m_stencilBits;

	if (m_doubleBuffer) {
		attribs[i++] = GLX_DOUBLEBUFFER;
	}

	if (m_fsaa > 1) {
		attribs[i++] = GLX_SAMPLE_BUFFERS_ARB; attribs[i++] = 1;
		attribs[i++] = GLX_SAMPLES_ARB; attribs[i++] = m_fsaa;
	}

	attribs[i] = None;

	XVisualInfo *visinfo = glXChooseVisual(session->m_display, session->m_screen, attribs);

    if (visinfo == NULL)
        Log(EError, "Could not find a matching visual!");

	return visinfo;
}

MTS_IMPLEMENT_CLASS(GLXDevice, false, X11Device)
MTS_NAMESPACE_END
