blob: de39f5c5a698f483ce754d86ccc6ec78e6d0f17b [file] [log] [blame]
/*
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d;
import java.awt.*;
import java.awt.color.*;
import java.awt.image.*;
import java.nio.*;
import sun.awt.image.*;
import sun.java2d.loops.*;
public class OSXOffScreenSurfaceData extends OSXSurfaceData // implements RasterListener
{
private static native void initIDs();
static {
initIDs();
}
// the image associated with this surface
BufferedImage bim;
// the image associated with this custom surface
BufferedImage bimBackup;
// <rdar://problem/4177639> nio based images use ARGB_PRE
static DirectColorModel dcmBackup = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, true, DataBuffer.TYPE_INT);
Object lock;
// cached rasters for easy access
WritableRaster bufImgRaster;
SunWritableRaster bufImgSunRaster;
// these are extra image types we can handle
private static final int TYPE_3BYTE_RGB = BufferedImage.TYPE_BYTE_INDEXED + 1;
// these are for callbacks when pixes have been touched
protected ByteBuffer fImageInfo;
IntBuffer fImageInfoInt;
private static final int kNeedToSyncFromJavaPixelsIndex = 0;
private static final int kNativePixelsChangedIndex = 1;
private static final int kImageStolenIndex = 2;
private static final int kSizeOfParameters = kImageStolenIndex + 1;
public static native SurfaceData getSurfaceData(BufferedImage bufImg);
protected static native void setSurfaceData(BufferedImage bufImg, SurfaceData sData);
public static SurfaceData createData(BufferedImage bufImg) {
/*
* if ((bufImg.getWidth() == 32) && (bufImg.getHeight() == 32)) { Thread.dumpStack(); }
*/
// This could be called from multiple threads. We need to synchronized on the image so that
// we can ensure that only one surface data is created per image. (<rdar://4564873>)
// Note: Eventually, we should switch to using the same mechanism (CachingSurfaceManager) that Sun uses
// <rdar://4563741>
synchronized (bufImg) {
SurfaceData sData = getSurfaceData(bufImg);
if (sData != null) { return sData; }
OSXOffScreenSurfaceData osData = OSXOffScreenSurfaceData.createNewSurface(bufImg);
OSXOffScreenSurfaceData.setSurfaceData(bufImg, osData);
osData.cacheRasters(bufImg);
// osData.setRasterListener();
return osData;
}
}
public static SurfaceData createData(Raster ras, ColorModel cm) {
throw new InternalError("SurfaceData not implemented for Raster/CM");
}
static OSXOffScreenSurfaceData createNewSurface(BufferedImage bufImg) {
SurfaceData sData = null;
ColorModel cm = bufImg.getColorModel();
int type = bufImg.getType();
// REMIND: Check the image type and pick an appropriate subclass
switch (type) {
case BufferedImage.TYPE_INT_BGR:
sData = createDataIC(bufImg, SurfaceType.IntBgr);
break;
case BufferedImage.TYPE_INT_RGB:
sData = createDataIC(bufImg, SurfaceType.IntRgb);
break;
case BufferedImage.TYPE_INT_ARGB:
sData = createDataIC(bufImg, SurfaceType.IntArgb);
break;
case BufferedImage.TYPE_INT_ARGB_PRE:
sData = createDataIC(bufImg, SurfaceType.IntArgbPre);
break;
case BufferedImage.TYPE_3BYTE_BGR:
sData = createDataBC(bufImg, SurfaceType.ThreeByteBgr, 2);
break;
case BufferedImage.TYPE_4BYTE_ABGR:
sData = createDataBC(bufImg, SurfaceType.FourByteAbgr, 3);
break;
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
sData = createDataBC(bufImg, SurfaceType.FourByteAbgrPre, 3);
break;
case BufferedImage.TYPE_USHORT_565_RGB:
sData = createDataSC(bufImg, SurfaceType.Ushort565Rgb, null);
break;
case BufferedImage.TYPE_USHORT_555_RGB:
sData = createDataSC(bufImg, SurfaceType.Ushort555Rgb, null);
break;
case BufferedImage.TYPE_BYTE_INDEXED: {
SurfaceType sType;
switch (cm.getTransparency()) {
case OPAQUE:
if (isOpaqueGray((IndexColorModel) cm)) {
sType = SurfaceType.Index8Gray;
} else {
sType = SurfaceType.ByteIndexedOpaque;
}
break;
case BITMASK:
sType = SurfaceType.ByteIndexedBm;
break;
case TRANSLUCENT:
sType = SurfaceType.ByteIndexed;
break;
default:
throw new InternalError("Unrecognized transparency");
}
sData = createDataBC(bufImg, sType, 0);
}
break;
case BufferedImage.TYPE_BYTE_GRAY:
sData = createDataBC(bufImg, SurfaceType.ByteGray, 0);
break;
case BufferedImage.TYPE_USHORT_GRAY:
sData = createDataSC(bufImg, SurfaceType.UshortGray, null);
break;
case BufferedImage.TYPE_BYTE_BINARY:
case BufferedImage.TYPE_CUSTOM:
default: {
Raster raster = bufImg.getRaster();
// we try to fit a custom image into one of the predefined BufferedImages (BufferedImage does that
// first, we further refine it here)
// we can do that because a pointer in C is a pointer (pixel pointer not dependent on DataBuffer type)
SampleModel sm = bufImg.getSampleModel();
SurfaceType sType = SurfaceType.Custom;
int transferType = cm.getTransferType();
int pixelSize = cm.getPixelSize();
int numOfComponents = cm.getNumColorComponents();
if ((numOfComponents == 3) && (cm instanceof ComponentColorModel) && (sm instanceof PixelInterleavedSampleModel)) {
int sizes[] = cm.getComponentSize();
boolean validsizes = (sizes[0] == 8) && (sizes[1] == 8) && (sizes[2] == 8);
int[] offs = ((ComponentSampleModel) sm).getBandOffsets();
int numBands = raster.getNumBands();
boolean bigendian = (offs[0] == numBands - 3) && (offs[1] == numBands - 2) && (offs[2] == numBands - 1);
boolean littleendian = (offs[0] == numBands - 1) && (offs[1] == numBands - 2) && (offs[2] == numBands - 3);
if ((pixelSize == 32) && (transferType == DataBuffer.TYPE_INT)) {
if (validsizes && bigendian && cm.hasAlpha() && cm.isAlphaPremultiplied() && sizes[3] == 8) {
try {
sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_ARGB_PRE);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && bigendian && cm.hasAlpha() && sizes[3] == 8) {
try {
sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_ARGB);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && littleendian && cm.hasAlpha() && cm.isAlphaPremultiplied() && sizes[3] == 8) {
try {
sData = createDataIC(bufImg, sType, BufferedImage.TYPE_4BYTE_ABGR_PRE);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && littleendian && cm.hasAlpha() && sizes[3] == 8) {
try {
sData = createDataIC(bufImg, sType, BufferedImage.TYPE_4BYTE_ABGR);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && bigendian) {
try {
sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_RGB);
} catch (ClassCastException e) {
sData = null;
}
}
} else if ((pixelSize == 32) && (transferType == DataBuffer.TYPE_BYTE)) {
if (validsizes && bigendian && cm.hasAlpha() && cm.isAlphaPremultiplied() && sizes[3] == 8) {
try {
sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_INT_ARGB_PRE);
} catch (ClassCastException e) {
sData = null;
}
}
if (validsizes && bigendian && cm.hasAlpha() && sizes[3] == 8) {
try {
sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_INT_ARGB);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && littleendian && cm.hasAlpha() && cm.isAlphaPremultiplied() && sizes[3] == 8) {
try {
sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_4BYTE_ABGR_PRE);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && littleendian && cm.hasAlpha() && sizes[3] == 8) {
try {
sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_4BYTE_ABGR);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && littleendian) {
try {
sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_INT_BGR);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && bigendian) {
try {
sData = createDataBC(bufImg, sType, 3, BufferedImage.TYPE_INT_RGB);
} catch (ClassCastException e) {
sData = null;
}
}
} else if ((pixelSize == 24) && (transferType == DataBuffer.TYPE_INT)) {
if (validsizes && bigendian) {
try {
sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_RGB);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && littleendian) {
try {
sData = createDataIC(bufImg, sType, BufferedImage.TYPE_INT_BGR);
} catch (ClassCastException e) {
sData = null;
}
}
} else if ((pixelSize == 24) && (transferType == DataBuffer.TYPE_BYTE)) {
if (validsizes && bigendian) {
try {
sData = createDataBC(bufImg, sType, 0, TYPE_3BYTE_RGB);
} catch (ClassCastException e) {
sData = null;
}
} else if (validsizes && littleendian) {
try {
sData = createDataBC(bufImg, sType, 0, BufferedImage.TYPE_3BYTE_BGR);
} catch (ClassCastException e) {
sData = null;
}
}
} else if ((pixelSize == 16) && (transferType == DataBuffer.TYPE_USHORT)) {
validsizes = (sizes[0] == 5) && (sizes[1] == 6) && (sizes[2] == 5);
if (validsizes && bigendian) {
try {
sData = createDataSC(bufImg, sType, null, BufferedImage.TYPE_USHORT_565_RGB);
} catch (ClassCastException e) {
sData = null;
}
}
} else if ((pixelSize == 16) && (transferType == DataBuffer.TYPE_BYTE)) {
validsizes = (sizes[0] == 5) && (sizes[1] == 6) && (sizes[2] == 5);
if (validsizes && bigendian) {
try {
sData = createDataBC(bufImg, sType, 1, BufferedImage.TYPE_USHORT_565_RGB);
} catch (ClassCastException e) {
sData = null;
}
}
} else if ((pixelSize == 15) && (transferType == DataBuffer.TYPE_USHORT)) {
validsizes = (sizes[0] == 5) && (sizes[1] == 5) && (sizes[2] == 5);
if (validsizes && bigendian) {
try {
sData = createDataSC(bufImg, sType, null, BufferedImage.TYPE_USHORT_555_RGB);
} catch (ClassCastException e) {
sData = null;
}
}
} else if ((pixelSize == 15) && (transferType == DataBuffer.TYPE_BYTE)) {
validsizes = (sizes[0] == 5) && (sizes[1] == 5) && (sizes[2] == 5);
if (validsizes && bigendian) {
try {
sData = createDataBC(bufImg, sType, 1, BufferedImage.TYPE_USHORT_555_RGB);
} catch (ClassCastException e) {
sData = null;
}
}
}
}
}
break;
}
// we failed to match
if (sData == null) {
sData = new OSXOffScreenSurfaceData(bufImg, SurfaceType.Custom);
OSXOffScreenSurfaceData offsd = (OSXOffScreenSurfaceData) sData;
// 2004_03_26 cmc: We used to use createCompatibleImage here. Now that createCompatibleImage returns
// an INT_ARGB_PRE instead of an NIO-based image, we need to explicitly create an NIO-based image.
IntegerNIORaster backupRaster = (IntegerNIORaster) IntegerNIORaster.createNIORaster(bufImg.getWidth(), bufImg.getHeight(), dcmBackup.getMasks(), null);
offsd.bimBackup = new BufferedImage(dcmBackup, backupRaster, dcmBackup.isAlphaPremultiplied(), null);
// the trick that makes it work - assign the raster from backup to the surface data of the original image
offsd.initCustomRaster(backupRaster.getBuffer(),
backupRaster.getWidth(),
backupRaster.getHeight(),
offsd.fGraphicsStates,
offsd.fGraphicsStatesObject,
offsd.fImageInfo);
//offsd.checkIfLazyPixelConversionDisabled();
offsd.fImageInfoInt.put(kImageStolenIndex, 1);
}
return (OSXOffScreenSurfaceData) sData;
}
private static SurfaceData createDataIC(BufferedImage bImg, SurfaceType sType, int iType) {
OSXOffScreenSurfaceData offsd = new OSXOffScreenSurfaceData(bImg, sType);
IntegerComponentRaster icRaster = (IntegerComponentRaster) bImg.getRaster();
offsd.initRaster(icRaster.getDataStorage(),
icRaster.getDataOffset(0) * 4,
icRaster.getWidth(),
icRaster.getHeight(),
icRaster.getPixelStride() * 4,
icRaster.getScanlineStride() * 4,
null,
iType,
offsd.fGraphicsStates,
offsd.fGraphicsStatesObject,
offsd.fImageInfo);
// offsd.checkIfLazyPixelConversionDisabled();
offsd.fImageInfoInt.put(kImageStolenIndex, 1);
return offsd;
}
public static SurfaceData createDataIC(BufferedImage bImg, SurfaceType sType) {
return createDataIC(bImg, sType, bImg.getType());
}
private static SurfaceData createDataSC(BufferedImage bImg, SurfaceType sType, IndexColorModel icm, int iType) {
OSXOffScreenSurfaceData offsd = new OSXOffScreenSurfaceData(bImg, sType);
ShortComponentRaster scRaster = (ShortComponentRaster) bImg.getRaster();
offsd.initRaster(scRaster.getDataStorage(),
scRaster.getDataOffset(0) * 2,
scRaster.getWidth(),
scRaster.getHeight(),
scRaster.getPixelStride() * 2,
scRaster.getScanlineStride() * 2,
icm,
iType,
offsd.fGraphicsStates,
offsd.fGraphicsStatesObject,
offsd.fImageInfo);
//offsd.checkIfLazyPixelConversionDisabled();
offsd.fImageInfoInt.put(kImageStolenIndex, 1);
return offsd;
}
public static SurfaceData createDataSC(BufferedImage bImg, SurfaceType sType, IndexColorModel icm) {
return createDataSC(bImg, sType, icm, bImg.getType());
}
private static SurfaceData createDataBC(BufferedImage bImg, SurfaceType sType, int primaryBank, int iType) {
OSXOffScreenSurfaceData offsd = new OSXOffScreenSurfaceData(bImg, sType);
ByteComponentRaster bcRaster = (ByteComponentRaster) bImg.getRaster();
ColorModel cm = bImg.getColorModel();
IndexColorModel icm = ((cm instanceof IndexColorModel) ? (IndexColorModel) cm : null);
offsd.initRaster(bcRaster.getDataStorage(),
bcRaster.getDataOffset(primaryBank),
bcRaster.getWidth(),
bcRaster.getHeight(),
bcRaster.getPixelStride(),
bcRaster.getScanlineStride(),
icm,
iType,
offsd.fGraphicsStates,
offsd.fGraphicsStatesObject,
offsd.fImageInfo);
offsd.fImageInfoInt.put(kImageStolenIndex, 1);
return offsd;
}
public static SurfaceData createDataBC(BufferedImage bImg, SurfaceType sType, int primaryBank) {
return createDataBC(bImg, sType, primaryBank, bImg.getType());
}
private static SurfaceData createDataBP(BufferedImage bImg, SurfaceType sType, int iType) {
OSXOffScreenSurfaceData offsd = new OSXOffScreenSurfaceData(bImg, sType);
BytePackedRaster bpRaster = (BytePackedRaster) bImg.getRaster();
ColorModel cm = bImg.getColorModel();
IndexColorModel icm = ((cm instanceof IndexColorModel) ? (IndexColorModel) cm : null);
offsd.initRaster(bpRaster.getDataStorage(),
bpRaster.getDataBitOffset(), // in bits, NOT bytes! (needs special attention in native
// code!)
bpRaster.getWidth(),
bpRaster.getHeight(),
bpRaster.getPixelBitStride(),
bpRaster.getScanlineStride() * 8,
icm,
iType,
offsd.fGraphicsStates,
offsd.fGraphicsStatesObject,
offsd.fImageInfo);
//offsd.checkIfLazyPixelConversionDisabled();
offsd.fImageInfoInt.put(kImageStolenIndex, 1);
return offsd;
}
protected native void initRaster(Object theArray, int offset, int width, int height, int pixStr, int scanStr, IndexColorModel icm, int type, ByteBuffer graphicsStates, Object graphicsStatesObjects, ByteBuffer imageInfo);
protected native void initCustomRaster(IntBuffer buffer, int width, int height, ByteBuffer graphicsStates, Object graphicsStatesObjects, ByteBuffer imageInfo);
public Object getLockObject() {
return this.lock;
}
// Makes the constructor package private instead of public.
OSXOffScreenSurfaceData(BufferedImage bufImg, SurfaceType sType) {
super(sType, bufImg.getColorModel());
setBounds(0, 0, bufImg.getWidth(), bufImg.getHeight());
this.bim = bufImg;
this.fImageInfo = ByteBuffer.allocateDirect(4 * kSizeOfParameters);
this.fImageInfo.order(ByteOrder.nativeOrder());
this.fImageInfoInt = this.fImageInfo.asIntBuffer();
this.fImageInfoInt.put(kNeedToSyncFromJavaPixelsIndex, 1); // need to sync from Java the very first time
this.fImageInfoInt.put(kNativePixelsChangedIndex, 0);
this.fImageInfoInt.put(kImageStolenIndex, 0);
this.lock = new Object();
}
/**
* Performs a copyArea within this surface.
*/
public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) {
// <rdar://problem/4488745> For the Sun2D renderer we should rely on the implementation of the super class.
// BufImageSurfaceData.java doesn't have an implementation of copyArea() and relies on the super class.
if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
return false;
}
// reset the clip (this is how it works on windows)
// we actually can handle a case with any clips but windows ignores the light clip
Shape clip = sg2d.getClip();
sg2d.setClip(getBounds());
// clip copyArea
Rectangle clippedCopyAreaRect = clipCopyArea(sg2d, x, y, w, h, dx, dy);
if (clippedCopyAreaRect == null) {
// clipped out
return true;
}
// the rectangle returned from clipCopyArea() is in the coordinate space
// of the surface (image)
x = clippedCopyAreaRect.x;
y = clippedCopyAreaRect.y;
w = clippedCopyAreaRect.width;
h = clippedCopyAreaRect.height;
// copy (dst coordinates are in the coord space of the graphics2d, and
// src coordinates are in the coordinate space of the image)
// sg2d.drawImage expects the destination rect to be in the coord space
// of the graphics2d. <rdar://3746194> (vm)
// we need to substract the transX and transY to move it
// to the coordinate space of the graphics2d.
int dstX = x + dx - sg2d.transX;
int dstY = y + dy - sg2d.transY;
sg2d.drawImage(this.bim, dstX, dstY, dstX + w, dstY + h,
x, y, x + w, y + h, null);
// restore the clip
sg2d.setClip(clip);
return true;
}
/**
* Performs a copyarea from this surface to a buffered image. If null is passed in for the image a new image will be
* created.
*
* Only used by compositor code (private API)
*/
public BufferedImage copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, BufferedImage dstImage) {
// create the destination image if needed
if (dstImage == null) {
dstImage = getDeviceConfiguration().createCompatibleImage(w, h);
}
// copy
Graphics g = dstImage.createGraphics();
g.drawImage(this.bim, 0, 0, w, h, x, y, x + w, y + h, null);
g.dispose();
return dstImage;
}
public boolean xorSurfacePixels(SunGraphics2D sg2d, BufferedImage srcPixels, int x, int y, int w, int h, int colorXOR) {
int type = this.bim.getType();
if ((type == BufferedImage.TYPE_INT_ARGB_PRE) || (type == BufferedImage.TYPE_INT_ARGB) || (type == BufferedImage.TYPE_INT_RGB)) { return xorSurfacePixels(createData(srcPixels), colorXOR, x, y, w, h); }
return false;
}
native boolean xorSurfacePixels(SurfaceData src, int colorXOR, int x, int y, int w, int h);
public void clearRect(BufferedImage bim, int w, int h) {
OSXOffScreenSurfaceData offsd = (OSXOffScreenSurfaceData) (OSXOffScreenSurfaceData.createData(bim));
// offsd.clear();
if (offsd.clearSurfacePixels(w, h) == false) {
Graphics2D g = bim.createGraphics();
g.setComposite(AlphaComposite.Clear);
g.fillRect(0, 0, w, h);
g.dispose();
}
}
native boolean clearSurfacePixels(int w, int h);
// 04/06/04 cmc: radr://3612381 Graphics.drawImage ignores bgcolor parameter.
// getCopyWithBgColor returns a new version of an image, drawn with a background
// color. Called by blitImage in OSXSurfaceData.java.
BufferedImage copyWithBgColor_cache = null;
public SurfaceData getCopyWithBgColor(Color bgColor) {
int bimW = this.bim.getWidth();
int bimH = this.bim.getHeight();
if ((this.copyWithBgColor_cache == null)
|| (this.copyWithBgColor_cache.getWidth() < bimW) || (this.copyWithBgColor_cache.getHeight() < bimH)) {
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
this.copyWithBgColor_cache = gc.createCompatibleImage(bimW, bimH);
}
Graphics g2 = this.copyWithBgColor_cache.createGraphics();
g2.setColor(bgColor);
g2.fillRect(0, 0, bimW, bimH);
g2.drawImage(this.bim, 0, 0, bimW, bimH, null);
g2.dispose();
return getSurfaceData(this.copyWithBgColor_cache);
}
/**
* Invoked before the raster's contents are to be read (via one of the modifier methods in Raster such as
* getPixel())
*/
public void rasterRead() {
if (fImageInfoInt.get(kNativePixelsChangedIndex) == 1) {
syncToJavaPixels();
}
}
/**
* Invoked before the raster's contents are to be written to (via one of the modifier methods in Raster such as
* setPixel())
*/
public void rasterWrite() {
if (fImageInfoInt.get(kNativePixelsChangedIndex) == 1) {
syncToJavaPixels();
}
fImageInfoInt.put(kNeedToSyncFromJavaPixelsIndex, 1); // the pixels will change
}
private void syncFromCustom() {
}
private void syncToCustom() {
}
// /**
// * Invoked when the raster's contents will be taken (via the Raster.getDataBuffer() method)
// */
// public void rasterStolen() {
// fImageInfoInt.put(kImageStolenIndex, 1); // this means we must convert between Java and native pixels every
// // single primitive! (very expensive)
// if (fImageInfoInt.get(kNativePixelsChangedIndex) == 1) {
// syncToJavaPixels();
// }
//
// // we know the pixels have been stolen, no need to listen for changes any more
//// if (this.bufImgSunRaster != null) {
//// this.bufImgSunRaster.setRasterListener(null);
//// }
// }
private native void syncToJavaPixels();
// we need to refer to rasters often, so cache them
void cacheRasters(BufferedImage bim) {
this.bufImgRaster = bim.getRaster();
if (this.bufImgRaster instanceof SunWritableRaster) {
this.bufImgSunRaster = (SunWritableRaster) this.bufImgRaster;
}
}
// void setRasterListener() {
// if (this.bufImgSunRaster != null) {
// this.bufImgSunRaster.setRasterListener(this);
//
// Raster parentRaster = this.bufImgSunRaster.getParent();
// if (parentRaster != null) {
// if (parentRaster instanceof SunWritableRaster) {
// // mark subimages stolen to turn off lazy pixel conversion (gznote: can we do better here?)
// ((SunWritableRaster) parentRaster).notifyStolen();
// }
// rasterStolen();
// }
// } else {
// // it's a custom image (non-natively supported) and we can not set a raster listener
// // so mark the image as stolen - this will turn off LazyPixelConversion optimization (slow, but correct)
// rasterStolen();
// }
// }
}