7032904: XRender: Java2Demo : Infinite loop in Java_sun_java2d_loops_MaskBlit_MaskBlit on OEL 5.6 x64

Reviewed-by: prr
This commit is contained in:
Andrew Brygin 2011-05-30 12:05:22 +04:00
parent 991abaa069
commit 4994ea2e8f
2 changed files with 116 additions and 17 deletions

View file

@ -121,7 +121,7 @@ public class X11GraphicsEnvironment
// only attempt to initialize Xrender if it was requested // only attempt to initialize Xrender if it was requested
if (xRenderRequested) { if (xRenderRequested) {
xRenderAvailable = initXRender(); xRenderAvailable = initXRender(xRenderVerbose);
if (xRenderVerbose && !xRenderAvailable) { if (xRenderVerbose && !xRenderAvailable) {
System.out.println( System.out.println(
"Could not enable XRender pipeline"); "Could not enable XRender pipeline");
@ -159,7 +159,7 @@ public class X11GraphicsEnvironment
private static boolean xRenderVerbose; private static boolean xRenderVerbose;
private static boolean xRenderAvailable; private static boolean xRenderAvailable;
private static native boolean initXRender(); private static native boolean initXRender(boolean verbose);
public static boolean isXRenderAvailable() { public static boolean isXRenderAvailable() {
return xRenderAvailable; return xRenderAvailable;
} }

View file

@ -66,9 +66,10 @@ typedef struct _XRadialGradient {
} XRadialGradient; } XRadialGradient;
#endif #endif
#include <dlfcn.h>
#ifdef __solaris__ #ifdef __solaris__
/* Solaris 10 will not have these symbols at runtime */ /* Solaris 10 will not have these symbols at runtime */
#include <dlfcn.h>
#include <link.h> #include <link.h>
typedef Picture (*XRenderCreateLinearGradientFuncType) typedef Picture (*XRenderCreateLinearGradientFuncType)
@ -104,12 +105,20 @@ static
TRANSFORM.matrix[2][2] = 1<<16; \ 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; void *xrenderlib;
int major_opcode, first_event, first_error; int major_opcode, first_event, first_error;
jboolean available = JNI_TRUE;
if (!XQueryExtension(awt_display, "RENDER", if (!XQueryExtension(awt_display, "RENDER",
&major_opcode, &first_event, &first_error)) { &major_opcode, &first_event, &first_error)) {
@ -131,12 +140,102 @@ static jboolean IsXRenderAvailable() {
if (XRenderCreateLinearGradientFunc == NULL || if (XRenderCreateLinearGradientFunc == NULL ||
XRenderCreateRadialGradientFunc == NULL) XRenderCreateRadialGradientFunc == NULL)
{ {
dlclose(xrenderlib); available = JNI_FALSE;
return 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';
// 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 (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 #endif
return JNI_TRUE;
return available;
} }
/* /*
* Class: sun_awt_X11GraphicsEnvironment * Class: sun_awt_X11GraphicsEnvironment
@ -145,7 +244,7 @@ static jboolean IsXRenderAvailable() {
*/ */
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
Java_sun_awt_X11GraphicsEnvironment_initXRender Java_sun_awt_X11GraphicsEnvironment_initXRender
(JNIEnv *env, jclass x11ge) (JNIEnv *env, jclass x11ge, jboolean verbose)
{ {
#ifndef HEADLESS #ifndef HEADLESS
static jboolean xrenderAvailable = JNI_FALSE; static jboolean xrenderAvailable = JNI_FALSE;
@ -153,7 +252,7 @@ Java_sun_awt_X11GraphicsEnvironment_initXRender
if (firstTime) { if (firstTime) {
AWT_LOCK(); AWT_LOCK();
xrenderAvailable = IsXRenderAvailable(); xrenderAvailable = IsXRenderAvailable(verbose);
AWT_UNLOCK(); AWT_UNLOCK();
firstTime = JNI_FALSE; firstTime = JNI_FALSE;
} }