aboutsummaryrefslogtreecommitdiffstats
path: root/eclipse/plugins
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2010-11-29 17:49:19 -0800
committerXavier Ducrohet <xav@android.com>2010-11-30 14:59:48 -0800
commit645b8a905ad70a7d0623dfbbfe6da720da038de9 (patch)
tree539839f309b7d83d10002c31de932c3580da6b27 /eclipse/plugins
parent7aebcab2414437c477570804d602a8b163d964de (diff)
downloadsdk-645b8a905ad70a7d0623dfbbfe6da720da038de9.zip
sdk-645b8a905ad70a7d0623dfbbfe6da720da038de9.tar.gz
sdk-645b8a905ad70a7d0623dfbbfe6da720da038de9.tar.bz2
ADT/Layoutlib: New API to let the caller instantiate the bitmap.
This allows us to use a bitmap more compatible with SWT. In ADT's case, because the bitmap needs to be converted to SWT before being displayed, we create a BufferedImage using a byte[] instead of a int[] so that we can simply do an array copy. Also, we reuse the generated BufferedImage unless the size changed, which lets us see less GC during animation playback. Change-Id: I0062a4f4442ff6469cf0ad4f501c1fbe8c719400
Diffstat (limited to 'eclipse/plugins')
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java5
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/ImageOverlay.java100
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/LayoutCanvas.java4
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/Overlay.java7
4 files changed, 106 insertions, 10 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java
index 8cb13e6..1e51994 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/GraphicalEditorPart.java
@@ -1436,12 +1436,17 @@ public class GraphicalEditorPart extends EditorPart
theme, isProjectTheme,
configuredProjectRes, frameworkResources, mProjectCallback,
mLogger);
+
if (transparentBackground) {
// It doesn't matter what the background color is as long as the alpha
// is 0 (fully transparent). We're using red to make it more obvious if
// for some reason the background is painted when it shouldn't be.
params.setCustomBackgroundColor(0x00FF0000);
}
+
+ // set the Image Overlay as the image factory.
+ params.setImageFactory(getCanvasControl().getImageOverlay());
+
LayoutScene scene = layoutLib.getBridge().createScene(params);
return scene;
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 893ed8f..4e5f56a 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
@@ -16,20 +16,37 @@
package com.android.ide.eclipse.adt.internal.editors.layout.gle2;
+import com.android.layoutlib.api.IImageFactory;
+
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.GC;
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.WritableRaster;
/**
* The {@link ImageOverlay} class renders an image as an overlay.
*/
-public class ImageOverlay extends Overlay {
+public class ImageOverlay extends Overlay implements IImageFactory {
/** Current background image. Null when there's no image. */
private Image mImage;
+ /** Current background AWT image. This is created by {@link #getImage()}, which is called
+ * by the LayoutLib. */
+ private BufferedImage mAwtImage;
/** The associated {@link LayoutCanvas}. */
private LayoutCanvas mCanvas;
@@ -41,6 +58,12 @@ public class ImageOverlay extends Overlay {
private CanvasTransform mHScale;
/**
+ * A lazily instantiated SWT sample model
+ */
+ private PixelInterleavedSampleModel mSampleModel;
+
+
+ /**
* Constructs an {@link ImageOverlay} tied to the given canvas.
*
* @param canvas The {@link LayoutCanvas} to paint the overlay over.
@@ -77,14 +100,34 @@ public class ImageOverlay extends Overlay {
* @return The corresponding SWT image, or null.
*/
public Image setImage(BufferedImage awtImage) {
- if (mImage != null) {
- mImage.dispose();
- }
- if (awtImage == null) {
- mImage = null;
+ if (awtImage != mAwtImage) {
+ mAwtImage = null;
+
+ if (mImage != null) {
+ mImage.dispose();
+ }
+ if (awtImage == null) {
+ mImage = null;
+ } else {
+ mImage = SwtUtils.convertToSwt(mCanvas.getDisplay(), awtImage, false, -1);
+ }
} else {
- mImage = SwtUtils.convertToSwt(mCanvas.getDisplay(), awtImage, false, -1);
+ // 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);
}
return mImage;
@@ -180,4 +223,47 @@ public class ImageOverlay extends Overlay {
}
}
+ 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();
+
+ // 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));
+
+ ColorModel colorModel = new ComponentColorModel(
+ ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB),
+ true /*hasAlpha*/, true /*isAlphaPremultiplied*/,
+ ColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);
+
+ mAwtImage = new BufferedImage(colorModel, raster, false, null);
+ }
+
+ return mAwtImage;
+ }
+
+ 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));
+ }
+
+ return mSampleModel.createCompatibleSampleModel(w, h);
+ }
+
+ 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 430fd68..e05db27 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
@@ -1025,14 +1025,12 @@ class LayoutCanvas extends Canvas {
*/
public void drawImage() {
// get last image
- BufferedImage image;
synchronized (this) {
- image = mImage;
+ mImageOverlay.setImage(mImage);
mImage = null;
mPendingDrawing = false;
}
- mImageOverlay.setImage(image);
redraw();
}
});
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/Overlay.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/Overlay.java
index ac96d76..432d074 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/Overlay.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/gle2/Overlay.java
@@ -26,6 +26,8 @@ import org.eclipse.swt.graphics.GC;
* {@link MoveGesture}.
*/
public abstract class Overlay {
+ private Device mDevice;
+
/**
* Construct the overlay, using the given graphics context for painting.
*/
@@ -41,6 +43,7 @@ public abstract class Overlay {
* to {@link #paint} will correspond to this device.
*/
public void create(Device device) {
+ mDevice = device;
}
/**
@@ -59,4 +62,8 @@ public abstract class Overlay {
throw new IllegalArgumentException("paint() not implemented, probably done "
+ "with specialized paint signature");
}
+
+ public Device getDevice() {
+ return mDevice;
+ }
}