
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "gl/SkGLContext.h"

#include <X11/Xlib.h>
#include <GL/glx.h>
#include <GL/glu.h>

namespace {

/* Note: Skia requires glx 1.3 or newer */

/* This struct is taken from a mesa demo.  Please update as required */
static const struct { int major, minor; } gl_versions[] = {
   {1, 0},
   {1, 1},
   {1, 2},
   {1, 3},
   {1, 4},
   {1, 5},
   {2, 0},
   {2, 1},
   {3, 0},
   {3, 1},
   {3, 2},
   {3, 3},
   {4, 0},
   {4, 1},
   {4, 2},
   {4, 3},
   {4, 4},
   {0, 0} /* end of list */
};
#define NUM_GL_VERSIONS SK_ARRAY_COUNT(gl_versions)

static bool ctxErrorOccurred = false;
static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
    ctxErrorOccurred = true;
    return 0;
}

class GLXGLContext : public SkGLContext {
public:
    GLXGLContext();

    virtual ~GLXGLContext();

    virtual void makeCurrent() const SK_OVERRIDE;
    virtual void swapBuffers() const SK_OVERRIDE;
protected:
    virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
    virtual void destroyGLContext() SK_OVERRIDE;

private:
    GLXContext fContext;
    Display* fDisplay;
    Pixmap fPixmap;
    GLXPixmap fGlxPixmap;
};

GLXGLContext::GLXGLContext()
    : fContext(NULL)
    , fDisplay(NULL)
    , fPixmap(0)
    , fGlxPixmap(0) {
}

GLXGLContext::~GLXGLContext() {
    this->destroyGLContext();
}

void GLXGLContext::destroyGLContext() {
    if (fDisplay) {
        glXMakeCurrent(fDisplay, 0, 0);

        if (fContext) {
            glXDestroyContext(fDisplay, fContext);
            fContext = NULL;
        }

        if (fGlxPixmap) {
            glXDestroyGLXPixmap(fDisplay, fGlxPixmap);
            fGlxPixmap = 0;
        }

        if (fPixmap) {
            XFreePixmap(fDisplay, fPixmap);
            fPixmap = 0;
        }

        XCloseDisplay(fDisplay);
        fDisplay = NULL;
    }
}

const GrGLInterface* GLXGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
    fDisplay = XOpenDisplay(0);

    if (!fDisplay) {
        SkDebugf("Failed to open X display.\n");
        this->destroyGLContext();
        return NULL;
    }

    // Get a matching FB config
    static int visual_attribs[] = {
        GLX_X_RENDERABLE    , True,
        GLX_DRAWABLE_TYPE   , GLX_PIXMAP_BIT,
        None
    };

    int glx_major, glx_minor;

    // FBConfigs were added in GLX version 1.3.
    if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) ||
            ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) {
        SkDebugf("GLX version 1.3 or higher required.\n");
        this->destroyGLContext();
        return NULL;
    }

    //SkDebugf("Getting matching framebuffer configs.\n");
    int fbcount;
    GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay),
                                          visual_attribs, &fbcount);
    if (!fbc) {
        SkDebugf("Failed to retrieve a framebuffer config.\n");
        this->destroyGLContext();
        return NULL;
    }
    //SkDebugf("Found %d matching FB configs.\n", fbcount);

    // Pick the FB config/visual with the most samples per pixel
    //SkDebugf("Getting XVisualInfos.\n");
    int best_fbc = -1, best_num_samp = -1;

    int i;
    for (i = 0; i < fbcount; ++i) {
        XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]);
        if (vi) {
            int samp_buf, samples;
            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
            glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples);

            //SkDebugf("  Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d,"
            //       " SAMPLES = %d\n",
            //        i, (unsigned int)vi->visualid, samp_buf, samples);

            if (best_fbc < 0 || (samp_buf && samples > best_num_samp))
                best_fbc = i, best_num_samp = samples;
        }
        XFree(vi);
    }

    GLXFBConfig bestFbc = fbc[best_fbc];

    // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
    XFree(fbc);

    // Get a visual
    XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc);
    //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid);

    fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth);

    if (!fPixmap) {
        SkDebugf("Failed to create pixmap.\n");
        this->destroyGLContext();
        return NULL;
    }

    fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap);

    // Done with the visual info data
    XFree(vi);

    // Create the context

    // Install an X error handler so the application won't exit if GL 3.0
    // context allocation fails.
    //
    // Note this error handler is global.
    // All display connections in all threads of a process use the same
    // error handler, so be sure to guard against other threads issuing
    // X commands while this code is running.
    ctxErrorOccurred = false;
    int (*oldHandler)(Display*, XErrorEvent*) =
        XSetErrorHandler(&ctxErrorHandler);

    // Get the default screen's GLX extension list
    const char *glxExts = glXQueryExtensionsString(
        fDisplay, DefaultScreen(fDisplay)
    );


    // Check for the GLX_ARB_create_context extension string and the function.
    // If either is not present, use GLX 1.3 context creation method.
    if (!gluCheckExtension(reinterpret_cast<const GLubyte*>("GLX_ARB_create_context"),
                           reinterpret_cast<const GLubyte*>(glxExts))) {
        if (kGLES_GrGLStandard != forcedGpuAPI) {
            fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True);
        }
    } else {
        //SkDebugf("Creating context.\n");
        PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB =
            (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB");

        if (kGLES_GrGLStandard == forcedGpuAPI) {
            if (gluCheckExtension(
                    reinterpret_cast<const GLubyte*>("GLX_EXT_create_context_es2_profile"),
                    reinterpret_cast<const GLubyte*>(glxExts))) {
                static const int context_attribs_gles[] = {
                    GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
                    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
                    GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
                    None
                };
                fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True,
                                                      context_attribs_gles);
            }
        } else {
            // Well, unfortunately GLX will not just give us the highest context so instead we have
            // to do this nastiness
            for (i = NUM_GL_VERSIONS - 2; i > 0 ; i--) {
                /* don't bother below GL 3.0 */
                if (gl_versions[i].major == 3 && gl_versions[i].minor == 0) {
                    break;
                }
                // On Nvidia GPUs, to use Nv Path rendering we need a compatibility profile for the
                // time being.
                // TODO when Nvidia implements NVPR on Core profiles, we should start requesting
                // core here
                static const int context_attribs_gl[] = {
                      GLX_CONTEXT_MAJOR_VERSION_ARB, gl_versions[i].major,
                      GLX_CONTEXT_MINOR_VERSION_ARB, gl_versions[i].minor,
                      GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
                      None
                };
                fContext =
                        glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True, context_attribs_gl);

                // Sync to ensure any errors generated are processed.
                XSync(fDisplay, False);

                if (!ctxErrorOccurred && fContext) {
                    break;
                }
                // try again
                ctxErrorOccurred = false;
            }

            // Couldn't create GL 3.0 context.
            // Fall back to old-style 2.x context.
            // When a context version below 3.0 is requested,
            // implementations will return the newest context version
            // compatible with OpenGL versions less than version 3.0.
            if (ctxErrorOccurred || !fContext) {
                static const int context_attribs_gl_fallback[] = {
                    GLX_CONTEXT_MAJOR_VERSION_ARB, 1,
                    GLX_CONTEXT_MINOR_VERSION_ARB, 0,
                    None
                };

                ctxErrorOccurred = false;

                fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True,
                                                      context_attribs_gl_fallback);
            }
        }
    }

    // Sync to ensure any errors generated are processed.
    XSync(fDisplay, False);

    // Restore the original error handler
    XSetErrorHandler(oldHandler);

    if (ctxErrorOccurred || !fContext) {
        SkDebugf("Failed to create an OpenGL context.\n");
        this->destroyGLContext();
        return NULL;
    }

    // Verify that context is a direct context
    if (!glXIsDirect(fDisplay, fContext)) {
        //SkDebugf("Indirect GLX rendering context obtained.\n");
    } else {
        //SkDebugf("Direct GLX rendering context obtained.\n");
    }

    //SkDebugf("Making context current.\n");
    if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
      SkDebugf("Could not set the context.\n");
        this->destroyGLContext();
        return NULL;
    }

    const GrGLInterface* interface = GrGLCreateNativeInterface();
    if (!interface) {
        SkDebugf("Failed to create gl interface");
        this->destroyGLContext();
        return NULL;
    }
    return interface;
}

void GLXGLContext::makeCurrent() const {
    if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
        SkDebugf("Could not set the context.\n");
    }
}

void GLXGLContext::swapBuffers() const {
    glXSwapBuffers(fDisplay, fGlxPixmap);
}

} // anonymous namespace

SkGLContext* SkCreatePlatformGLContext() {
    return SkNEW(GLXGLContext);
}
