0N/A/*
2362N/A * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#include <stdlib.h>
0N/A#include <string.h>
0N/A
0N/A#include "sun_java2d_opengl_GLXGraphicsConfig.h"
0N/A
0N/A#include "jni.h"
0N/A#include "jlong.h"
0N/A#include "GLXGraphicsConfig.h"
0N/A#include "GLXSurfaceData.h"
0N/A#include "awt_GraphicsEnv.h"
0N/A#include "awt_util.h"
0N/A
0N/A#ifndef HEADLESS
0N/A
0N/Aextern Bool usingXinerama;
0N/A
0N/A/**
0N/A * This is a globally shared context used when creating textures. When any
0N/A * new contexts are created, they specify this context as the "share list"
0N/A * context, which means any texture objects created when this shared context
0N/A * is current will be available to any other context.
0N/A */
0N/Astatic GLXContext sharedContext = 0;
0N/A
0N/A/**
0N/A * Attempts to initialize GLX and the core OpenGL library. For this method
0N/A * to return JNI_TRUE, the following must be true:
0N/A * - libGL must be loaded successfully (via dlopen)
0N/A * - all function symbols from libGL must be available and loaded properly
0N/A * - the GLX extension must be available through X11
0N/A * - client GLX version must be >= 1.3
0N/A * If any of these requirements are not met, this method will return
0N/A * JNI_FALSE, indicating there is no hope of using GLX/OpenGL for any
0N/A * GraphicsConfig in the environment.
0N/A */
0N/Astatic jboolean
0N/AGLXGC_InitGLX()
0N/A{
0N/A int errorbase, eventbase;
0N/A const char *version;
0N/A
0N/A J2dRlsTraceLn(J2D_TRACE_INFO, "GLXGC_InitGLX");
0N/A
0N/A if (!OGLFuncs_OpenLibrary()) {
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A if (!OGLFuncs_InitPlatformFuncs() ||
0N/A !OGLFuncs_InitBaseFuncs() ||
0N/A !OGLFuncs_InitExtFuncs())
0N/A {
0N/A OGLFuncs_CloseLibrary();
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A if (!j2d_glXQueryExtension(awt_display, &errorbase, &eventbase)) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_InitGLX: GLX extension is not present");
0N/A OGLFuncs_CloseLibrary();
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A version = j2d_glXGetClientString(awt_display, GLX_VERSION);
0N/A if (version == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_InitGLX: could not query GLX version");
0N/A OGLFuncs_CloseLibrary();
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A // we now only verify that the client GLX version is >= 1.3 (if the
0N/A // server does not support GLX 1.3, then we will find that out later
0N/A // when we attempt to create a GLXFBConfig)
0N/A J2dRlsTraceLn1(J2D_TRACE_INFO,
0N/A "GLXGC_InitGLX: client GLX version=%s", version);
0N/A if (!((version[0] == '1' && version[2] >= '3') || (version[0] > '1'))) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_InitGLX: invalid GLX version; 1.3 is required");
0N/A OGLFuncs_CloseLibrary();
0N/A return JNI_FALSE;
0N/A }
0N/A
0N/A return JNI_TRUE;
0N/A}
0N/A
0N/A/**
0N/A * Returns JNI_TRUE if GLX is available for the current display. Note that
0N/A * this method will attempt to initialize GLX (and all the necessary function
0N/A * symbols) if it has not been already. The AWT_LOCK must be acquired before
0N/A * calling this method.
0N/A */
0N/Ajboolean
0N/AGLXGC_IsGLXAvailable()
0N/A{
0N/A static jboolean glxAvailable = JNI_FALSE;
0N/A static jboolean firstTime = JNI_TRUE;
0N/A
0N/A J2dTraceLn(J2D_TRACE_INFO, "GLXGC_IsGLXAvailable");
0N/A
0N/A if (firstTime) {
0N/A glxAvailable = GLXGC_InitGLX();
0N/A firstTime = JNI_FALSE;
0N/A }
0N/A
0N/A return glxAvailable;
0N/A}
0N/A
0N/A/**
0N/A * Disposes all memory and resources allocated for the given OGLContext.
0N/A */
0N/Astatic void
0N/AGLXGC_DestroyOGLContext(OGLContext *oglc)
0N/A{
0N/A GLXCtxInfo *ctxinfo;
0N/A
0N/A J2dTraceLn(J2D_TRACE_INFO, "GLXGC_DestroyOGLContext");
0N/A
0N/A if (oglc == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_DestroyOGLContext: context is null");
0N/A return;
0N/A }
0N/A
0N/A // at this point, this context will be current to its scratch surface
0N/A // so the following GL/GLX operations should be safe...
0N/A
0N/A OGLContext_DestroyContextResources(oglc);
0N/A
0N/A ctxinfo = (GLXCtxInfo *)oglc->ctxInfo;
0N/A if (ctxinfo != NULL) {
0N/A // release the current context before we continue
0N/A j2d_glXMakeContextCurrent(awt_display, None, None, NULL);
0N/A
0N/A if (ctxinfo->context != 0) {
0N/A j2d_glXDestroyContext(awt_display, ctxinfo->context);
0N/A }
0N/A if (ctxinfo->scratchSurface != 0) {
0N/A j2d_glXDestroyPbuffer(awt_display, ctxinfo->scratchSurface);
0N/A }
0N/A
0N/A free(ctxinfo);
0N/A }
0N/A
0N/A free(oglc);
0N/A}
0N/A
0N/A/**
0N/A * Disposes all memory and resources associated with the given
0N/A * GLXGraphicsConfigInfo (including its native OGLContext data).
0N/A */
0N/Avoid
0N/AOGLGC_DestroyOGLGraphicsConfig(jlong pConfigInfo)
0N/A{
0N/A GLXGraphicsConfigInfo *glxinfo =
0N/A (GLXGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
0N/A
0N/A J2dTraceLn(J2D_TRACE_INFO, "OGLGC_DestroyOGLGraphicsConfig");
0N/A
0N/A if (glxinfo == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "OGLGC_DestroyOGLGraphicsConfig: info is null");
0N/A return;
0N/A }
0N/A
0N/A if (glxinfo->context != NULL) {
0N/A GLXGC_DestroyOGLContext(glxinfo->context);
0N/A }
0N/A
0N/A free(glxinfo);
0N/A}
0N/A
0N/A/**
0N/A * Attempts to create a new GLXFBConfig for the requested screen and visual.
0N/A * If visualid is 0, this method will iterate through all GLXFBConfigs (if
0N/A * any) that match the requested attributes and will attempt to find an
0N/A * fbconfig with a minimal combined depth+stencil buffer. Note that we
0N/A * currently only need depth capabilities (for shape clipping purposes), but
0N/A * glXChooseFBConfig() will often return a list of fbconfigs with the largest
0N/A * depth buffer (and stencil) sizes at the top of the list. Therefore, we
0N/A * scan through the whole list to find the most VRAM-efficient fbconfig.
0N/A * If visualid is non-zero, the GLXFBConfig associated with the given visual
0N/A * is chosen (assuming it meets the requested attributes). If there are no
0N/A * valid GLXFBConfigs available, this method returns 0.
0N/A */
0N/Astatic GLXFBConfig
0N/AGLXGC_InitFBConfig(JNIEnv *env, jint screennum, VisualID visualid)
0N/A{
0N/A GLXFBConfig *fbconfigs;
0N/A GLXFBConfig chosenConfig = 0;
0N/A int nconfs, i;
0N/A int attrlist[] = {GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT | GLX_PBUFFER_BIT,
0N/A GLX_RENDER_TYPE, GLX_RGBA_BIT,
0N/A GLX_CONFIG_CAVEAT, GLX_NONE, // avoid "slow" configs
0N/A GLX_DEPTH_SIZE, 16, // anything >= 16 will work for us
0N/A 0};
0N/A
0N/A // this is the initial minimum value for the combined depth+stencil size
0N/A // (we initialize it to some absurdly high value; realistic values will
0N/A // be much less than this number)
0N/A int minDepthPlusStencil = 512;
0N/A
0N/A J2dRlsTraceLn2(J2D_TRACE_INFO, "GLXGC_InitFBConfig: scn=%d vis=0x%x",
0N/A screennum, visualid);
0N/A
0N/A // find all fbconfigs for this screen with the provided attributes
0N/A fbconfigs = j2d_glXChooseFBConfig(awt_display, screennum,
0N/A attrlist, &nconfs);
0N/A
0N/A if ((fbconfigs == NULL) || (nconfs <= 0)) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_InitFBConfig: could not find any valid fbconfigs");
0N/A return 0;
0N/A }
0N/A
0N/A J2dRlsTraceLn(J2D_TRACE_VERBOSE, " candidate fbconfigs:");
0N/A
0N/A // iterate through the list of fbconfigs, looking for the one that matches
0N/A // the requested VisualID and supports RGBA rendering as well as the
0N/A // creation of windows and pbuffers
0N/A for (i = 0; i < nconfs; i++) {
0N/A XVisualInfo *xvi;
0N/A VisualID fbvisualid;
0N/A GLXFBConfig fbc = fbconfigs[i];
0N/A
0N/A // get VisualID from GLXFBConfig
0N/A xvi = j2d_glXGetVisualFromFBConfig(awt_display, fbc);
0N/A if (xvi == NULL) {
0N/A continue;
0N/A }
0N/A fbvisualid = xvi->visualid;
0N/A XFree(xvi);
0N/A
0N/A if (visualid == 0 || visualid == fbvisualid) {
0N/A int dtype, rtype, depth, stencil, db, alpha, gamma;
0N/A
0N/A // get GLX-specific attributes from GLXFBConfig
0N/A j2d_glXGetFBConfigAttrib(awt_display, fbc,
0N/A GLX_DRAWABLE_TYPE, &dtype);
0N/A j2d_glXGetFBConfigAttrib(awt_display, fbc,
0N/A GLX_RENDER_TYPE, &rtype);
0N/A j2d_glXGetFBConfigAttrib(awt_display, fbc,
0N/A GLX_DEPTH_SIZE, &depth);
0N/A j2d_glXGetFBConfigAttrib(awt_display, fbc,
0N/A GLX_STENCIL_SIZE, &stencil);
0N/A
0N/A // these attributes don't affect our decision, but they are
0N/A // interesting for trace logs, so we will query them anyway
0N/A j2d_glXGetFBConfigAttrib(awt_display, fbc,
0N/A GLX_DOUBLEBUFFER, &db);
0N/A j2d_glXGetFBConfigAttrib(awt_display, fbc,
0N/A GLX_ALPHA_SIZE, &alpha);
0N/A
0N/A J2dRlsTrace5(J2D_TRACE_VERBOSE,
0N/A "[V] id=0x%x db=%d alpha=%d depth=%d stencil=%d valid=",
0N/A fbvisualid, db, alpha, depth, stencil);
0N/A
0N/A#ifdef __sparc
0N/A /*
0N/A * Sun's OpenGL implementation will always
0N/A * return at least two GLXFBConfigs (visuals) from
0N/A * glXChooseFBConfig(). The first will be a linear (gamma
0N/A * corrected) visual; the second will have the same capabilities
0N/A * as the first, except it will be a non-linear (non-gamma
0N/A * corrected) visual, which is the one we want, otherwise
0N/A * everything will look "washed out". So we will reject any
0N/A * visuals that have gamma values other than 1.0 (the value
0N/A * returned by glXGetFBConfigAttrib() will be scaled
0N/A * by 100, so 100 corresponds to a gamma value of 1.0, 220
0N/A * corresponds to 2.2, and so on).
0N/A */
0N/A j2d_glXGetFBConfigAttrib(awt_display, fbc,
0N/A GLX_GAMMA_VALUE_SUN, &gamma);
0N/A if (gamma != 100) {
0N/A J2dRlsTrace(J2D_TRACE_VERBOSE, "false (linear visual)\n");
0N/A continue;
0N/A }
0N/A#endif /* __sparc */
0N/A
0N/A if ((dtype & GLX_WINDOW_BIT) &&
0N/A (dtype & GLX_PBUFFER_BIT) &&
0N/A (rtype & GLX_RGBA_BIT) &&
0N/A (depth >= 16))
0N/A {
0N/A if (visualid == 0) {
0N/A // when visualid == 0, we loop through all configs
0N/A // looking for an fbconfig that has the smallest combined
0N/A // depth+stencil size (this keeps VRAM usage to a minimum)
0N/A if ((depth + stencil) < minDepthPlusStencil) {
0N/A J2dRlsTrace(J2D_TRACE_VERBOSE, "true\n");
0N/A minDepthPlusStencil = depth + stencil;
0N/A chosenConfig = fbc;
0N/A } else {
0N/A J2dRlsTrace(J2D_TRACE_VERBOSE,
0N/A "false (large depth)\n");
0N/A }
0N/A continue;
0N/A } else {
0N/A // in this case, visualid == fbvisualid, which means
0N/A // we've found a valid fbconfig corresponding to the
0N/A // requested VisualID, so break out of the loop
0N/A J2dRlsTrace(J2D_TRACE_VERBOSE, "true\n");
0N/A chosenConfig = fbc;
0N/A break;
0N/A }
0N/A } else {
0N/A J2dRlsTrace(J2D_TRACE_VERBOSE, "false (bad match)\n");
0N/A }
0N/A }
0N/A }
0N/A
0N/A // free the list of fbconfigs
0N/A XFree(fbconfigs);
0N/A
0N/A if (chosenConfig == 0) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_InitFBConfig: could not find an appropriate fbconfig");
0N/A return 0;
0N/A }
0N/A
0N/A return chosenConfig;
0N/A}
0N/A
0N/A/**
0N/A * Returns the X11 VisualID that corresponds to the best GLXFBConfig for the
0N/A * given screen. If no valid visual could be found, this method returns zero.
0N/A * Note that this method will attempt to initialize GLX (and all the
0N/A * necessary function symbols) if it has not been already. The AWT_LOCK
0N/A * must be acquired before calling this method.
0N/A */
0N/AVisualID
0N/AGLXGC_FindBestVisual(JNIEnv *env, jint screen)
0N/A{
0N/A GLXFBConfig fbc;
0N/A XVisualInfo *xvi;
0N/A VisualID visualid;
0N/A
0N/A J2dRlsTraceLn1(J2D_TRACE_INFO, "GLXGC_FindBestVisual: scn=%d", screen);
0N/A
0N/A if (!GLXGC_IsGLXAvailable()) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_FindBestVisual: could not initialize GLX");
0N/A return 0;
0N/A }
0N/A
0N/A fbc = GLXGC_InitFBConfig(env, screen, 0);
0N/A if (fbc == 0) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_FindBestVisual: could not find best visual");
0N/A return 0;
0N/A }
0N/A
0N/A xvi = j2d_glXGetVisualFromFBConfig(awt_display, fbc);
0N/A if (xvi == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_FindBestVisual: could not get visual for fbconfig");
0N/A return 0;
0N/A }
0N/A
0N/A visualid = xvi->visualid;
0N/A XFree(xvi);
0N/A
0N/A J2dRlsTraceLn2(J2D_TRACE_INFO,
0N/A "GLXGC_FindBestVisual: chose 0x%x as the best visual for screen %d",
0N/A visualid, screen);
0N/A
0N/A return visualid;
0N/A}
0N/A
0N/A/**
0N/A * Creates a scratch pbuffer, which can be used to make a context current
0N/A * for extension queries, etc.
0N/A */
0N/Astatic GLXPbuffer
0N/AGLXGC_InitScratchPbuffer(GLXFBConfig fbconfig)
0N/A{
0N/A int pbattrlist[] = {GLX_PBUFFER_WIDTH, 1,
0N/A GLX_PBUFFER_HEIGHT, 1,
0N/A GLX_PRESERVED_CONTENTS, GL_FALSE,
0N/A 0};
0N/A
0N/A J2dTraceLn(J2D_TRACE_INFO, "GLXGC_InitScratchPbuffer");
0N/A
0N/A return j2d_glXCreatePbuffer(awt_display, fbconfig, pbattrlist);
0N/A}
0N/A
0N/A/**
0N/A * Initializes a new OGLContext, which includes the native GLXContext handle
0N/A * and some other important information such as the associated GLXFBConfig.
0N/A */
0N/Astatic OGLContext *
0N/AGLXGC_InitOGLContext(GLXFBConfig fbconfig, GLXContext context,
0N/A GLXPbuffer scratch, jint caps)
0N/A{
0N/A OGLContext *oglc;
0N/A GLXCtxInfo *ctxinfo;
0N/A
0N/A J2dTraceLn(J2D_TRACE_INFO, "GLXGC_InitOGLContext");
0N/A
0N/A oglc = (OGLContext *)malloc(sizeof(OGLContext));
0N/A if (oglc == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_InitOGLContext: could not allocate memory for oglc");
0N/A return NULL;
0N/A }
0N/A
0N/A memset(oglc, 0, sizeof(OGLContext));
0N/A
0N/A ctxinfo = (GLXCtxInfo *)malloc(sizeof(GLXCtxInfo));
0N/A if (ctxinfo == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGC_InitOGLContext: could not allocate memory for ctxinfo");
0N/A free(oglc);
0N/A return NULL;
0N/A }
0N/A
0N/A ctxinfo->fbconfig = fbconfig;
0N/A ctxinfo->context = context;
0N/A ctxinfo->scratchSurface = scratch;
0N/A oglc->ctxInfo = ctxinfo;
0N/A oglc->caps = caps;
0N/A
0N/A return oglc;
0N/A}
0N/A
0N/A#endif /* !HEADLESS */
0N/A
0N/A/**
0N/A * Determines whether the GLX pipeline can be used for a given GraphicsConfig
0N/A * provided its screen number and visual ID. If the minimum requirements are
0N/A * met, the native GLXGraphicsConfigInfo structure is initialized for this
0N/A * GraphicsConfig with the necessary information (GLXFBConfig, etc.)
0N/A * and a pointer to this structure is returned as a jlong. If
0N/A * initialization fails at any point, zero is returned, indicating that GLX
0N/A * cannot be used for this GraphicsConfig (we should fallback on the existing
0N/A * X11 pipeline).
0N/A */
0N/AJNIEXPORT jlong JNICALL
0N/AJava_sun_java2d_opengl_GLXGraphicsConfig_getGLXConfigInfo(JNIEnv *env,
0N/A jclass glxgc,
0N/A jint screennum,
0N/A jint visnum)
0N/A{
0N/A#ifndef HEADLESS
0N/A OGLContext *oglc;
0N/A GLXFBConfig fbconfig;
0N/A GLXContext context;
0N/A GLXPbuffer scratch;
0N/A GLXGraphicsConfigInfo *glxinfo;
430N/A jint caps = CAPS_EMPTY;
0N/A int db, alpha;
0N/A const unsigned char *versionstr;
0N/A
0N/A J2dRlsTraceLn(J2D_TRACE_INFO, "GLXGraphicsConfig_getGLXConfigInfo");
0N/A
0N/A if (usingXinerama) {
0N/A // when Xinerama is enabled, the screen ID needs to be 0
0N/A screennum = 0;
0N/A }
0N/A
0N/A fbconfig = GLXGC_InitFBConfig(env, screennum, (VisualID)visnum);
0N/A if (fbconfig == 0) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: could not create fbconfig");
0N/A return 0L;
0N/A }
0N/A
0N/A if (sharedContext == 0) {
0N/A // create the one shared context
0N/A sharedContext = j2d_glXCreateNewContext(awt_display, fbconfig,
0N/A GLX_RGBA_TYPE, 0, GL_TRUE);
0N/A if (sharedContext == 0) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: could not create shared context");
0N/A return 0L;
0N/A }
0N/A }
0N/A
0N/A // create the GLXContext for this GLXGraphicsConfig
0N/A context = j2d_glXCreateNewContext(awt_display, fbconfig,
0N/A GLX_RGBA_TYPE, sharedContext,
0N/A GL_TRUE);
0N/A if (context == 0) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: could not create GLX context");
0N/A return 0L;
0N/A }
0N/A
0N/A // this is pretty sketchy, but it seems to be the easiest way to create
0N/A // some form of GLXDrawable using only the display and a GLXFBConfig
0N/A // (in order to make the context current for checking the version,
0N/A // extensions, etc)...
0N/A scratch = GLXGC_InitScratchPbuffer(fbconfig);
0N/A if (scratch == 0) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: could not create scratch pbuffer");
0N/A j2d_glXDestroyContext(awt_display, context);
0N/A return 0L;
0N/A }
0N/A
0N/A // the context must be made current before we can query the
0N/A // version and extension strings
0N/A j2d_glXMakeContextCurrent(awt_display, scratch, scratch, context);
0N/A
0N/A#ifdef __sparc
0N/A /*
0N/A * 6438225: The software rasterizer used by Sun's OpenGL libraries
0N/A * for certain boards has quality issues, and besides, performance
0N/A * of these boards is not high enough to justify the use of the
0N/A * OpenGL-based Java 2D pipeline. If we detect one of the following
0N/A * boards via the GL_RENDERER string, just give up:
0N/A * - FFB[2[+]] ("Creator[3D]")
0N/A * - PGX-series ("m64")
0N/A * - AFB ("Elite3D")
0N/A */
0N/A {
0N/A const char *renderer = (const char *)j2d_glGetString(GL_RENDERER);
0N/A
0N/A J2dRlsTraceLn1(J2D_TRACE_VERBOSE,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: detected renderer (%s)",
0N/A (renderer == NULL) ? "null" : renderer);
0N/A
0N/A if (renderer == NULL ||
0N/A strncmp(renderer, "Creator", 7) == 0 ||
0N/A strncmp(renderer, "SUNWm64", 7) == 0 ||
0N/A strncmp(renderer, "Elite", 5) == 0)
0N/A {
0N/A J2dRlsTraceLn1(J2D_TRACE_ERROR,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: unsupported board (%s)",
0N/A (renderer == NULL) ? "null" : renderer);
0N/A j2d_glXMakeContextCurrent(awt_display, None, None, NULL);
0N/A j2d_glXDestroyPbuffer(awt_display, scratch);
0N/A j2d_glXDestroyContext(awt_display, context);
0N/A return 0L;
0N/A }
0N/A }
0N/A#endif /* __sparc */
0N/A
0N/A versionstr = j2d_glGetString(GL_VERSION);
0N/A OGLContext_GetExtensionInfo(env, &caps);
0N/A
0N/A // destroy the temporary resources
0N/A j2d_glXMakeContextCurrent(awt_display, None, None, NULL);
0N/A
0N/A J2dRlsTraceLn1(J2D_TRACE_INFO,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: OpenGL version=%s",
0N/A (versionstr == NULL) ? "null" : (char *)versionstr);
0N/A
0N/A if (!OGLContext_IsVersionSupported(versionstr)) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: OpenGL 1.2 is required");
0N/A j2d_glXDestroyPbuffer(awt_display, scratch);
0N/A j2d_glXDestroyContext(awt_display, context);
0N/A return 0L;
0N/A }
0N/A
0N/A // get config-specific capabilities
0N/A j2d_glXGetFBConfigAttrib(awt_display, fbconfig, GLX_DOUBLEBUFFER, &db);
0N/A if (db) {
430N/A caps |= CAPS_DOUBLEBUFFERED;
0N/A }
0N/A j2d_glXGetFBConfigAttrib(awt_display, fbconfig, GLX_ALPHA_SIZE, &alpha);
0N/A if (alpha > 0) {
430N/A caps |= CAPS_STORED_ALPHA;
0N/A }
0N/A
0N/A // initialize the OGLContext, which wraps the GLXFBConfig and GLXContext
0N/A oglc = GLXGC_InitOGLContext(fbconfig, context, scratch, caps);
0N/A if (oglc == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: could not create oglc");
0N/A j2d_glXDestroyPbuffer(awt_display, scratch);
0N/A j2d_glXDestroyContext(awt_display, context);
0N/A return 0L;
0N/A }
0N/A
0N/A J2dTraceLn(J2D_TRACE_VERBOSE,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: finished checking dependencies");
0N/A
0N/A // create the GLXGraphicsConfigInfo record for this config
0N/A glxinfo = (GLXGraphicsConfigInfo *)malloc(sizeof(GLXGraphicsConfigInfo));
0N/A if (glxinfo == NULL) {
0N/A J2dRlsTraceLn(J2D_TRACE_ERROR,
0N/A "GLXGraphicsConfig_getGLXConfigInfo: could not allocate memory for glxinfo");
0N/A GLXGC_DestroyOGLContext(oglc);
0N/A return 0L;
0N/A }
0N/A
0N/A glxinfo->screen = screennum;
0N/A glxinfo->visual = visnum;
0N/A glxinfo->context = oglc;
0N/A glxinfo->fbconfig = fbconfig;
0N/A
0N/A return ptr_to_jlong(glxinfo);
0N/A#else
0N/A return 0L;
0N/A#endif /* !HEADLESS */
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_java2d_opengl_GLXGraphicsConfig_initConfig(JNIEnv *env,
0N/A jobject glxgc,
0N/A jlong aData,
0N/A jlong configInfo)
0N/A{
0N/A#ifndef HEADLESS
0N/A GLXGraphicsConfigInfo *glxinfo;
0N/A AwtGraphicsConfigDataPtr configData =
0N/A (AwtGraphicsConfigDataPtr)jlong_to_ptr(aData);
0N/A
0N/A J2dTraceLn(J2D_TRACE_INFO, "GLXGraphicsConfig_initConfig");
0N/A
0N/A if (configData == NULL) {
0N/A JNU_ThrowNullPointerException(env, "Native GraphicsConfig missing");
0N/A return;
0N/A }
0N/A
0N/A glxinfo = (GLXGraphicsConfigInfo *)jlong_to_ptr(configInfo);
0N/A if (glxinfo == NULL) {
0N/A JNU_ThrowNullPointerException(env,
0N/A "GLXGraphicsConfigInfo data missing");
0N/A return;
0N/A }
0N/A
0N/A configData->glxInfo = glxinfo;
0N/A#endif /* !HEADLESS */
0N/A}
0N/A
0N/AJNIEXPORT jint JNICALL
0N/AJava_sun_java2d_opengl_GLXGraphicsConfig_getOGLCapabilities(JNIEnv *env,
0N/A jclass glxgc,
0N/A jlong configInfo)
0N/A{
0N/A#ifndef HEADLESS
0N/A GLXGraphicsConfigInfo *glxinfo =
0N/A (GLXGraphicsConfigInfo *)jlong_to_ptr(configInfo);
0N/A
0N/A J2dTraceLn(J2D_TRACE_INFO, "GLXGraphicsConfig_getOGLCapabilities");
0N/A
0N/A if (glxinfo == NULL || glxinfo->context == NULL) {
430N/A return CAPS_EMPTY;
0N/A }
0N/A
0N/A return glxinfo->context->caps;
0N/A#else
430N/A return CAPS_EMPTY;
0N/A#endif /* !HEADLESS */
0N/A}