1 /*
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #import "ImageSurfaceData.h"
27
28 #import "java_awt_Transparency.h"
29 #import "java_awt_image_BufferedImage.h"
30 #import "sun_awt_image_BufImgSurfaceData.h"
31 #import "sun_java2d_OSXOffScreenSurfaceData.h"
32
33 #import "jni_util.h"
34 #import <JavaNativeFoundation/JavaNativeFoundation.h>
35
36 #import "BufImgSurfaceData.h"
37 #import "ThreadUtilities.h"
38
39
40
41 //#define DEBUG 1
42 #if defined DEBUG
43 #define IMAGE_SURFACE_INLINE
44 #define PRINT(msg) {fprintf(stderr, "%s\n", msg);fflush(stderr);}
45 #else
46 #define IMAGE_SURFACE_INLINE static inline
47 #define PRINT(msg) {}
48 #endif
49
50 // same value as defined in Sun's own code
51 #define XOR_ALPHA_CUTOFF 128
52
53 // for vImage framework headers
54 #include <Accelerate/Accelerate.h>
55
56 static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] =
57 {
58 {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_CUSTOM // special case
59 {YES, YES, 8, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_RGB
178 {
179 isdo->imgRef = CGImageCreate(isdo->width,
180 isdo->height,
181 isdo->contextInfo.bitsPerComponent,
182 isdo->contextInfo.bytesPerPixel * 8,
183 isdo->contextInfo.bytesPerRow,
184 isdo->contextInfo.colorSpace,
185 isdo->contextInfo.alphaInfo,
186 isdo->dataProvider,
187 NULL,
188 NO,
189 kCGRenderingIntentDefault);
190 }
191 }
192
193 IMAGE_SURFACE_INLINE void customPixelsFromJava(JNIEnv *env, ImageSDOps *isdo)
194 {
195 PRINT(" customPixelsFromJava")
196
197 SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
198 JNFCallVoidMethod([ThreadUtilities getJNIEnv], sdo->sdObject, jm_syncFromCustom); // AWT_THREADING Safe (known object)
199 }
200
201
202 IMAGE_SURFACE_INLINE void copyBits(jint w, jint h, jint javaPixelsBytesPerRow, Pixel8bit *pixelsSrc, jint dstPixelsBytesPerRow, Pixel8bit *pixelsDst)
203 {
204 PRINT(" copyBits")
205
206 if (javaPixelsBytesPerRow == dstPixelsBytesPerRow)
207 {
208 memcpy(pixelsDst, pixelsSrc, h*javaPixelsBytesPerRow);
209 }
210 else
211 {
212 register jint y;
213 for (y=0; y<h; y++)
214 {
215 memcpy(pixelsDst, pixelsSrc, dstPixelsBytesPerRow);
216
217 pixelsSrc += javaPixelsBytesPerRow;
218 pixelsDst += dstPixelsBytesPerRow;
219 }
220 }
221 }
410
411 green = ((pixel >> 5) & 63); // rrrrrggggggbbbbb => shift 5 right = 00000rrrrrgggggg => and 63 = 0000000000gggggg
412 green = ((jint) (((CGFloat) green / 63.0f) * 31.0f)) & 31; // first normalize to value between 0 and 1 and then un-normalize to 5 bit (31 = 0000000000011111)
413
414 *pixelsDst++ = ((pixel&0xf800)>>1) | (green << 5) | (pixel&0x01f);
415 }
416 pixelsSrc += skip;
417
418 p8Bit = (Pixel8bit *) pixelsDst;
419 p8Bit += extraBytesPerRow;
420 pixelsDst = (Pixel16bit *) p8Bit;
421 }
422 }
423
424
425 IMAGE_SURFACE_INLINE void customPixelsToJava(JNIEnv *env, ImageSDOps *isdo)
426 {
427 PRINT(" customPixelsToJava")
428
429 SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
430 JNFCallVoidMethod([ThreadUtilities getJNIEnv], sdo->sdObject, jm_syncToCustom); // AWT_THREADING Safe (known object)
431 }
432
433 IMAGE_SURFACE_INLINE void removeAlphaPre_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc)
434 {
435 PRINT(" removeAlphaPre_32bit")
436
437 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
438 register Pixel32bit pixel, alpha, red, green, blue;
439 register jint x, y;
440
441 for (y=0; y<h; y++)
442 {
443 for (x=0; x<w; x++)
444 {
445 pixel = *pixelsSrc;
446
447 alpha = (pixel >> 24) & 0xff;
448
449 if (alpha != 0)
450 {
978 {
979 PRINT("unholdJavaPixels")
980
981 if (isdo->type != java_awt_image_BufferedImage_TYPE_CUSTOM)
982 {
983 isdo->nrOfPixelsOwners--;
984 if (isdo->nrOfPixelsOwners == 0)
985 {
986 isdo->pixels = NULL;
987
988 (*env)->ReleasePrimitiveArrayCritical(env, isdo->array, isdo->pixelsLocked, 0); // Do not use JNI_COMMIT, as that will not free the buffer copy when +ProtectJavaHeap is on.
989 isdo->pixelsLocked = NULL;
990 }
991 }
992 }
993
994 static void imageDataProvider_UnholdJavaPixels(void *info, const void *data, size_t size)
995 {
996 PRINT("imageDataProvider_UnholdJavaPixels")
997
998 ImageSDOps* isdo = (ImageSDOps*)info;
999 unholdJavaPixels([ThreadUtilities getJNIEnv], isdo);
1000 }
1001 static void imageDataProvider_FreeTempPixels(void *info, const void *data, size_t size)
1002 {
1003 PRINT("imageDataProvider_FreeTempPixels")
1004
1005 free((void *)data);
1006 }
1007 IMAGE_SURFACE_INLINE void syncFromJavaPixels(JNIEnv* env, ImageSDOps* isdo)
1008 {
1009 PRINT("syncFromJavaPixels")
1010
1011 // check to see if we have any work to do
1012 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] == 1)
1013 {
1014 // if we do, lock down Java pixels, this halts GarbageCollector!
1015 holdJavaPixels(env, isdo);
1016 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] == 1)
1017 {
1018 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 0;
1019
1020 void *dataProviderData = NULL;
|
1 /*
2 * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 #import "ImageSurfaceData.h"
27
28 #import "java_awt_Transparency.h"
29 #import "java_awt_image_BufferedImage.h"
30 #import "sun_awt_image_BufImgSurfaceData.h"
31 #import "sun_java2d_OSXOffScreenSurfaceData.h"
32
33 #import "jni_util.h"
34 #import <JavaNativeFoundation/JavaNativeFoundation.h>
35
36 #import "BufImgSurfaceData.h"
37
38 //#define DEBUG 1
39 #if defined DEBUG
40 #define IMAGE_SURFACE_INLINE
41 #define PRINT(msg) {fprintf(stderr, "%s\n", msg);fflush(stderr);}
42 #else
43 #define IMAGE_SURFACE_INLINE static inline
44 #define PRINT(msg) {}
45 #endif
46
47 // same value as defined in Sun's own code
48 #define XOR_ALPHA_CUTOFF 128
49
50 // for vImage framework headers
51 #include <Accelerate/Accelerate.h>
52
53 static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] =
54 {
55 {YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_CUSTOM // special case
56 {YES, YES, 8, 4, 0, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_INT_RGB
175 {
176 isdo->imgRef = CGImageCreate(isdo->width,
177 isdo->height,
178 isdo->contextInfo.bitsPerComponent,
179 isdo->contextInfo.bytesPerPixel * 8,
180 isdo->contextInfo.bytesPerRow,
181 isdo->contextInfo.colorSpace,
182 isdo->contextInfo.alphaInfo,
183 isdo->dataProvider,
184 NULL,
185 NO,
186 kCGRenderingIntentDefault);
187 }
188 }
189
190 IMAGE_SURFACE_INLINE void customPixelsFromJava(JNIEnv *env, ImageSDOps *isdo)
191 {
192 PRINT(" customPixelsFromJava")
193
194 SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
195 JNFCallVoidMethod(env, sdo->sdObject, jm_syncFromCustom); // AWT_THREADING Safe (known object)
196 }
197
198 IMAGE_SURFACE_INLINE void copyBits(jint w, jint h, jint javaPixelsBytesPerRow, Pixel8bit *pixelsSrc, jint dstPixelsBytesPerRow, Pixel8bit *pixelsDst)
199 {
200 PRINT(" copyBits")
201
202 if (javaPixelsBytesPerRow == dstPixelsBytesPerRow)
203 {
204 memcpy(pixelsDst, pixelsSrc, h*javaPixelsBytesPerRow);
205 }
206 else
207 {
208 register jint y;
209 for (y=0; y<h; y++)
210 {
211 memcpy(pixelsDst, pixelsSrc, dstPixelsBytesPerRow);
212
213 pixelsSrc += javaPixelsBytesPerRow;
214 pixelsDst += dstPixelsBytesPerRow;
215 }
216 }
217 }
406
407 green = ((pixel >> 5) & 63); // rrrrrggggggbbbbb => shift 5 right = 00000rrrrrgggggg => and 63 = 0000000000gggggg
408 green = ((jint) (((CGFloat) green / 63.0f) * 31.0f)) & 31; // first normalize to value between 0 and 1 and then un-normalize to 5 bit (31 = 0000000000011111)
409
410 *pixelsDst++ = ((pixel&0xf800)>>1) | (green << 5) | (pixel&0x01f);
411 }
412 pixelsSrc += skip;
413
414 p8Bit = (Pixel8bit *) pixelsDst;
415 p8Bit += extraBytesPerRow;
416 pixelsDst = (Pixel16bit *) p8Bit;
417 }
418 }
419
420
421 IMAGE_SURFACE_INLINE void customPixelsToJava(JNIEnv *env, ImageSDOps *isdo)
422 {
423 PRINT(" customPixelsToJava")
424
425 SurfaceDataOps *sdo = (SurfaceDataOps*)isdo;
426 JNFCallVoidMethod(env, sdo->sdObject, jm_syncToCustom); // AWT_THREADING Safe (known object)
427 }
428
429 IMAGE_SURFACE_INLINE void removeAlphaPre_32bit(jint w, jint h, jint javaPixelsBytesPerRow, jint javaPixelBytes, Pixel32bit *pixelsSrc)
430 {
431 PRINT(" removeAlphaPre_32bit")
432
433 register jint skip = (javaPixelsBytesPerRow/javaPixelBytes)-w; // in pixelsSrc units
434 register Pixel32bit pixel, alpha, red, green, blue;
435 register jint x, y;
436
437 for (y=0; y<h; y++)
438 {
439 for (x=0; x<w; x++)
440 {
441 pixel = *pixelsSrc;
442
443 alpha = (pixel >> 24) & 0xff;
444
445 if (alpha != 0)
446 {
974 {
975 PRINT("unholdJavaPixels")
976
977 if (isdo->type != java_awt_image_BufferedImage_TYPE_CUSTOM)
978 {
979 isdo->nrOfPixelsOwners--;
980 if (isdo->nrOfPixelsOwners == 0)
981 {
982 isdo->pixels = NULL;
983
984 (*env)->ReleasePrimitiveArrayCritical(env, isdo->array, isdo->pixelsLocked, 0); // Do not use JNI_COMMIT, as that will not free the buffer copy when +ProtectJavaHeap is on.
985 isdo->pixelsLocked = NULL;
986 }
987 }
988 }
989
990 static void imageDataProvider_UnholdJavaPixels(void *info, const void *data, size_t size)
991 {
992 PRINT("imageDataProvider_UnholdJavaPixels")
993
994 // Currently do nothing
995 }
996
997 static void imageDataProvider_FreeTempPixels(void *info, const void *data, size_t size)
998 {
999 PRINT("imageDataProvider_FreeTempPixels")
1000
1001 free((void *)data);
1002 }
1003 IMAGE_SURFACE_INLINE void syncFromJavaPixels(JNIEnv* env, ImageSDOps* isdo)
1004 {
1005 PRINT("syncFromJavaPixels")
1006
1007 // check to see if we have any work to do
1008 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] == 1)
1009 {
1010 // if we do, lock down Java pixels, this halts GarbageCollector!
1011 holdJavaPixels(env, isdo);
1012 if (isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] == 1)
1013 {
1014 isdo->javaImageInfo[sun_java2d_OSXOffScreenSurfaceData_kNeedToSyncFromJavaPixelsIndex] = 0;
1015
1016 void *dataProviderData = NULL;
|