diff options
author | Xavier Ducrohet <xav@android.com> | 2010-12-01 10:43:11 -0800 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2010-12-01 10:43:11 -0800 |
commit | a4784054ddf4e10b40af2a864ab7eb592966c8d1 (patch) | |
tree | e75d76d44be48a5e965ddbead717912e64352dc9 /eclipse | |
parent | 632cb06abcf0af0dec812804efd6168978e637c2 (diff) | |
parent | 8dcbdc76135c8cc6a48cfa9b3e05c183522aff41 (diff) | |
download | sdk-a4784054ddf4e10b40af2a864ab7eb592966c8d1.zip sdk-a4784054ddf4e10b40af2a864ab7eb592966c8d1.tar.gz sdk-a4784054ddf4e10b40af2a864ab7eb592966c8d1.tar.bz2 |
Merge "ADT: The image given to layoutlib now shares data with ImageData"
Diffstat (limited to 'eclipse')
3 files changed, 81 insertions, 79 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageOverlay.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageOverlay.java index 4e5f56a..3177f32 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageOverlay.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageOverlay.java @@ -26,16 +26,8 @@ import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.PaletteData; -import java.awt.Point; -import java.awt.color.ColorSpace; import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.ComponentColorModel; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferByte; -import java.awt.image.PixelInterleavedSampleModel; -import java.awt.image.Raster; -import java.awt.image.SampleModel; +import java.awt.image.DataBufferInt; import java.awt.image.WritableRaster; /** @@ -57,11 +49,6 @@ public class ImageOverlay extends Overlay implements IImageFactory { /** Horizontal scaling & scrollbar information. */ private CanvasTransform mHScale; - /** - * A lazily instantiated SWT sample model - */ - private PixelInterleavedSampleModel mSampleModel; - /** * Constructs an {@link ImageOverlay} tied to the given canvas. @@ -99,8 +86,8 @@ public class ImageOverlay extends Overlay implements IImageFactory { * @param awtImage The AWT image to be rendered as an SWT image. * @return The corresponding SWT image, or null. */ - public Image setImage(BufferedImage awtImage) { - if (awtImage != mAwtImage) { + public synchronized Image setImage(BufferedImage awtImage) { + if (awtImage != mAwtImage || awtImage == null) { mAwtImage = null; if (mImage != null) { @@ -113,21 +100,8 @@ public class ImageOverlay extends Overlay implements IImageFactory { mImage = SwtUtils.convertToSwt(mCanvas.getDisplay(), awtImage, false, -1); } } else { - // The image being passed is the one that was created in #getImage(int,int), - // we can create an SWT image more efficiently. - WritableRaster awtRaster = mAwtImage.getRaster(); - DataBufferByte byteBuffer = (DataBufferByte) awtRaster.getDataBuffer(); - byte[] data = byteBuffer.getData(); - - ImageData imageData = new ImageData(mAwtImage.getWidth(), mAwtImage.getHeight(), 32, - new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF)); - - // normally we'd use ImageData.setPixels() but it only accepts int[] for 32 bits image. - // However from #getImage(int, int), we know the raster data is the same exact format - // as the SWT image, so we just do a copy. - System.arraycopy(data, 0, imageData.data, 0, data.length); - - mImage = new Image(getDevice(), imageData); + assert awtImage instanceof SwtReadyBufferedImage; + mImage = ((SwtReadyBufferedImage)awtImage).getSwtImage(); } return mImage; @@ -143,7 +117,7 @@ public class ImageOverlay extends Overlay implements IImageFactory { } @Override - public void paint(GC gc) { + public synchronized void paint(GC gc) { if (mImage != null) { boolean valid = mCanvas.getViewHierarchy().isValid(); if (!valid) { @@ -223,47 +197,76 @@ public class ImageOverlay extends Overlay implements IImageFactory { } } - public BufferedImage getImage(int w, int h) { - if (mAwtImage == null || - mAwtImage.getWidth() != w || - mAwtImage.getHeight() != h) { - - ImageData imageData = - new ImageData(w, h, 32, new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF)); - Image image = new Image(getDevice(), imageData); - - // get the new imageData in case the host OS forced a different format. - imageData = image.getImageData(); + /** + * Custom {@link BufferedImage} class able to convert itself into an SWT {@link Image} + * efficiently. + * + * The BufferedImage also contains an instance of {@link ImageData} that's kept around + * and used to create new SWT {@link Image} objects in {@link #getSwtImage()}. + * + */ + private static final class SwtReadyBufferedImage extends BufferedImage { + + private final ImageData mImageData; + private final Device mDevice; + + /** + * Creates the image with a given model, raster and SWT {@link ImageData} + * @param model the color model + * @param raster the image raster + * @param imageData the SWT image data. + * @param device the {@link Device} in which the SWT image will be painted. + */ + private SwtReadyBufferedImage(int width, int height, ImageData imageData, Device device) { + super(width, height, BufferedImage.TYPE_INT_ARGB); + mImageData = imageData; + mDevice = device; + } - // create a writable raster around the image data. - WritableRaster raster = (WritableRaster) Raster.createRaster( - getSampleModel(imageData.palette, w, h), - new DataBufferByte(imageData.data, imageData.data.length), - new Point(0,0)); + /** + * Returns a new {@link Image} object initialized with the content of the BufferedImage. + * @return the image object. + */ + private Image getSwtImage() { + // transfer the content of the bufferedImage into the image data. + WritableRaster raster = getRaster(); + int[] imageDataBuffer = ((DataBufferInt) raster.getDataBuffer()).getData(); - ColorModel colorModel = new ComponentColorModel( - ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), - true /*hasAlpha*/, true /*isAlphaPremultiplied*/, - ColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE); + mImageData.setPixels(0, 0, imageDataBuffer.length, imageDataBuffer, 0); - mAwtImage = new BufferedImage(colorModel, raster, false, null); + return new Image(mDevice, mImageData); } - return mAwtImage; + /** + * Creates a new {@link SwtReadyBufferedImage}. + * @param w the width of the image + * @param h the height of the image + * @param device the device in which the SWT image will be painted + * @return a new {@link SwtReadyBufferedImage} object + */ + private static SwtReadyBufferedImage createImage(int w, int h, Device device) { + ImageData imageData = new ImageData(w, h, 32, + new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF)); + + SwtReadyBufferedImage swtReadyImage = new SwtReadyBufferedImage(w, h, + imageData, device); + + return swtReadyImage; + } } - private SampleModel getSampleModel(PaletteData palette, int w, int h) { - if (mSampleModel == null) { - return mSampleModel = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, w, h, - 4 /*pixel stride*/, w * 4 /*scanlineStride*/, - getBandOffset(palette)); + /** + * Implementation of {@link IImageFactory#getImage(int, int)}. + */ + public BufferedImage getImage(int w, int h) { + if (mAwtImage == null || + mAwtImage.getWidth() != w || + mAwtImage.getHeight() != h) { + + mAwtImage = SwtReadyBufferedImage.createImage(w, h, getDevice()); } - return mSampleModel.createCompatibleSampleModel(w, h); + return mAwtImage; } - private int[] getBandOffset(PaletteData palette) { - // FIXME actually figure out the PixelInterleavedSampleModel's band offset from the image data palette. - return new int[] {3, 2, 1, 0}; - } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java index e05db27..ed42207 100755 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java @@ -996,19 +996,20 @@ class LayoutCanvas extends Canvas { scene.animate(viewObject, "testanim", false /*isFrameworkAnimation*/, new IAnimationListener() { private int mCount = 0; - private BufferedImage mImage; private boolean mPendingDrawing = false; - public synchronized void onNewFrame(final BufferedImage image) { + public void onNewFrame(final BufferedImage image) { mCount++; - mImage = image; - if (mPendingDrawing == false) { - getDisplay().asyncExec(new Runnable() { - public void run() { - drawImage(); - } - }); - - mPendingDrawing = true; + mImageOverlay.setImage(image); + synchronized (this) { + if (mPendingDrawing == false) { + getDisplay().asyncExec(new Runnable() { + public void run() { + drawImage(); + } + }); + + mPendingDrawing = true; + } } } @@ -1026,8 +1027,6 @@ class LayoutCanvas extends Canvas { public void drawImage() { // get last image synchronized (this) { - mImageOverlay.setImage(mImage); - mImage = null; mPendingDrawing = false; } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtils.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtils.java index 854ebf5..29a6059 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtils.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/SwtUtils.java @@ -27,7 +27,7 @@ import org.eclipse.swt.widgets.Display; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; -import java.awt.image.Raster; +import java.awt.image.WritableRaster; import java.lang.reflect.Field; import java.util.List; @@ -85,7 +85,7 @@ public class SwtUtils { int width = awtImage.getWidth(); int height = awtImage.getHeight(); - Raster raster = awtImage.getData(new java.awt.Rectangle(width, height)); + WritableRaster raster = awtImage.getRaster(); int[] imageDataBuffer = ((DataBufferInt) raster.getDataBuffer()).getData(); ImageData imageData = |