From 28aa3a810f56b89d90ae32e5e75101db133ff530 Mon Sep 17 00:00:00 2001 From: Brian Hinz Date: Thu, 5 Apr 2012 02:08:49 +0000 Subject: [PATCH] BufferedImage performance is poor on Microsoft Windows platforms, so fallback to the 1.2 implementation if the BI cannot be HW accelerated. Also streamline some of the code by removing synchronized statements and making the method calls themselves synchronized. Modification to the selector implementation to make it behave more like a unix selector git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4880 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- .../tigervnc/network/SocketDescriptor.java | 39 ++++--- java/com/tigervnc/rfb/CMsgWriter.java | 16 +-- java/com/tigervnc/rfb/CMsgWriterV3.java | 12 +- java/com/tigervnc/rfb/TightDecoder.java | 11 +- .../tigervnc/vncviewer/AWTPixelBuffer.java | 103 +++++++++++++++++ .../com/tigervnc/vncviewer/BIPixelBuffer.java | 105 ++++++++++++++++++ java/com/tigervnc/vncviewer/CConn.java | 67 ++++------- .../com/tigervnc/vncviewer/DesktopWindow.java | 70 ++++++------ ...ferImage.java => PlatformPixelBuffer.java} | 73 ++---------- 9 files changed, 306 insertions(+), 190 deletions(-) create mode 100644 java/com/tigervnc/vncviewer/AWTPixelBuffer.java create mode 100644 java/com/tigervnc/vncviewer/BIPixelBuffer.java rename java/com/tigervnc/vncviewer/{PixelBufferImage.java => PlatformPixelBuffer.java} (60%) diff --git a/java/com/tigervnc/network/SocketDescriptor.java b/java/com/tigervnc/network/SocketDescriptor.java index f9207316..e336a863 100644 --- a/java/com/tigervnc/network/SocketDescriptor.java +++ b/java/com/tigervnc/network/SocketDescriptor.java @@ -38,12 +38,14 @@ public class SocketDescriptor extends SocketChannel try { channel = SocketChannel.open(); channel.configureBlocking(false); - selector = Selector.open(); + writeSelector = Selector.open(); + readSelector = Selector.open(); } catch (IOException e) { throw new Exception(e.toString()); } try { - channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE ); + channel.register(writeSelector, SelectionKey.OP_WRITE); + channel.register(readSelector, SelectionKey.OP_READ); } catch (java.nio.channels.ClosedChannelException e) { throw new Exception(e.toString()); } @@ -90,6 +92,12 @@ public class SocketDescriptor extends SocketChannel synchronized public int select(int interestOps, Integer timeout) throws Exception { int n; + Selector selector; + if ((interestOps & SelectionKey.OP_READ) != 0) { + selector = readSelector; + } else { + selector = writeSelector; + } selector.selectedKeys().clear(); try { if (timeout == null) { @@ -105,20 +113,10 @@ public class SocketDescriptor extends SocketChannel break; } } - if (n == 0) - return -1; } catch (java.io.IOException e) { throw new Exception(e.toString()); } - Set keys = selector.selectedKeys(); - Iterator iter = keys.iterator(); - while (iter.hasNext()) { - SelectionKey key = (SelectionKey)iter.next(); - if ((key.readyOps() & interestOps) != 0) { - return n; - } - } - return 0; + return n; } public int write(ByteBuffer buf) throws Exception { @@ -198,22 +196,27 @@ public class SocketDescriptor extends SocketChannel try { if (channel != null) channel.close(); - if (selector != null) - selector.close(); + if (readSelector != null) + readSelector.close(); + if (writeSelector != null) + writeSelector.close(); channel = channel_; channel.configureBlocking(false); - selector = Selector.open(); + writeSelector = Selector.open(); + readSelector = Selector.open(); } catch (java.io.IOException e) { throw new Exception(e.toString()); } try { - channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE ); + channel.register(writeSelector, SelectionKey.OP_WRITE); + channel.register(readSelector, SelectionKey.OP_READ); } catch (java.nio.channels.ClosedChannelException e) { System.out.println(e.toString()); } } protected SocketChannel channel; - protected Selector selector; + protected Selector writeSelector; + protected Selector readSelector; } diff --git a/java/com/tigervnc/rfb/CMsgWriter.java b/java/com/tigervnc/rfb/CMsgWriter.java index c4f43554..af7d1370 100644 --- a/java/com/tigervnc/rfb/CMsgWriter.java +++ b/java/com/tigervnc/rfb/CMsgWriter.java @@ -24,7 +24,7 @@ abstract public class CMsgWriter { abstract public void writeClientInit(boolean shared); - public void writeSetPixelFormat(PixelFormat pf) + synchronized public void writeSetPixelFormat(PixelFormat pf) { startMsg(MsgTypes.msgTypeSetPixelFormat); os.pad(3); @@ -32,7 +32,7 @@ abstract public class CMsgWriter { endMsg(); } - public void writeSetEncodings(int nEncodings, int[] encodings) + synchronized public void writeSetEncodings(int nEncodings, int[] encodings) { startMsg(MsgTypes.msgTypeSetEncodings); os.skip(1); @@ -45,7 +45,7 @@ abstract public class CMsgWriter { // Ask for encodings based on which decoders are supported. Assumes higher // encoding numbers are more desirable. - public void writeSetEncodings(int preferredEncoding, boolean useCopyRect) + synchronized public void writeSetEncodings(int preferredEncoding, boolean useCopyRect) { int nEncodings = 0; int[] encodings = new int[Encodings.encodingMax+3]; @@ -113,7 +113,7 @@ abstract public class CMsgWriter { writeSetEncodings(nEncodings, encodings); } - public void writeFramebufferUpdateRequest(Rect r, boolean incremental) + synchronized public void writeFramebufferUpdateRequest(Rect r, boolean incremental) { startMsg(MsgTypes.msgTypeFramebufferUpdateRequest); os.writeU8(incremental?1:0); @@ -124,7 +124,7 @@ abstract public class CMsgWriter { endMsg(); } - public void writeKeyEvent(int key, boolean down) + synchronized public void writeKeyEvent(int key, boolean down) { startMsg(MsgTypes.msgTypeKeyEvent); os.writeU8(down?1:0); @@ -133,7 +133,7 @@ abstract public class CMsgWriter { endMsg(); } - public void writePointerEvent(Point pos, int buttonMask) + synchronized public void writePointerEvent(Point pos, int buttonMask) { Point p = new Point(pos.x,pos.y); if (p.x < 0) p.x = 0; @@ -148,7 +148,7 @@ abstract public class CMsgWriter { endMsg(); } - public void writeClientCutText(String str, int len) + synchronized public void writeClientCutText(String str, int len) { startMsg(MsgTypes.msgTypeClientCutText); os.pad(3); @@ -165,7 +165,7 @@ abstract public class CMsgWriter { abstract public void startMsg(int type); abstract public void endMsg(); - public void setOutStream(OutStream os_) { os = os_; } + synchronized public void setOutStream(OutStream os_) { os = os_; } ConnParams getConnParams() { return cp; } OutStream getOutStream() { return os; } diff --git a/java/com/tigervnc/rfb/CMsgWriterV3.java b/java/com/tigervnc/rfb/CMsgWriterV3.java index 430c3746..8f01f3c2 100644 --- a/java/com/tigervnc/rfb/CMsgWriterV3.java +++ b/java/com/tigervnc/rfb/CMsgWriterV3.java @@ -26,20 +26,20 @@ public class CMsgWriterV3 extends CMsgWriter { public CMsgWriterV3(ConnParams cp_, OutStream os_) { super(cp_, os_); } - public void writeClientInit(boolean shared) { + synchronized public void writeClientInit(boolean shared) { os.writeU8(shared?1:0); endMsg(); } - public void startMsg(int type) { + synchronized public void startMsg(int type) { os.writeU8(type); } - public void endMsg() { + synchronized public void endMsg() { os.flush(); } - public void writeSetDesktopSize(int width, int height, + synchronized public void writeSetDesktopSize(int width, int height, ScreenSet layout) { if (!cp.supportsSetDesktopSize) @@ -67,7 +67,7 @@ public class CMsgWriterV3 extends CMsgWriter { endMsg(); } - public void writeFence(int flags, int len, byte[] data) + synchronized public void writeFence(int flags, int len, byte[] data) { if (!cp.supportsFence) throw new Exception("Server does not support fences"); @@ -87,7 +87,7 @@ public class CMsgWriterV3 extends CMsgWriter { endMsg(); } - public void writeEnableContinuousUpdates(boolean enable, + synchronized public void writeEnableContinuousUpdates(boolean enable, int x, int y, int w, int h) { if (!cp.supportsContinuousUpdates) diff --git a/java/com/tigervnc/rfb/TightDecoder.java b/java/com/tigervnc/rfb/TightDecoder.java index 74244572..9902097e 100644 --- a/java/com/tigervnc/rfb/TightDecoder.java +++ b/java/com/tigervnc/rfb/TightDecoder.java @@ -249,16 +249,7 @@ public class TightDecoder extends Decoder { // Create an Image object from the JPEG data. Image jpeg = tk.createImage(netbuf); - tk.prepareImage(jpeg, -1, -1, null); - synchronized(this) { - while ((tk.checkImage(jpeg, -1, -1, null) & ImageObserver.ALLBITS) == 0) { - try { - this.wait(1); - } catch (InterruptedException e) { - throw new Exception("Error decoding JPEG data"); - } - } - } + jpeg.setAccelerationPriority(1); handler.imageRect(r, jpeg); jpeg.flush(); } diff --git a/java/com/tigervnc/vncviewer/AWTPixelBuffer.java b/java/com/tigervnc/vncviewer/AWTPixelBuffer.java new file mode 100644 index 00000000..6b74eee9 --- /dev/null +++ b/java/com/tigervnc/vncviewer/AWTPixelBuffer.java @@ -0,0 +1,103 @@ +/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright (C) 2011-2012 TigerVNC Team. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +package com.tigervnc.vncviewer; + +import java.awt.*; +import java.awt.image.*; + +import com.tigervnc.rfb.*; +import com.tigervnc.rfb.Exception; + +public class AWTPixelBuffer extends PlatformPixelBuffer +{ + public AWTPixelBuffer(int w, int h, CConn cc_, DesktopWindow desktop_) { + super(w, h, cc_, desktop_); + } + + public void setPF(PixelFormat pf) { + super.setPF(pf); + if (source != null) + source.newPixels(data, cm, 0, width_); + } + + public void updateColourMap() { + cm = new IndexColorModel(8, nColours, reds, greens, blues); + if (source != null) + source.newPixels(data, cm, 0, width_); + } + + // resize() resizes the image, preserving the image data where possible. + public void resize(int w, int h) { + if (w == width() && h == height()) return; + + int rowsToCopy = h < height() ? h : height(); + int copyWidth = w < width() ? w : width(); + int[] oldData = data; + + width_ = w; + height_ = h; + + data = new int[width() * height()]; + for (int i = 0; i < rowsToCopy; i++) + System.arraycopy(oldData, copyWidth * i, + data, width_ * i, copyWidth); + + source = new MemoryImageSource(w, h, cm, data, 0, w); + source.setAnimated(true); + source.setFullBufferUpdates(false); + image = desktop.createImage(source); + source.newPixels(data, cm, 0, width_); + } + + public void fillRect(int x, int y, int w, int h, int pix) { + super.fillRect(x, y, w, h, pix); + source.newPixels(x, y, w, h, true); + } + + public void imageRect(int x, int y, int w, int h, Object pix) { + if (pix instanceof Image) { + PixelGrabber pg = + new PixelGrabber((Image)pix, 0, 0, w, h, data, (width_ * y) + x, width_); + try { + pg.grabPixels(0); + } catch (InterruptedException e) { + vlog.error("Tight Decoding: Wrong JPEG data recieved"); + } + } else { + for (int j = 0; j < h; j++) + System.arraycopy(pix, (w*j), data, width_ * (y + j) + x, w); + } + source.newPixels(x, y, w, h, true); + } + + public void copyRect(int x, int y, int w, int h, int srcX, int srcY) { + super.copyRect(x, y, w, h, srcX, srcY); + source.newPixels(x, y, w, h, true); + } + + public Image getImage() { + return (Image)image; + } + + Image image; + MemoryImageSource source; + + static LogWriter vlog = new LogWriter("AWTPixelBuffer"); +} diff --git a/java/com/tigervnc/vncviewer/BIPixelBuffer.java b/java/com/tigervnc/vncviewer/BIPixelBuffer.java new file mode 100644 index 00000000..cc19c1da --- /dev/null +++ b/java/com/tigervnc/vncviewer/BIPixelBuffer.java @@ -0,0 +1,105 @@ +/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright (C) 2011-2012 TigerVNC Team. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +package com.tigervnc.vncviewer; + +import java.awt.*; +import java.awt.image.*; + +import com.tigervnc.rfb.*; +import com.tigervnc.rfb.Exception; + +public class BIPixelBuffer extends PlatformPixelBuffer +{ + public BIPixelBuffer(int w, int h, CConn cc_, DesktopWindow desktop_) { + super(w, h, cc_, desktop_); + } + + // resize() resizes the image, preserving the image data where possible. + public void resize(int w, int h) { + if (w == width() && h == height()) return; + + width_ = w; + height_ = h; + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + image = gc.createCompatibleImage(w, h, Transparency.OPAQUE); + image.setAccelerationPriority(1); + image.createGraphics(); + } + + public void fillRect(int x, int y, int w, int h, int pix) { + Graphics2D graphics = (Graphics2D)image.getGraphics(); + switch (format.depth) { + case 24: + graphics.setColor(new Color(pix)); + graphics.fillRect(x, y, w, h); + break; + default: + Color color = new Color((0xff << 24) | (cm.getRed(pix) << 16) | + (cm.getGreen(pix) << 8) | (cm.getBlue(pix))); + graphics.setColor(color); + graphics.fillRect(x, y, w, h); + break; + } + graphics.dispose(); + } + + public void imageRect(int x, int y, int w, int h, Object pix) { + Graphics2D graphics = (Graphics2D)image.getGraphics(); + Image img; + if (pix instanceof Image) { + img = (Image)pix; + } else { + img = tk.createImage(new MemoryImageSource(w, h, cm, (int[])pix, 0, w)); + img.setAccelerationPriority(1); + } + boolean ret = tk.prepareImage(img, -1, -1, null); + if (!ret) { + while ((tk.checkImage(img, -1, -1, null) & ImageObserver.ALLBITS) == 0) { + synchronized (this) { + try { + this.wait(0, 10000); + } catch (InterruptedException e) { + throw new Exception("Error decoding JPEG data"); + } + } + } + } + graphics.drawImage(img, x, y, w, h, null); + graphics.dispose(); + img.flush(); + } + + public void copyRect(int x, int y, int w, int h, int srcX, int srcY) { + Graphics2D graphics = (Graphics2D)image.getGraphics(); + graphics.copyArea(srcX, srcY, w, h, x - srcX, y - srcY); + graphics.dispose(); + } + + public Image getImage() { + return (Image)image; + } + + BufferedImage image; + + static LogWriter vlog = new LogWriter("BIPixelBuffer"); +} diff --git a/java/com/tigervnc/vncviewer/CConn.java b/java/com/tigervnc/vncviewer/CConn.java index 061e6fbe..0f95c691 100644 --- a/java/com/tigervnc/vncviewer/CConn.java +++ b/java/com/tigervnc/vncviewer/CConn.java @@ -115,7 +115,6 @@ class ViewportFrame extends JFrame public void addChild(DesktopWindow child) { sp = new JScrollPane(child); - sp.setDoubleBuffered(true); child.setBackground(Color.BLACK); child.setOpaque(true); sp.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); @@ -426,9 +425,7 @@ public class CConn extends CConnection // We need fences to make extra update requests and continuous // updates "safe". See fence() for the next step. if (cp.supportsFence) - synchronized(this) { - writer().writeFence(fenceTypes.fenceFlagRequest | fenceTypes.fenceFlagSyncNext, 0, null); - } + writer().writeFence(fenceTypes.fenceFlagRequest | fenceTypes.fenceFlagSyncNext, 0, null); if (cp.supportsSetDesktopSize && viewer.desktopSize.getValue() != null && @@ -460,9 +457,7 @@ public class CConn extends CConnection screen0.dimensions.br.x = width; screen0.dimensions.br.y = height; - synchronized(this) { - writer().writeSetDesktopSize(width, height, layout); - } + writer().writeSetDesktopSize(width, height, layout); } firstUpdate = false; @@ -537,9 +532,7 @@ public class CConn extends CConnection // We handle everything synchronously so we trivially honor these modes flags = flags & (fenceTypes.fenceFlagBlockBefore | fenceTypes.fenceFlagBlockAfter); - synchronized(this) { - writer().writeFence(flags, len, data); - } + writer().writeFence(flags, len, data); return; } @@ -551,9 +544,7 @@ public class CConn extends CConnection if (cp.supportsContinuousUpdates) { vlog.info("Enabling continuous updates"); continuousUpdates = true; - synchronized(this) { - writer().writeEnableContinuousUpdates(true, 0, 0, cp.width, cp.height); - } + writer().writeEnableContinuousUpdates(true, 0, 0, cp.width, cp.height); } } } else { @@ -574,9 +565,7 @@ public class CConn extends CConnection return; if (continuousUpdates) - synchronized(this) { - writer().writeEnableContinuousUpdates(true, 0, 0, cp.width, cp.height); - } + writer().writeEnableContinuousUpdates(true, 0, 0, cp.width, cp.height); if ((cp.width == 0) && (cp.height == 0)) return; @@ -749,10 +738,8 @@ public class CConn extends CConnection pf.write(memStream); - synchronized(this) { - writer().writeFence(fenceTypes.fenceFlagRequest | fenceTypes.fenceFlagSyncNext, - memStream.length(), (byte[])memStream.data()); - } + writer().writeFence(fenceTypes.fenceFlagRequest | fenceTypes.fenceFlagSyncNext, + memStream.length(), (byte[])memStream.data()); } else { // New requests are sent out at the start of processing the last // one, so we cannot switch our internal format right now (doing so @@ -763,9 +750,7 @@ public class CConn extends CConnection String str = pf.print(); vlog.info("Using pixel format "+str); - synchronized (this) { - writer().writeSetPixelFormat(pf); - } + writer().writeSetPixelFormat(pf); formatChange = false; } @@ -774,10 +759,8 @@ public class CConn extends CConnection if (forceNonincremental || !continuousUpdates) { pendingUpdate = true; - synchronized (this) { - writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height), - !formatChange); - } + writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height), + !formatChange); } forceNonincremental = false; @@ -845,9 +828,7 @@ public class CConn extends CConnection } public void refresh() { - synchronized (this) { - writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height), false); - } + writer().writeFramebufferUpdateRequest(new Rect(0,0,cp.width,cp.height), false); pendingUpdate = true; } @@ -1216,17 +1197,17 @@ public class CConn extends CConnection } // writeClientCutText() is called from the clipboard dialog - synchronized public void writeClientCutText(String str, int len) { + public void writeClientCutText(String str, int len) { if (state() != RFBSTATE_NORMAL) return; writer().writeClientCutText(str,len); } - synchronized public void writeKeyEvent(int keysym, boolean down) { + public void writeKeyEvent(int keysym, boolean down) { if (state() != RFBSTATE_NORMAL) return; writer().writeKeyEvent(keysym, down); } - synchronized public void writeKeyEvent(KeyEvent ev) { + public void writeKeyEvent(KeyEvent ev) { if (ev.getID() != KeyEvent.KEY_PRESSED && !ev.isActionKey()) return; @@ -1335,9 +1316,7 @@ public class CConn extends CConnection break; } - synchronized (this) { - writeModifiers(ev.getModifiers() & ~KeyEvent.ALT_MASK & ~KeyEvent.META_MASK); - } + writeModifiers(ev.getModifiers() & ~KeyEvent.ALT_MASK & ~KeyEvent.META_MASK); if (cp.width != desktop.scaledWidth || cp.height != desktop.scaledHeight) { @@ -1348,9 +1327,7 @@ public class CConn extends CConnection ev.translatePoint(sx - ev.getX(), sy - ev.getY()); } - synchronized (this) { - writer().writePointerEvent(new Point(ev.getX(),ev.getY()), buttonMask); - } + writer().writePointerEvent(new Point(ev.getX(),ev.getY()), buttonMask); if (buttonMask == 0) writeModifiers(0); } @@ -1369,11 +1346,9 @@ public class CConn extends CConnection for (int i=0;i= 0 && e.getX() < im.width() && - e.getY() >= 0 && e.getY() < im.height()) { - cursorPosX = e.getX(); - cursorPosY = e.getY(); - if (softCursor == null) - showLocalCursor(); - } + if (e.getX() >= 0 && e.getX() < im.width() && + e.getY() >= 0 && e.getY() < im.height()) { + cursorPosX = e.getX(); + cursorPosY = e.getY(); + if (softCursor == null) + showLocalCursor(); } } } @@ -527,8 +524,7 @@ class DesktopWindow extends JPanel implements CConn cc; // access to the following must be synchronized: - PixelBufferImage im; - Graphics graphics; + PlatformPixelBuffer im; Thread setColourMapEntriesTimerThread; Cursor cursor; diff --git a/java/com/tigervnc/vncviewer/PixelBufferImage.java b/java/com/tigervnc/vncviewer/PlatformPixelBuffer.java similarity index 60% rename from java/com/tigervnc/vncviewer/PixelBufferImage.java rename to java/com/tigervnc/vncviewer/PlatformPixelBuffer.java index e77f460e..f5844d55 100644 --- a/java/com/tigervnc/vncviewer/PixelBufferImage.java +++ b/java/com/tigervnc/vncviewer/PlatformPixelBuffer.java @@ -17,11 +17,6 @@ * USA. */ -// -// PixelBufferImage is an PixelBuffer which also acts as an ImageProducer. -// Currently it only supports 8-bit colourmapped pixel format. -// - package com.tigervnc.vncviewer; import java.awt.*; @@ -30,9 +25,9 @@ import java.nio.ByteOrder; import com.tigervnc.rfb.*; -public class PixelBufferImage extends PixelBuffer +abstract public class PlatformPixelBuffer extends PixelBuffer { - public PixelBufferImage(int w, int h, CConn cc_, DesktopWindow desktop_) { + public PlatformPixelBuffer(int w, int h, CConn cc_, DesktopWindow desktop_) { cc = cc_; desktop = desktop_; PixelFormat nativePF = getNativePF(); @@ -45,30 +40,7 @@ public class PixelBufferImage extends PixelBuffer } // resize() resizes the image, preserving the image data where possible. - public void resize(int w, int h) { - if (w == width() && h == height()) return; - - width_ = w; - height_ = h; - switch (format.depth) { - case 3: - // Fall-through to depth 8 - case 6: - // Fall-through to depth 8 - case 8: - image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED); - break; - default: - GraphicsEnvironment ge = - GraphicsEnvironment.getLocalGraphicsEnvironment(); - GraphicsDevice gd = ge.getDefaultScreenDevice(); - GraphicsConfiguration gc = gd.getDefaultConfiguration(); - image = gc.createCompatibleImage(w, h, Transparency.OPAQUE); - break; - } - image.setAccelerationPriority(1); - graphics = image.createGraphics(); - } + abstract public void resize(int w, int h); public PixelFormat getNativePF() { PixelFormat pf; @@ -96,34 +68,7 @@ public class PixelBufferImage extends PixelBuffer return pf; } - public void fillRect(int x, int y, int w, int h, int pix) { - switch (format.depth) { - case 24: - graphics.setColor(new Color(pix)); - graphics.fillRect(x, y, w, h); - break; - default: - Color color = new Color((0xff << 24) | (cm.getRed(pix) << 16) | - (cm.getGreen(pix) << 8) | (cm.getBlue(pix))); - graphics.setColor(color); - graphics.fillRect(x, y, w, h); - break; - } - } - - public void imageRect(int x, int y, int w, int h, Object pix) { - if (pix instanceof java.awt.Image) { - graphics.drawImage((Image)pix, x, y, w, h, null); - } else { - Image img = tk.createImage(new MemoryImageSource(w, h, cm, (int[])pix, 0, w)); - graphics.drawImage(img, x, y, w, h, null); - img.flush(); - } - } - - public void copyRect(int x, int y, int w, int h, int srcX, int srcY) { - graphics.copyArea(srcX, srcY, w, h, x - srcX, y - srcY); - } + abstract public void imageRect(int x, int y, int w, int h, Object pix); // setColourMapEntries() changes some of the entries in the colourmap. // However these settings won't take effect until updateColourMap() is @@ -147,11 +92,11 @@ public class PixelBufferImage extends PixelBuffer cm = new IndexColorModel(8, nColours, reds, greens, blues); } - private static Toolkit tk = java.awt.Toolkit.getDefaultToolkit(); + protected static Toolkit tk = Toolkit.getDefaultToolkit(); + + abstract public Image getImage(); - Graphics2D graphics; - BufferedImage image; - ImageConsumer ic; + protected Image image; int nColours; byte[] reds; @@ -160,5 +105,5 @@ public class PixelBufferImage extends PixelBuffer CConn cc; DesktopWindow desktop; - static LogWriter vlog = new LogWriter("PixelBufferImage"); + static LogWriter vlog = new LogWriter("PlatformPixelBuffer"); } -- 2.39.5