110 #define REQUIRED_XRENDER_VER3 3 |
110 #define REQUIRED_XRENDER_VER3 3 |
111 |
111 |
112 #define PKGINFO_LINE_LEN_MAX 256 |
112 #define PKGINFO_LINE_LEN_MAX 256 |
113 #define PKGINFO_LINE_CNT_MAX 50 |
113 #define PKGINFO_LINE_CNT_MAX 50 |
114 |
114 |
|
115 /* |
|
116 * X protocol uses (u_int16)length to specify the length in 4 bytes quantities |
|
117 * of the whole request. Both XRenderFillRectangles() and XFillRectangles() |
|
118 * have provisions to fragment into several requests if the number of rectangles |
|
119 * plus the current x request does not fit into 65535*4 bytes. While |
|
120 * XRenderCreateLinearGradient() and XRenderCreateRadialGradient() have |
|
121 * provisions to gracefully degrade if the resulting request would exceed |
|
122 * 65535*4 bytes. |
|
123 * |
|
124 * Below, we define a cap of 65535*4 bytes for the maximum X request payload |
|
125 * allowed for Non-(XRenderFillRectangles() or XFillRectangles()) API calls, |
|
126 * just to be conservative. This is offset by the size of our maximum x*Req |
|
127 * type in this compilation unit, which is xRenderCreateRadiaGradientReq. |
|
128 * |
|
129 * Note that sizeof(xRenderCreateRadiaGradientReq) = 36 |
|
130 */ |
|
131 #define MAX_PAYLOAD (262140u - 36u) |
|
132 #define MAXUINT (0xffffffffu) |
|
133 |
115 static jboolean IsXRenderAvailable(jboolean verbose) { |
134 static jboolean IsXRenderAvailable(jboolean verbose) { |
116 |
135 |
117 void *xrenderlib; |
136 void *xrenderlib; |
118 |
137 |
119 int major_opcode, first_event, first_error; |
138 int major_opcode, first_event, first_error; |
464 Picture gradient = 0; |
487 Picture gradient = 0; |
465 XRenderColor *colors; |
488 XRenderColor *colors; |
466 XFixed *stops; |
489 XFixed *stops; |
467 XLinearGradient grad; |
490 XLinearGradient grad; |
468 |
491 |
|
492 if (MAX_PAYLOAD / (sizeof(XRenderColor) + sizeof(XFixed)) |
|
493 < (unsigned)numStops) { |
|
494 /* numStops too big, payload overflow */ |
|
495 return -1; |
|
496 } |
|
497 |
469 if ((pixels = (jshort *) |
498 if ((pixels = (jshort *) |
470 (*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) { |
499 (*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) { |
471 return -1; |
500 return -1; |
472 } |
501 } |
473 if ((fractions = (jfloat *) |
502 if ((fractions = (jfloat *) |
483 grad.p2.y = y2; |
512 grad.p2.y = y2; |
484 |
513 |
485 /*TODO optimized & malloc check*/ |
514 /*TODO optimized & malloc check*/ |
486 colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor)); |
515 colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor)); |
487 stops = (XFixed *) malloc(numStops * sizeof(XFixed)); |
516 stops = (XFixed *) malloc(numStops * sizeof(XFixed)); |
|
517 |
|
518 if (colors == NULL || stops == NULL) { |
|
519 if (colors != NULL) { |
|
520 free(colors); |
|
521 } |
|
522 if (stops != NULL) { |
|
523 free(stops); |
|
524 } |
|
525 (*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT); |
|
526 (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT); |
|
527 return -1; |
|
528 } |
488 |
529 |
489 for (i=0; i < numStops; i++) { |
530 for (i=0; i < numStops; i++) { |
490 stops[i] = XDoubleToFixed(fractions[i]); |
531 stops[i] = XDoubleToFixed(fractions[i]); |
491 colors[i].alpha = pixels[i*4 + 0]; |
532 colors[i].alpha = pixels[i*4 + 0]; |
492 colors[i].red = pixels[i*4 + 1]; |
533 colors[i].red = pixels[i*4 + 1]; |
531 Picture gradient = 0; |
572 Picture gradient = 0; |
532 XRenderColor *colors; |
573 XRenderColor *colors; |
533 XFixed *stops; |
574 XFixed *stops; |
534 XRadialGradient grad; |
575 XRadialGradient grad; |
535 |
576 |
|
577 if (MAX_PAYLOAD / (sizeof(XRenderColor) + sizeof(XFixed)) |
|
578 < (unsigned)numStops) { |
|
579 /* numStops too big, payload overflow */ |
|
580 return -1; |
|
581 } |
536 |
582 |
537 if ((pixels = |
583 if ((pixels = |
538 (jshort *)(*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) { |
584 (jshort *)(*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) { |
539 return -1; |
585 return -1; |
540 } |
586 } |
553 grad.outer.radius = outerRadius; |
599 grad.outer.radius = outerRadius; |
554 |
600 |
555 /*TODO optimized & malloc check*/ |
601 /*TODO optimized & malloc check*/ |
556 colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor)); |
602 colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor)); |
557 stops = (XFixed *) malloc(numStops * sizeof(XFixed)); |
603 stops = (XFixed *) malloc(numStops * sizeof(XFixed)); |
|
604 |
|
605 if (colors == NULL || stops == NULL) { |
|
606 if (colors != NULL) { |
|
607 free(colors); |
|
608 } |
|
609 if (stops != NULL) { |
|
610 free(stops); |
|
611 } |
|
612 (*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT); |
|
613 (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT); |
|
614 return -1; |
|
615 } |
558 |
616 |
559 for (i=0; i < numStops; i++) { |
617 for (i=0; i < numStops; i++) { |
560 stops[i] = XDoubleToFixed(fractions[i]); |
618 stops[i] = XDoubleToFixed(fractions[i]); |
561 colors[i].alpha = pixels[i*4 + 0]; |
619 colors[i].alpha = pixels[i*4 + 0]; |
562 colors[i].red = pixels[i*4 + 1]; |
620 colors[i].red = pixels[i*4 + 1]; |
712 jbyteArray pixelDataArray, int pixelDataLength) { |
770 jbyteArray pixelDataArray, int pixelDataLength) { |
713 jlong *glyphInfoPtrs; |
771 jlong *glyphInfoPtrs; |
714 unsigned char *pixelData; |
772 unsigned char *pixelData; |
715 int i; |
773 int i; |
716 |
774 |
|
775 if (MAX_PAYLOAD / (sizeof(XGlyphInfo) + sizeof(Glyph)) |
|
776 < (unsigned)glyphCnt) { |
|
777 /* glyphCnt too big, payload overflow */ |
|
778 return; |
|
779 } |
|
780 |
717 XGlyphInfo *xginfo = (XGlyphInfo *) malloc(sizeof(XGlyphInfo) * glyphCnt); |
781 XGlyphInfo *xginfo = (XGlyphInfo *) malloc(sizeof(XGlyphInfo) * glyphCnt); |
718 Glyph *gid = (Glyph *) malloc(sizeof(Glyph) * glyphCnt); |
782 Glyph *gid = (Glyph *) malloc(sizeof(Glyph) * glyphCnt); |
719 |
783 |
720 if (xginfo == NULL || gid == NULL) { |
784 if (xginfo == NULL || gid == NULL) { |
721 if (xginfo != NULL) { |
785 if (xginfo != NULL) { |
773 } |
837 } |
774 |
838 |
775 JNIEXPORT void JNICALL |
839 JNIEXPORT void JNICALL |
776 Java_sun_java2d_xr_XRBackendNative_XRFreeGlyphsNative |
840 Java_sun_java2d_xr_XRBackendNative_XRFreeGlyphsNative |
777 (JNIEnv *env, jclass cls, jint glyphSet, jintArray gidArray, jint glyphCnt) { |
841 (JNIEnv *env, jclass cls, jint glyphSet, jintArray gidArray, jint glyphCnt) { |
|
842 |
|
843 if (MAX_PAYLOAD / sizeof(Glyph) < (unsigned)glyphCnt) { |
|
844 /* glyphCnt too big, payload overflow */ |
|
845 return; |
|
846 } |
778 |
847 |
779 /* The glyph ids are 32 bit but may be stored in a 64 bit long on |
848 /* The glyph ids are 32 bit but may be stored in a 64 bit long on |
780 * a 64 bit architecture. So optimise the 32 bit case to avoid |
849 * a 64 bit architecture. So optimise the 32 bit case to avoid |
781 * extra stack or heap allocations by directly referencing the |
850 * extra stack or heap allocations by directly referencing the |
782 * underlying Java array and only allocate on 64 bit. |
851 * underlying Java array and only allocate on 64 bit. |
844 unsigned int *xids; |
913 unsigned int *xids; |
845 XGlyphElt32 selts[24]; |
914 XGlyphElt32 selts[24]; |
846 unsigned int sids[256]; |
915 unsigned int sids[256]; |
847 int charCnt = 0; |
916 int charCnt = 0; |
848 |
917 |
|
918 if ((MAX_PAYLOAD / sizeof(XGlyphElt32) < (unsigned)eltCnt) |
|
919 || (MAX_PAYLOAD / sizeof(unsigned int) < (unsigned)glyphCnt) |
|
920 || ((MAX_PAYLOAD - sizeof(XGlyphElt32)*(unsigned)eltCnt) / |
|
921 sizeof(unsigned int) < (unsigned)glyphCnt)) |
|
922 { |
|
923 /* (eltCnt, glyphCnt) too big, payload overflow */ |
|
924 return; |
|
925 } |
|
926 |
849 if (eltCnt <= 24) { |
927 if (eltCnt <= 24) { |
850 xelts = &selts[0]; |
928 xelts = &selts[0]; |
851 }else { |
929 }else { |
852 xelts = (XGlyphElt32 *) malloc(sizeof(XGlyphElt32) * eltCnt); |
930 xelts = (XGlyphElt32 *) malloc(sizeof(XGlyphElt32) * eltCnt); |
853 if (xelts == NULL) { |
931 if (xelts == NULL) { |
942 XRectangle sRects[256]; |
1020 XRectangle sRects[256]; |
943 |
1021 |
944 if (rectCnt <= 256) { |
1022 if (rectCnt <= 256) { |
945 xRects = &sRects[0]; |
1023 xRects = &sRects[0]; |
946 } else { |
1024 } else { |
|
1025 if (MAXUINT / sizeof(XRectangle) < (unsigned)rectCnt) { |
|
1026 /* rectCnt too big, integer overflow */ |
|
1027 return; |
|
1028 } |
|
1029 |
947 xRects = (XRectangle *) malloc(sizeof(XRectangle) * rectCnt); |
1030 xRects = (XRectangle *) malloc(sizeof(XRectangle) * rectCnt); |
948 if (xRects == NULL) { |
1031 if (xRects == NULL) { |
949 return; |
1032 return; |
950 } |
1033 } |
951 } |
1034 } |