Create BufferedImage using our own buffer - allows faster pixel
writing
This commit is contained in:
parent
eed29f4763
commit
cf10e506fe
4 changed files with 134 additions and 107 deletions
|
|
@ -3,6 +3,7 @@ package org.dynmap.kzedmap;
|
|||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
|
@ -17,6 +18,11 @@ import org.dynmap.MapTile;
|
|||
import org.dynmap.MapType;
|
||||
import org.dynmap.MapChunkCache;
|
||||
import org.json.simple.JSONObject;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
|
||||
public class KzedMap extends MapType {
|
||||
protected static final Logger log = Logger.getLogger("Minecraft");
|
||||
|
|
@ -41,11 +47,18 @@ public class KzedMap extends MapType {
|
|||
MapTileRenderer[] renderers;
|
||||
ZoomedTileRenderer zoomrenderer;
|
||||
|
||||
/* BufferedImage with direct access to its ARGB-formatted data buffer */
|
||||
public static class KzedBufferedImage {
|
||||
public BufferedImage buf_img;
|
||||
public int[] argb_buf;
|
||||
public int width;
|
||||
public int height;
|
||||
}
|
||||
|
||||
/* BufferedImage cache - we use the same things a lot... */
|
||||
private static Object lock = new Object();
|
||||
private static HashMap<Long, LinkedList<BufferedImage>> imgcache =
|
||||
new HashMap<Long, LinkedList<BufferedImage>>(); /* Indexed by resolution - X<<32+Y */
|
||||
private static int[] zerobuf = new int[128];
|
||||
private static HashMap<Long, LinkedList<KzedBufferedImage>> imgcache =
|
||||
new HashMap<Long, LinkedList<KzedBufferedImage>>(); /* Indexed by resolution - X<<32+Y */
|
||||
private static final int CACHE_LIMIT = 10;
|
||||
|
||||
public KzedMap(ConfigurationNode configuration) {
|
||||
|
|
@ -263,22 +276,24 @@ public class KzedMap extends MapType {
|
|||
* @param x - x dimension
|
||||
* @param y - y dimension
|
||||
*/
|
||||
public static BufferedImage allocateBufferedImage(int x, int y) {
|
||||
BufferedImage img = null;
|
||||
public static KzedBufferedImage allocateBufferedImage(int x, int y) {
|
||||
KzedBufferedImage img = null;
|
||||
synchronized(lock) {
|
||||
long k = (x<<16) + y;
|
||||
LinkedList<BufferedImage> ll = imgcache.get(k);
|
||||
LinkedList<KzedBufferedImage> ll = imgcache.get(k);
|
||||
if(ll != null) {
|
||||
img = ll.poll();
|
||||
}
|
||||
}
|
||||
if(img != null) { /* Got it - reset it for use */
|
||||
if(zerobuf.length < x)
|
||||
zerobuf = new int[x];
|
||||
img.setRGB(0, 0, x, y, zerobuf, 0, 0);
|
||||
Arrays.fill(img.argb_buf, 0);
|
||||
}
|
||||
else {
|
||||
img = new BufferedImage(x, y, BufferedImage.TYPE_INT_ARGB);
|
||||
img = new KzedBufferedImage();
|
||||
img.width = x;
|
||||
img.height = y;
|
||||
img.argb_buf = new int[x*y];
|
||||
img.buf_img = createBufferedImage(img.argb_buf, img.width, img.height);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
|
@ -286,13 +301,13 @@ public class KzedMap extends MapType {
|
|||
/**
|
||||
* Return buffered image to pool
|
||||
*/
|
||||
public static void freeBufferedImage(BufferedImage img) {
|
||||
img.flush();
|
||||
public static void freeBufferedImage(KzedBufferedImage img) {
|
||||
img.buf_img.flush();
|
||||
synchronized(lock) {
|
||||
long k = (img.getWidth()<<16) + img.getHeight();
|
||||
LinkedList<BufferedImage> ll = imgcache.get(k);
|
||||
long k = (img.width<<16) + img.height;
|
||||
LinkedList<KzedBufferedImage> ll = imgcache.get(k);
|
||||
if(ll == null) {
|
||||
ll = new LinkedList<BufferedImage>();
|
||||
ll = new LinkedList<KzedBufferedImage>();
|
||||
imgcache.put(k, ll);
|
||||
}
|
||||
if(ll.size() < CACHE_LIMIT) {
|
||||
|
|
@ -308,4 +323,21 @@ public class KzedMap extends MapType {
|
|||
renderer.buildClientConfiguration(worldObject);
|
||||
}
|
||||
}
|
||||
|
||||
/* ARGB band masks */
|
||||
private static final int [] band_masks = {0xFF0000, 0xFF00, 0xff, 0xff000000};
|
||||
|
||||
/**
|
||||
* Build BufferedImage from provided ARGB array and dimensions
|
||||
*/
|
||||
public static BufferedImage createBufferedImage(int[] argb_buf, int w, int h) {
|
||||
/* Create integer-base data buffer */
|
||||
DataBuffer db = new DataBufferInt (argb_buf, w*h);
|
||||
/* Create writable raster */
|
||||
WritableRaster raster = Raster.createPackedRaster(db, w, h, w, band_masks, null);
|
||||
/* RGB color model */
|
||||
ColorModel color_model = ColorModel.getRGBdefault ();
|
||||
/* Return buffered image */
|
||||
return new BufferedImage (color_model, raster, false, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue