# HG changeset patch # User bae # Date 1306742722 -14400 # Node ID 5c5883cf6c967872b539fd47b3c5d2033fa3bc9d # Parent 90976a831a86019edafa7779f466c490c0b3f68a 7032904: XRender: Java2Demo : Infinite loop in Java_sun_java2d_loops_MaskBlit_MaskBlit on OEL 5.6 x64 Reviewed-by: prr diff -r 90976a831a86 -r 5c5883cf6c96 jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java Fri May 27 13:25:54 2011 -0700 +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java Mon May 30 12:05:22 2011 +0400 @@ -121,7 +121,7 @@ // only attempt to initialize Xrender if it was requested if (xRenderRequested) { - xRenderAvailable = initXRender(); + xRenderAvailable = initXRender(xRenderVerbose); if (xRenderVerbose && !xRenderAvailable) { System.out.println( "Could not enable XRender pipeline"); @@ -159,7 +159,7 @@ private static boolean xRenderVerbose; private static boolean xRenderAvailable; - private static native boolean initXRender(); + private static native boolean initXRender(boolean verbose); public static boolean isXRenderAvailable() { return xRenderAvailable; } diff -r 90976a831a86 -r 5c5883cf6c96 jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c --- a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c Fri May 27 13:25:54 2011 -0700 +++ b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c Mon May 30 12:05:22 2011 +0400 @@ -66,9 +66,10 @@ } XRadialGradient; #endif +#include + #ifdef __solaris__ /* Solaris 10 will not have these symbols at runtime */ -#include #include typedef Picture (*XRenderCreateLinearGradientFuncType) @@ -104,12 +105,20 @@ TRANSFORM.matrix[2][2] = 1<<16; \ } +/* The xrender pipleine requires libXrender.so version 0.9.3 or later. */ +#define REQUIRED_XRENDER_VER1 0 +#define REQUIRED_XRENDER_VER2 9 +#define REQUIRED_XRENDER_VER3 3 -static jboolean IsXRenderAvailable() { +#define PKGINFO_LINE_LEN_MAX 256 +#define PKGINFO_LINE_CNT_MAX 50 + +static jboolean IsXRenderAvailable(jboolean verbose) { void *xrenderlib; int major_opcode, first_event, first_error; + jboolean available = JNI_TRUE; if (!XQueryExtension(awt_display, "RENDER", &major_opcode, &first_event, &first_error)) { @@ -120,23 +129,113 @@ xrenderlib = dlopen("libXrender.so",RTLD_GLOBAL|RTLD_LAZY); if (xrenderlib != NULL) { - XRenderCreateLinearGradientFunc = - (XRenderCreateLinearGradientFuncType) - dlsym(xrenderlib, "XRenderCreateLinearGradient"); + XRenderCreateLinearGradientFunc = + (XRenderCreateLinearGradientFuncType) + dlsym(xrenderlib, "XRenderCreateLinearGradient"); + + XRenderCreateRadialGradientFunc = + (XRenderCreateRadialGradientFuncType) + dlsym(xrenderlib, "XRenderCreateRadialGradient"); + + if (XRenderCreateLinearGradientFunc == NULL || + XRenderCreateRadialGradientFunc == NULL) + { + available = JNI_FALSE; + } + dlclose(xrenderlib); + } else { + available = JNI_FALSE; + } +#else + Dl_info info; + jboolean versionInfoIsFound = JNI_FALSE; + + memset(&info, 0, sizeof(Dl_info)); + if (dladdr(&XRenderChangePicture, &info) && info.dli_fname != NULL) { + char pkgInfoPath[FILENAME_MAX]; + char *pkgFileName = "/pkgconfig/xrender.pc"; + size_t pkgFileNameLen = strlen(pkgFileName); + size_t pos, len = strlen(info.dli_fname); + + pos = len; + while (pos > 0 && info.dli_fname[pos] != '/') { + pos -= 1; + } + + if (pos > 0 && pos < (FILENAME_MAX - pkgFileNameLen - 1)) { + struct stat stat_info; + + // compose absolute filename to package config + strncpy(pkgInfoPath, info.dli_fname, pos); + + strcpy(pkgInfoPath + pos, pkgFileName); + pkgInfoPath[pos + pkgFileNameLen] = '\0'; - XRenderCreateRadialGradientFunc = - (XRenderCreateRadialGradientFuncType) - dlsym(xrenderlib, "XRenderCreateRadialGradient"); + // check whether the config file exist and is a regular file + if ((stat(pkgInfoPath, &stat_info)== 0) && + S_ISREG(stat_info.st_mode)) + { + FILE *fp = fopen(pkgInfoPath, "r"); + if (fp != NULL) { + char line[PKGINFO_LINE_LEN_MAX]; + int lineCount = PKGINFO_LINE_CNT_MAX; + char *versionPrefix = "Version: "; + size_t versionPrefixLen = strlen(versionPrefix); + + // look for version + while(fgets(line,sizeof(line),fp) != NULL && --lineCount > 0) { + size_t lineLen = strlen(line); + + if (lineLen > versionPrefixLen && + strncmp(versionPrefix, line, versionPrefixLen) == 0) + { + int v1 = 0, v2 = 0, v3 = 0; + int numNeeded = 3,numProcessed; + char* version = line + versionPrefixLen; + numProcessed = sscanf(version, "%d.%d.%d", &v1, &v2, &v3); + + if (numProcessed == numNeeded) { + // we successfuly read the library version + versionInfoIsFound = JNI_TRUE; - if (XRenderCreateLinearGradientFunc == NULL || - XRenderCreateRadialGradientFunc == NULL) - { - dlclose(xrenderlib); - return JNI_FALSE; + if (REQUIRED_XRENDER_VER1 == v1 && + ((REQUIRED_XRENDER_VER2 > v2) || + ((REQUIRED_XRENDER_VER2 == v2) && (REQUIRED_XRENDER_VER3 > v3)))) + { + available = JNI_FALSE; + + if (verbose) { + printf("INFO: the version %d.%d.%d of libXrender.so is " + "not supported.\n\tSee release notes for more details.\n", + v1, v2, v3); + fflush(stdout); + } + } else { + if (verbose) { + printf("INFO: The version of libXrender.so " + "is detected as %d.%d%d\n", v1, v2, v3); + fflush(stdout); + } + } + } + break; + } + } + fclose(fp); + } } + } + } + if (verbose && !versionInfoIsFound) { + printf("WARNING: The version of libXrender.so cannot be detected.\n," + "The pipe line will be enabled, but note that versions less than 0.9.3\n" + "may cause hangs and crashes\n" + "\tSee the release notes for more details.\n"); + fflush(stdout); } #endif - return JNI_TRUE; + + return available; } /* * Class: sun_awt_X11GraphicsEnvironment @@ -145,7 +244,7 @@ */ JNIEXPORT jboolean JNICALL Java_sun_awt_X11GraphicsEnvironment_initXRender - (JNIEnv *env, jclass x11ge) +(JNIEnv *env, jclass x11ge, jboolean verbose) { #ifndef HEADLESS static jboolean xrenderAvailable = JNI_FALSE; @@ -153,7 +252,7 @@ if (firstTime) { AWT_LOCK(); - xrenderAvailable = IsXRenderAvailable(); + xrenderAvailable = IsXRenderAvailable(verbose); AWT_UNLOCK(); firstTime = JNI_FALSE; }