/*
 * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#ifndef HEADLESS

#include <stdlib.h>
#include <string.h>

#include "sun_java2d_SunGraphics2D.h"

#include "jlong.h"
#include "jni_util.h"
#include "OGLContext.h"
#include "OGLRenderQueue.h"
#include "OGLSurfaceData.h"
#include "GraphicsPrimitiveMgr.h"
#include "Region.h"

/**
 * The following methods are implemented in the windowing system (i.e. GLX
 * and WGL) source files.
 */
extern jboolean OGLSD_InitOGLWindow(JNIEnv *env, OGLSDOps *oglsdo);
extern OGLContext *OGLSD_MakeOGLContextCurrent(JNIEnv *env,
                                               OGLSDOps *srcOps,
                                               OGLSDOps *dstOps);

/**
 * This table contains the standard blending rules (or Porter-Duff compositing
 * factors) used in glBlendFunc(), indexed by the rule constants from the
 * AlphaComposite class.
 */
OGLBlendRule StdBlendRules[] = {
    { GL_ZERO,                GL_ZERO                }, /* 0 - Nothing      */
    { GL_ZERO,                GL_ZERO                }, /* 1 - RULE_Clear   */
    { GL_ONE,                 GL_ZERO                }, /* 2 - RULE_Src     */
    { GL_ONE,                 GL_ONE_MINUS_SRC_ALPHA }, /* 3 - RULE_SrcOver */
    { GL_ONE_MINUS_DST_ALPHA, GL_ONE                 }, /* 4 - RULE_DstOver */
    { GL_DST_ALPHA,           GL_ZERO                }, /* 5 - RULE_SrcIn   */
    { GL_ZERO,                GL_SRC_ALPHA           }, /* 6 - RULE_DstIn   */
    { GL_ONE_MINUS_DST_ALPHA, GL_ZERO                }, /* 7 - RULE_SrcOut  */
    { GL_ZERO,                GL_ONE_MINUS_SRC_ALPHA }, /* 8 - RULE_DstOut  */
    { GL_ZERO,                GL_ONE                 }, /* 9 - RULE_Dst     */
    { GL_DST_ALPHA,           GL_ONE_MINUS_SRC_ALPHA }, /*10 - RULE_SrcAtop */
    { GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA           }, /*11 - RULE_DstAtop */
    { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /*12 - RULE_AlphaXor*/
};

/** Evaluates to "front" or "back", depending on the value of buf. */
#define OGLC_ACTIVE_BUFFER_NAME(buf) \
    (buf == GL_FRONT || buf == GL_COLOR_ATTACHMENT0_EXT) ? "front" : "back"

/**
 * Initializes the viewport and projection matrix, effectively positioning
 * the origin at the top-left corner of the surface.  This allows Java 2D
 * coordinates to be passed directly to OpenGL, which is typically based on
 * a bottom-right coordinate system.  This method also sets the appropriate
 * read and draw buffers.
 */
static void
OGLContext_SetViewport(OGLSDOps *srcOps, OGLSDOps *dstOps)
{
    jint width = dstOps->width;
    jint height = dstOps->height;

    J2dTraceLn4(J2D_TRACE_INFO,
                "OGLContext_SetViewport: w=%d h=%d read=%s draw=%s",
                width, height,
                OGLC_ACTIVE_BUFFER_NAME(srcOps->activeBuffer),
                OGLC_ACTIVE_BUFFER_NAME(dstOps->activeBuffer));

    // set the viewport and projection matrix
    j2d_glViewport(dstOps->xOffset, dstOps->yOffset,
                   (GLsizei)width, (GLsizei)height);
    j2d_glMatrixMode(GL_PROJECTION);
    j2d_glLoadIdentity();
    j2d_glOrtho(0.0, (GLdouble)width, (GLdouble)height, 0.0, -1.0, 1.0);

    // set the active read and draw buffers
    j2d_glReadBuffer(srcOps->activeBuffer);
    j2d_glDrawBuffer(dstOps->activeBuffer);

    // set the color mask to enable alpha channel only when necessary
    j2d_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, (GLboolean)!dstOps->isOpaque);
}

/**
 * Initializes the alpha channel of the current surface so that it contains
 * fully opaque alpha values.
 */
static void
OGLContext_InitAlphaChannel()
{
    GLboolean scissorEnabled;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_InitAlphaChannel");

    // it is possible for the scissor test to be enabled at this point;
    // if it is, disable it temporarily since it can affect the glClear() op
    scissorEnabled = j2d_glIsEnabled(GL_SCISSOR_TEST);
    if (scissorEnabled) {
        j2d_glDisable(GL_SCISSOR_TEST);
    }

    // set the color mask so that we only affect the alpha channel
    j2d_glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);

    // clear the color buffer so that the alpha channel is fully opaque
    j2d_glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    j2d_glClear(GL_COLOR_BUFFER_BIT);

    // restore the color mask (as it was set in OGLContext_SetViewport())
    j2d_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);

    // re-enable scissor test, only if it was enabled earlier
    if (scissorEnabled) {
        j2d_glEnable(GL_SCISSOR_TEST);
    }
}

/**
 * Fetches the OGLContext associated with the given destination surface,
 * makes the context current for those surfaces, updates the destination
 * viewport, and then returns a pointer to the OGLContext.
 */
OGLContext *
OGLContext_SetSurfaces(JNIEnv *env, jlong pSrc, jlong pDst)
{
    OGLSDOps *srcOps = (OGLSDOps *)jlong_to_ptr(pSrc);
    OGLSDOps *dstOps = (OGLSDOps *)jlong_to_ptr(pDst);
    OGLContext *oglc = NULL;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_SetSurfaces");

    if (srcOps == NULL || dstOps == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLContext_SetSurfaces: ops are null");
        return NULL;
    }

    J2dTraceLn2(J2D_TRACE_VERBOSE, "  srctype=%d dsttype=%d",
                srcOps->drawableType, dstOps->drawableType);

    if (dstOps->drawableType == OGLSD_TEXTURE) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLContext_SetSurfaces: texture cannot be used as destination");
        return NULL;
    }

    if (dstOps->drawableType == OGLSD_UNDEFINED) {
        // initialize the surface as an OGLSD_WINDOW
        if (!OGLSD_InitOGLWindow(env, dstOps)) {
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                "OGLContext_SetSurfaces: could not init OGL window");
            return NULL;
        }
    }

    // make the context current
    oglc = OGLSD_MakeOGLContextCurrent(env, srcOps, dstOps);
    if (oglc == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLContext_SetSurfaces: could not make context current");
        return NULL;
    }

    // update the viewport
    OGLContext_SetViewport(srcOps, dstOps);

    // perform additional one-time initialization, if necessary
    if (dstOps->needsInit) {
        if (dstOps->isOpaque) {
            // in this case we are treating the destination as opaque, but
            // to do so, first we need to ensure that the alpha channel
            // is filled with fully opaque values (see 6319663)
            OGLContext_InitAlphaChannel();
        }
        dstOps->needsInit = JNI_FALSE;
    }

    return oglc;
}

/**
 * Resets the current clip state (disables both scissor and depth tests).
 */
void
OGLContext_ResetClip(OGLContext *oglc)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_ResetClip");

    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);

    j2d_glDisable(GL_SCISSOR_TEST);
    j2d_glDisable(GL_DEPTH_TEST);
}

/**
 * Sets the OpenGL scissor bounds to the provided rectangular clip bounds.
 */
void
OGLContext_SetRectClip(OGLContext *oglc, OGLSDOps *dstOps,
                       jint x1, jint y1, jint x2, jint y2)
{
    jint width = x2 - x1;
    jint height = y2 - y1;

    J2dTraceLn4(J2D_TRACE_INFO,
                "OGLContext_SetRectClip: x=%d y=%d w=%d h=%d",
                x1, y1, width, height);

    RETURN_IF_NULL(dstOps);
    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);

    if ((width < 0) || (height < 0)) {
        // use an empty scissor rectangle when the region is empty
        width = 0;
        height = 0;
    }

    j2d_glDisable(GL_DEPTH_TEST);
    j2d_glEnable(GL_SCISSOR_TEST);

    // the scissor rectangle is specified using the lower-left
    // origin of the clip region (in the framebuffer's coordinate
    // space), so we must account for the x/y offsets of the
    // destination surface
    j2d_glScissor(dstOps->xOffset + x1,
                  dstOps->yOffset + dstOps->height - (y1 + height),
                  width, height);
}

/**
 * Sets up a complex (shape) clip using the OpenGL depth buffer.  This
 * method prepares the depth buffer so that the clip Region spans can
 * be "rendered" into it.  The depth buffer is first cleared, then the
 * depth func is setup so that when we render the clip spans,
 * nothing is rendered into the color buffer, but for each pixel that would
 * be rendered, a non-zero value is placed into that location in the depth
 * buffer.  With depth test enabled, pixels will only be rendered into the
 * color buffer if the corresponding value at that (x,y) location in the
 * depth buffer differs from the incoming depth value.
 */
void
OGLContext_BeginShapeClip(OGLContext *oglc)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_BeginShapeClip");

    RETURN_IF_NULL(oglc);
    RESET_PREVIOUS_OP();

    j2d_glDisable(GL_SCISSOR_TEST);

    // enable depth test and clear depth buffer so that depth values are at
    // their maximum; also set the depth func to GL_ALWAYS so that the
    // depth values of the clip spans are forced into the depth buffer
    j2d_glEnable(GL_DEPTH_TEST);
    j2d_glClearDepth(1.0);
    j2d_glClear(GL_DEPTH_BUFFER_BIT);
    j2d_glDepthFunc(GL_ALWAYS);

    // disable writes into the color buffer while we set up the clip
    j2d_glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

    // save current transform
    j2d_glMatrixMode(GL_MODELVIEW);
    j2d_glPushMatrix();

    // use identity transform plus slight translation in the z-axis when
    // setting the clip spans; this will push the clip spans (which would
    // normally be at z=0) to the z=1 plane to give them some depth
    j2d_glLoadIdentity();
    j2d_glTranslatef(0.0f, 0.0f, 1.0f);
}

/**
 * Finishes setting up the shape clip by resetting the depth func
 * so that future rendering operations will once again be written into the
 * color buffer (while respecting the clip set up in the depth buffer).
 */
void
OGLContext_EndShapeClip(OGLContext *oglc, OGLSDOps *dstOps)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_EndShapeClip");

    RETURN_IF_NULL(dstOps);
    RETURN_IF_NULL(oglc);
    RESET_PREVIOUS_OP();

    // restore transform
    j2d_glPopMatrix();

    // re-enable writes into the color buffer
    j2d_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, (GLboolean)!dstOps->isOpaque);

    // enable the depth test so that only fragments within the clip region
    // (i.e. those fragments whose z-values are >= the values currently
    // stored in the depth buffer) are rendered
    j2d_glDepthFunc(GL_GEQUAL);
}

/**
 * Initializes the OpenGL state responsible for applying extra alpha.  This
 * step is only necessary for any operation that uses glDrawPixels() or
 * glCopyPixels() with a non-1.0f extra alpha value.  Since the source is
 * always premultiplied, we apply the extra alpha value to both alpha and
 * color components using GL_*_SCALE.
 */
void
OGLContext_SetExtraAlpha(jfloat ea)
{
    J2dTraceLn1(J2D_TRACE_INFO, "OGLContext_SetExtraAlpha: ea=%f", ea);

    j2d_glPixelTransferf(GL_ALPHA_SCALE, ea);
    j2d_glPixelTransferf(GL_RED_SCALE, ea);
    j2d_glPixelTransferf(GL_GREEN_SCALE, ea);
    j2d_glPixelTransferf(GL_BLUE_SCALE, ea);
}

/**
 * Resets all OpenGL compositing state (disables blending and logic
 * operations).
 */
void
OGLContext_ResetComposite(OGLContext *oglc)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_ResetComposite");

    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);

    // disable blending and XOR mode
    if (oglc->compState == sun_java2d_SunGraphics2D_COMP_ALPHA) {
        j2d_glDisable(GL_BLEND);
    } else if (oglc->compState == sun_java2d_SunGraphics2D_COMP_XOR) {
        j2d_glDisable(GL_COLOR_LOGIC_OP);
        j2d_glDisable(GL_ALPHA_TEST);
    }

    // set state to default values
    oglc->compState = sun_java2d_SunGraphics2D_COMP_ISCOPY;
    oglc->extraAlpha = 1.0f;
}

/**
 * Initializes the OpenGL blending state.  XOR mode is disabled and the
 * appropriate blend functions are setup based on the AlphaComposite rule
 * constant.
 */
void
OGLContext_SetAlphaComposite(OGLContext *oglc,
                             jint rule, jfloat extraAlpha, jint flags)
{
    J2dTraceLn1(J2D_TRACE_INFO,
                "OGLContext_SetAlphaComposite: flags=%d", flags);

    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);

    // disable XOR mode
    if (oglc->compState == sun_java2d_SunGraphics2D_COMP_XOR) {
        j2d_glDisable(GL_COLOR_LOGIC_OP);
        j2d_glDisable(GL_ALPHA_TEST);
    }

    // we can safely disable blending when:
    //   - comp is SrcNoEa or SrcOverNoEa, and
    //   - the source is opaque
    // (turning off blending can have a large positive impact on
    // performance)
    if ((rule == RULE_Src || rule == RULE_SrcOver) &&
        (extraAlpha == 1.0f) &&
        (flags & OGLC_SRC_IS_OPAQUE))
    {
        J2dTraceLn1(J2D_TRACE_VERBOSE,
                    "  disabling alpha comp: rule=%d ea=1.0 src=opq", rule);
        j2d_glDisable(GL_BLEND);
    } else {
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "  enabling alpha comp: rule=%d ea=%f", rule, extraAlpha);
        j2d_glEnable(GL_BLEND);
        j2d_glBlendFunc(StdBlendRules[rule].src, StdBlendRules[rule].dst);
    }

    // update state
    oglc->compState = sun_java2d_SunGraphics2D_COMP_ALPHA;
    oglc->extraAlpha = extraAlpha;
}

/**
 * Initializes the OpenGL logic op state to XOR mode.  Blending is disabled
 * before enabling logic op mode.  The XOR pixel value will be applied
 * later in the OGLContext_SetColor() method.
 */
void
OGLContext_SetXorComposite(OGLContext *oglc, jint xorPixel)
{
    J2dTraceLn1(J2D_TRACE_INFO,
                "OGLContext_SetXorComposite: xorPixel=%08x", xorPixel);

    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);

    // disable blending mode
    if (oglc->compState == sun_java2d_SunGraphics2D_COMP_ALPHA) {
        j2d_glDisable(GL_BLEND);
    }

    // enable XOR mode
    j2d_glEnable(GL_COLOR_LOGIC_OP);
    j2d_glLogicOp(GL_XOR);

    // set up the alpha test so that we discard transparent fragments (this
    // is primarily useful for rendering text in XOR mode)
    j2d_glEnable(GL_ALPHA_TEST);
    j2d_glAlphaFunc(GL_NOTEQUAL, 0.0f);

    // update state
    oglc->compState = sun_java2d_SunGraphics2D_COMP_XOR;
    oglc->xorPixel = xorPixel;
    oglc->extraAlpha = 1.0f;
}

/**
 * Resets the OpenGL transform state back to the identity matrix.
 */
void
OGLContext_ResetTransform(OGLContext *oglc)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_ResetTransform");

    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);

    j2d_glMatrixMode(GL_MODELVIEW);
    j2d_glLoadIdentity();
}

/**
 * Initializes the OpenGL transform state by setting the modelview transform
 * using the given matrix parameters.
 *
 * REMIND: it may be worthwhile to add serial id to AffineTransform, so we
 *         could do a quick check to see if the xform has changed since
 *         last time... a simple object compare won't suffice...
 */
void
OGLContext_SetTransform(OGLContext *oglc,
                        jdouble m00, jdouble m10,
                        jdouble m01, jdouble m11,
                        jdouble m02, jdouble m12)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_SetTransform");

    RETURN_IF_NULL(oglc);
    CHECK_PREVIOUS_OP(OGL_STATE_CHANGE);

    if (oglc->xformMatrix == NULL) {
        size_t arrsize = 16 * sizeof(GLdouble);
        oglc->xformMatrix = (GLdouble *)malloc(arrsize);
        memset(oglc->xformMatrix, 0, arrsize);
        oglc->xformMatrix[10] = 1.0;
        oglc->xformMatrix[15] = 1.0;
    }

    // copy values from AffineTransform object into native matrix array
    oglc->xformMatrix[0] = m00;
    oglc->xformMatrix[1] = m10;
    oglc->xformMatrix[4] = m01;
    oglc->xformMatrix[5] = m11;
    oglc->xformMatrix[12] = m02;
    oglc->xformMatrix[13] = m12;

    J2dTraceLn3(J2D_TRACE_VERBOSE, "  [%lf %lf %lf]",
                oglc->xformMatrix[0], oglc->xformMatrix[4],
                oglc->xformMatrix[12]);
    J2dTraceLn3(J2D_TRACE_VERBOSE, "  [%lf %lf %lf]",
                oglc->xformMatrix[1], oglc->xformMatrix[5],
                oglc->xformMatrix[13]);

    j2d_glMatrixMode(GL_MODELVIEW);
    j2d_glLoadMatrixd(oglc->xformMatrix);
}

/**
 * Creates a 2D texture of the given format and dimensions and returns the
 * texture object identifier.  This method is typically used to create a
 * temporary texture for intermediate work, such as in the
 * OGLContext_InitBlitTileTexture() method below.
 */
GLuint
OGLContext_CreateBlitTexture(GLenum internalFormat, GLenum pixelFormat,
                             GLuint width, GLuint height)
{
    GLuint texID;
    GLint sp, sr, rl, align;
    GLclampf priority = 1.0f;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_CreateBlitTexture");

    j2d_glGenTextures(1, &texID);
    j2d_glBindTexture(GL_TEXTURE_2D, texID);
    j2d_glPrioritizeTextures(1, &texID, &priority);
    j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    OGLSD_RESET_TEXTURE_WRAP(GL_TEXTURE_2D);

    // save pixel store parameters (since this method could be invoked after
    // the caller has already set up its pixel store parameters)
    j2d_glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &sp);
    j2d_glGetIntegerv(GL_UNPACK_SKIP_ROWS, &sr);
    j2d_glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rl);
    j2d_glGetIntegerv(GL_UNPACK_ALIGNMENT, &align);

    // set pixel store parameters to default values
    j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    j2d_glTexImage2D(GL_TEXTURE_2D, 0, internalFormat,
                     width, height, 0,
                     pixelFormat, GL_UNSIGNED_BYTE, NULL);

    // restore pixel store parameters
    j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sp);
    j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sr);
    j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, rl);
    j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, align);

    return texID;
}

/**
 * Initializes a small texture tile for use with tiled blit operations (see
 * OGLBlitLoops.c and OGLMaskBlit.c for usage examples).  The texture ID for
 * the tile is stored in the given OGLContext.  The tile is initially filled
 * with garbage values, but the tile is updated as needed (via
 * glTexSubImage2D()) with real RGBA values used in tiled blit situations.
 * The internal format for the texture is GL_RGBA8, which should be sufficient
 * for storing system memory surfaces of any known format (see PixelFormats
 * for a list of compatible surface formats).
 */
jboolean
OGLContext_InitBlitTileTexture(OGLContext *oglc)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_InitBlitTileTexture");

    oglc->blitTextureID =
        OGLContext_CreateBlitTexture(GL_RGBA8, GL_RGBA,
                                     OGLC_BLIT_TILE_SIZE,
                                     OGLC_BLIT_TILE_SIZE);

    return JNI_TRUE;
}

/**
 * Destroys the OpenGL resources associated with the given OGLContext.
 * It is required that the native context associated with the OGLContext
 * be made current prior to calling this method.
 */
void
OGLContext_DestroyContextResources(OGLContext *oglc)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_DestroyContextResources");

    if (oglc->xformMatrix != NULL) {
        free(oglc->xformMatrix);
    }

    if (oglc->blitTextureID != 0) {
        j2d_glDeleteTextures(1, &oglc->blitTextureID);
    }
}

/**
 * Returns JNI_TRUE if the given extension name is available for the current
 * GraphicsConfig; JNI_FALSE otherwise.  An extension is considered available
 * if its identifier string is found amongst the space-delimited GL_EXTENSIONS
 * string.
 *
 * Adapted from the OpenGL Red Book, pg. 506.
 */
jboolean
OGLContext_IsExtensionAvailable(const char *extString, char *extName)
{
    jboolean ret = JNI_FALSE;
    char *p = (char *)extString;
    char *end;

    if (extString == NULL) {
        J2dTraceLn(J2D_TRACE_INFO, "OGLContext_IsExtensionAvailable");
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLContext_IsExtensionAvailable: extension string is null");
        return JNI_FALSE;
    }

    end = p + strlen(p);

    while (p < end) {
        size_t n = strcspn(p, " ");

        if ((strlen(extName) == n) && (strncmp(extName, p, n) == 0)) {
            ret = JNI_TRUE;
            break;
        }

        p += (n + 1);
    }

    J2dRlsTraceLn2(J2D_TRACE_INFO,
                   "OGLContext_IsExtensionAvailable: %s=%s",
                   extName, ret ? "true" : "false");

    return ret;
}

/**
 * Returns JNI_TRUE only if all of the following conditions are met:
 *   - the GL_EXT_framebuffer_object extension is available
 *   - FBO support has been enabled via the system property
 *   - we can successfully create an FBO with depth capabilities
 */
static jboolean
OGLContext_IsFBObjectExtensionAvailable(JNIEnv *env,
                                        const char *extString)
{
    jboolean isFBObjectEnabled = JNI_FALSE;
    GLuint fbobjectID, textureID, depthID;
    jint width = 1, height = 1;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_IsFBObjectExtensionAvailable");

    // first see if the fbobject extension is available
    if (!OGLContext_IsExtensionAvailable(extString,
                                         "GL_EXT_framebuffer_object"))
    {
        return JNI_FALSE;
    }

    // next see if the fbobject system property has been enabled
    isFBObjectEnabled =
        JNU_GetStaticFieldByName(env, NULL,
                                 "sun/java2d/opengl/OGLSurfaceData",
                                 "isFBObjectEnabled", "Z").z;
    if (!isFBObjectEnabled) {
        J2dRlsTraceLn(J2D_TRACE_INFO,
            "OGLContext_IsFBObjectExtensionAvailable: disabled via flag");
        return JNI_FALSE;
    }

    // finally, create a dummy fbobject with depth capabilities to see
    // if this configuration is supported by the drivers/hardware
    // (first we initialize a color texture object that will be used to
    // construct the dummy fbobject)
    j2d_glGenTextures(1, &textureID);
    j2d_glBindTexture(GL_TEXTURE_2D, textureID);
    j2d_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
                     width, height, 0,
                     GL_RGB, GL_UNSIGNED_BYTE, NULL);
    j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    j2d_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    // initialize framebuffer object using color texture created above
    if (!OGLSD_InitFBObject(&fbobjectID, &depthID,
                            textureID, GL_TEXTURE_2D,
                            width, height))
    {
        J2dRlsTraceLn(J2D_TRACE_INFO,
            "OGLContext_IsFBObjectExtensionAvailable: fbobject unsupported");
        j2d_glDeleteTextures(1, &textureID);
        return JNI_FALSE;
    }

    // delete the temporary resources
    j2d_glDeleteTextures(1, &textureID);
    j2d_glDeleteRenderbuffersEXT(1, &depthID);
    j2d_glDeleteFramebuffersEXT(1, &fbobjectID);

    J2dRlsTraceLn(J2D_TRACE_INFO,
        "OGLContext_IsFBObjectExtensionAvailable: fbobject supported");

    return JNI_TRUE;
}

/**
 * Returns JNI_TRUE only if all of the following conditions are met:
 *   - the GL_ARB_fragment_shader extension is available
 *   - the LCD text shader codepath has been enabled via the system property
 *   - the hardware supports the minimum number of texture units
 */
static jboolean
OGLContext_IsLCDShaderSupportAvailable(JNIEnv *env,
                                       jboolean fragShaderAvailable)
{
    jboolean isLCDShaderEnabled = JNI_FALSE;
    GLint maxTexUnits;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_IsLCDShaderSupportAvailable");

    // first see if the fragment shader extension is available
    if (!fragShaderAvailable) {
        return JNI_FALSE;
    }

    // next see if the lcdshader system property has been enabled
    isLCDShaderEnabled =
        JNU_GetStaticFieldByName(env, NULL,
                                 "sun/java2d/opengl/OGLSurfaceData",
                                 "isLCDShaderEnabled", "Z").z;
    if (!isLCDShaderEnabled) {
        J2dRlsTraceLn(J2D_TRACE_INFO,
            "OGLContext_IsLCDShaderSupportAvailable: disabled via flag");
        return JNI_FALSE;
    }

    // finally, check to see if the hardware supports the required number
    // of texture units
    j2d_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &maxTexUnits);
    if (maxTexUnits < 4) {
        J2dRlsTraceLn1(J2D_TRACE_INFO,
          "OGLContext_IsLCDShaderSupportAvailable: not enough tex units (%d)",
          maxTexUnits);
    }

    J2dRlsTraceLn(J2D_TRACE_INFO,
        "OGLContext_IsLCDShaderSupportAvailable: LCD text shader supported");

    return JNI_TRUE;
}

/**
 * Returns JNI_TRUE only if all of the following conditions are met:
 *   - the GL_ARB_fragment_shader extension is available
 *   - the BufferedImageOp shader codepath has been enabled via the
 *     system property
 */
static jboolean
OGLContext_IsBIOpShaderSupportAvailable(JNIEnv *env,
                                        jboolean fragShaderAvailable)
{
    jboolean isBIOpShaderEnabled = JNI_FALSE;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_IsBIOpShaderSupportAvailable");

    // first see if the fragment shader extension is available
    if (!fragShaderAvailable) {
        return JNI_FALSE;
    }

    // next see if the biopshader system property has been enabled
    isBIOpShaderEnabled =
        JNU_GetStaticFieldByName(env, NULL,
                                 "sun/java2d/opengl/OGLSurfaceData",
                                 "isBIOpShaderEnabled", "Z").z;
    if (!isBIOpShaderEnabled) {
        J2dRlsTraceLn(J2D_TRACE_INFO,
            "OGLContext_IsBIOpShaderSupportAvailable: disabled via flag");
        return JNI_FALSE;
    }

    /*
     * Note: In theory we should probably do some other checks here, like
     * linking a sample shader to see if the hardware truly supports our
     * shader programs.  However, our current BufferedImageOp shaders were
     * designed to support first-generation shader-level hardware, so the
     * assumption is that if our shaders work on those GPUs, then they'll
     * work on newer ones as well.  Also, linking a fragment program can
     * cost valuable CPU cycles, which is another reason to avoid these
     * checks at startup.
     */

    J2dRlsTraceLn(J2D_TRACE_INFO,
        "OGLContext_IsBIOpShaderSupportAvailable: BufferedImageOp shader supported");

    return JNI_TRUE;
}

/**
 * Returns JNI_TRUE only if all of the following conditions are met:
 *   - the GL_ARB_fragment_shader extension is available
 *   - the Linear/RadialGradientPaint shader codepath has been enabled via the
 *     system property
 */
static jboolean
OGLContext_IsGradShaderSupportAvailable(JNIEnv *env,
                                        jboolean fragShaderAvailable)
{
    jboolean isGradShaderEnabled = JNI_FALSE;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_IsGradShaderSupportAvailable");

    // first see if the fragment shader extension is available
    if (!fragShaderAvailable) {
        return JNI_FALSE;
    }

    // next see if the gradshader system property has been enabled
    isGradShaderEnabled =
        JNU_GetStaticFieldByName(env, NULL,
                                 "sun/java2d/opengl/OGLSurfaceData",
                                 "isGradShaderEnabled", "Z").z;
    if (!isGradShaderEnabled) {
        J2dRlsTraceLn(J2D_TRACE_INFO,
            "OGLContext_IsGradShaderSupportAvailable: disabled via flag");
        return JNI_FALSE;
    }

    J2dRlsTraceLn(J2D_TRACE_INFO,
        "OGLContext_IsGradShaderSupportAvailable: Linear/RadialGradientPaint shader supported");

    return JNI_TRUE;
}

/**
 * Checks for the presence of the optional extensions used by
 * the Java 2D OpenGL pipeline.  The given caps bitfield is updated
 * to reflect the availability of these extensions.
 */
void
OGLContext_GetExtensionInfo(JNIEnv *env, jint *caps)
{
    jint vcap = OGLC_VENDOR_OTHER;
    const char *vendor = (char *)j2d_glGetString(GL_VENDOR);
    const char *e = (char *)j2d_glGetString(GL_EXTENSIONS);
    jboolean fragShaderAvail =
        OGLContext_IsExtensionAvailable(e, "GL_ARB_fragment_shader");

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_GetExtensionInfo");

    if (OGLContext_IsExtensionAvailable(e, "GL_ARB_multitexture")) {
        *caps |= sun_java2d_opengl_OGLContext_CAPS_EXT_MULTITEXTURE;
    }
    if (OGLContext_IsExtensionAvailable(e, "GL_ARB_texture_non_power_of_two")){
        *caps |= sun_java2d_opengl_OGLContext_CAPS_EXT_TEXNONPOW2;
    }
    if (OGLContext_IsExtensionAvailable(e, "GL_ARB_texture_rectangle")) {
        *caps |= sun_java2d_opengl_OGLContext_CAPS_EXT_TEXRECT;
    }
    if (OGLContext_IsFBObjectExtensionAvailable(env, e)) {
        *caps |= sun_java2d_opengl_OGLContext_CAPS_EXT_FBOBJECT;
    }
    if (OGLContext_IsLCDShaderSupportAvailable(env, fragShaderAvail)) {
        *caps |= sun_java2d_opengl_OGLContext_CAPS_EXT_LCD_SHADER;
    }
    if (OGLContext_IsBIOpShaderSupportAvailable(env, fragShaderAvail)) {
        *caps |= sun_java2d_opengl_OGLContext_CAPS_EXT_BIOP_SHADER;
    }
    if (OGLContext_IsGradShaderSupportAvailable(env, fragShaderAvail)) {
        *caps |= sun_java2d_opengl_OGLContext_CAPS_EXT_GRAD_SHADER;
    }

    // stuff vendor descriptor in the upper bits of the caps
    if (vendor != NULL) {
        if (strncmp(vendor, "ATI", 3) == 0) {
            vcap = OGLC_VENDOR_ATI;
        } else if (strncmp(vendor, "NVIDIA", 6) == 0) {
            vcap = OGLC_VENDOR_NVIDIA;
        } else if (strncmp(vendor, "Sun", 3) == 0) {
            vcap = OGLC_VENDOR_SUN;
        }
    }
    *caps |= ((vcap & OGLC_VCAP_MASK) << OGLC_VCAP_OFFSET);
}

/**
 * Returns JNI_TRUE if the given GL_VERSION string meets the minimum
 * requirements (>= 1.2); JNI_FALSE otherwise.
 */
jboolean
OGLContext_IsVersionSupported(const unsigned char *versionstr)
{
    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_IsVersionSupported");

    if (versionstr == NULL) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLContext_IsVersionSupported: version string is null");
        return JNI_FALSE;
    }

    // note that this check allows for OpenGL 2.x
    return ((versionstr[0] == '1' && versionstr[2] >= '2') ||
            (versionstr[0] >= '2'));
}

/**
 * Compiles and links the given fragment shader program.  If
 * successful, this function returns a handle to the newly created shader
 * program; otherwise returns 0.
 */
GLhandleARB
OGLContext_CreateFragmentProgram(const char *fragmentShaderSource)
{
    GLhandleARB fragmentShader, fragmentProgram;
    GLint success;
    int infoLogLength = 0;

    J2dTraceLn(J2D_TRACE_INFO, "OGLContext_CreateFragmentProgram");

    // create the shader object and compile the shader source code
    fragmentShader = j2d_glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
    j2d_glShaderSourceARB(fragmentShader, 1, &fragmentShaderSource, NULL);
    j2d_glCompileShaderARB(fragmentShader);
    j2d_glGetObjectParameterivARB(fragmentShader,
                                  GL_OBJECT_COMPILE_STATUS_ARB,
                                  &success);

    // print the compiler messages, if necessary
    j2d_glGetObjectParameterivARB(fragmentShader,
                                  GL_OBJECT_INFO_LOG_LENGTH_ARB,
                                  &infoLogLength);
    if (infoLogLength > 1) {
        char infoLog[1024];
        j2d_glGetInfoLogARB(fragmentShader, 1024, NULL, infoLog);
        J2dRlsTraceLn2(J2D_TRACE_WARNING,
            "OGLContext_CreateFragmentProgram: compiler msg (%d):\n%s",
                       infoLogLength, infoLog);
    }

    if (!success) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLContext_CreateFragmentProgram: error compiling shader");
        j2d_glDeleteObjectARB(fragmentShader);
        return 0;
    }

    // create the program object and attach it to the shader
    fragmentProgram = j2d_glCreateProgramObjectARB();
    j2d_glAttachObjectARB(fragmentProgram, fragmentShader);

    // it is now safe to delete the shader object
    j2d_glDeleteObjectARB(fragmentShader);

    // link the program
    j2d_glLinkProgramARB(fragmentProgram);
    j2d_glGetObjectParameterivARB(fragmentProgram,
                                  GL_OBJECT_LINK_STATUS_ARB,
                                  &success);

    // print the linker messages, if necessary
    j2d_glGetObjectParameterivARB(fragmentProgram,
                                  GL_OBJECT_INFO_LOG_LENGTH_ARB,
                                  &infoLogLength);
    if (infoLogLength > 1) {
        char infoLog[1024];
        j2d_glGetInfoLogARB(fragmentProgram, 1024, NULL, infoLog);
        J2dRlsTraceLn2(J2D_TRACE_WARNING,
            "OGLContext_CreateFragmentProgram: linker msg (%d):\n%s",
                       infoLogLength, infoLog);
    }

    if (!success) {
        J2dRlsTraceLn(J2D_TRACE_ERROR,
            "OGLContext_CreateFragmentProgram: error linking shader");
        j2d_glDeleteObjectARB(fragmentProgram);
        return 0;
    }

    return fragmentProgram;
}

#endif /* !HEADLESS */
