diff options
author | tdv <none@none> | 2008-07-18 10:48:44 -0700 |
---|---|---|
committer | tdv <none@none> | 2008-07-18 10:48:44 -0700 |
commit | ece64035a19f19d319b74da7f27b2fe7c2edbe8c (patch) | |
tree | 920ff3f87f4af71cf604006d8d76144f17d649fd /src/share/classes | |
parent | 85fa01e3802900948bea08a012a908ae85e1d1a1 (diff) |
6725214: D3D: forward-port the new pipeline from 6u10
Summary: Forward port of the new Direct3D 9 rendering pipeline from 6u10. Also includes fixes for 6690659 6689025 6658398 6596234.
Reviewed-by: campbell, prr
--HG--
rename : src/windows/classes/sun/java2d/windows/Win32SurfaceData.java => src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java
rename : src/windows/native/sun/java2d/windows/Win32SurfaceData.cpp => src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.cpp
rename : src/windows/native/sun/java2d/windows/Win32SurfaceData.h => src/windows/native/sun/java2d/windows/GDIWindowSurfaceData.h
Diffstat (limited to 'src/share/classes')
41 files changed, 2390 insertions, 226 deletions
diff --git a/src/share/classes/java/awt/Component.java b/src/share/classes/java/awt/Component.java index 9c54250df..03749b4ca 100644 --- a/src/share/classes/java/awt/Component.java +++ b/src/share/classes/java/awt/Component.java @@ -74,7 +74,11 @@ import sun.awt.dnd.SunDropTargetEvent; import sun.awt.im.CompositionArea; import sun.java2d.SunGraphics2D; import sun.java2d.pipe.Region; +import sun.awt.image.VSyncedBSManager; +import sun.java2d.pipe.hw.ExtendedBufferCapabilities; +import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.*; import sun.awt.RequestFocusController; +import sun.java2d.SunGraphicsEnvironment; /** * A <em>component</em> is an object having a graphical representation @@ -3508,6 +3512,11 @@ public abstract class Component implements ImageObserver, MenuContainer, if (numBuffers == 1) { bufferStrategy = new SingleBufferStrategy(caps); } else { + SunGraphicsEnvironment sge = (SunGraphicsEnvironment) + GraphicsEnvironment.getLocalGraphicsEnvironment(); + if (!caps.isPageFlipping() && sge.isFlipStrategyPreferred(peer)) { + caps = new ProxyCapabilities(caps); + } // assert numBuffers > 1; if (caps.isPageFlipping()) { bufferStrategy = new FlipSubRegionBufferStrategy(numBuffers, caps); @@ -3518,6 +3527,25 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** + * This is a proxy capabilities class used when a FlipBufferStrategy + * is created instead of the requested Blit strategy. + * + * @see sun.awt.SunGraphicsEnvironment#isFlipStrategyPreferred(ComponentPeer) + */ + private class ProxyCapabilities extends ExtendedBufferCapabilities { + private BufferCapabilities orig; + private ProxyCapabilities(BufferCapabilities orig) { + super(orig.getFrontBufferCapabilities(), + orig.getBackBufferCapabilities(), + orig.getFlipContents() == + BufferCapabilities.FlipContents.BACKGROUND ? + BufferCapabilities.FlipContents.BACKGROUND : + BufferCapabilities.FlipContents.COPIED); + this.orig = orig; + } + } + + /** * @return the buffer strategy used by this component * @see Window#createBufferStrategy * @see Canvas#createBufferStrategy @@ -3646,16 +3674,30 @@ public abstract class Component implements ImageObserver, MenuContainer, width = getWidth(); height = getHeight(); - if (drawBuffer == null) { - peer.createBuffers(numBuffers, caps); - } else { + if (drawBuffer != null) { // dispose the existing backbuffers drawBuffer = null; drawVBuffer = null; destroyBuffers(); // ... then recreate the backbuffers - peer.createBuffers(numBuffers, caps); } + + if (caps instanceof ExtendedBufferCapabilities) { + ExtendedBufferCapabilities ebc = + (ExtendedBufferCapabilities)caps; + if (ebc.getVSync() == VSYNC_ON) { + // if this buffer strategy is not allowed to be v-synced, + // change the caps that we pass to the peer but keep on + // trying to create v-synced buffers; + // do not throw IAE here in case it is disallowed, see + // ExtendedBufferCapabilities for more info + if (!VSyncedBSManager.vsyncAllowed(this)) { + caps = ebc.derive(VSYNC_DEFAULT); + } + } + } + + peer.createBuffers(numBuffers, caps); updateInternalBuffers(); } @@ -3700,7 +3742,23 @@ public abstract class Component implements ImageObserver, MenuContainer, */ protected void flip(BufferCapabilities.FlipContents flipAction) { if (peer != null) { - peer.flip(flipAction); + Image backBuffer = getBackBuffer(); + if (backBuffer != null) { + peer.flip(0, 0, + backBuffer.getWidth(null), + backBuffer.getHeight(null), flipAction); + } + } else { + throw new IllegalStateException( + "Component must have a valid peer"); + } + } + + void flipSubRegion(int x1, int y1, int x2, int y2, + BufferCapabilities.FlipContents flipAction) + { + if (peer != null) { + peer.flip(x1, y1, x2, y2, flipAction); } else { throw new IllegalStateException( "Component must have a valid peer"); @@ -3711,6 +3769,7 @@ public abstract class Component implements ImageObserver, MenuContainer, * Destroys the buffers created through this object */ protected void destroyBuffers() { + VSyncedBSManager.releaseVsync(this); if (peer != null) { peer.destroyBuffers(); } else { @@ -3723,7 +3782,11 @@ public abstract class Component implements ImageObserver, MenuContainer, * @return the buffering capabilities of this strategy */ public BufferCapabilities getCapabilities() { - return caps; + if (caps instanceof ProxyCapabilities) { + return ((ProxyCapabilities)caps).orig; + } else { + return caps; + } } /** @@ -3811,6 +3874,14 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** + * Makes specified region of the the next available buffer visible + * by either blitting or flipping. + */ + void showSubRegion(int x1, int y1, int x2, int y2) { + flipSubRegion(x1, y1, x2, y2, caps.getFlipContents()); + } + + /** * {@inheritDoc} * @since 1.6 */ @@ -4080,8 +4151,6 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * Private class to perform sub-region flipping. - * REMIND: this subclass currently punts on subregions and - * flips the entire buffer. */ private class FlipSubRegionBufferStrategy extends FlipBufferStrategy implements SubRegionShowable @@ -4095,14 +4164,13 @@ public abstract class Component implements ImageObserver, MenuContainer, } public void show(int x1, int y1, int x2, int y2) { - show(); + showSubRegion(x1, y1, x2, y2); } // This is invoked by Swing on the toolkit thread. - public boolean validateAndShow(int x1, int y1, int x2, int y2) { - revalidate(false); - if (!contentsRestored() && !contentsLost()) { - show(); + public boolean showIfNotLost(int x1, int y1, int x2, int y2) { + if (!contentsLost()) { + showSubRegion(x1, y1, x2, y2); return !contentsLost(); } return false; @@ -4130,9 +4198,8 @@ public abstract class Component implements ImageObserver, MenuContainer, } // This method is called by Swing on the toolkit thread. - public boolean validateAndShow(int x1, int y1, int x2, int y2) { - revalidate(false); - if (!contentsRestored() && !contentsLost()) { + public boolean showIfNotLost(int x1, int y1, int x2, int y2) { + if (!contentsLost()) { showSubRegion(x1, y1, x2, y2); return !contentsLost(); } diff --git a/src/share/classes/java/awt/GraphicsDevice.java b/src/share/classes/java/awt/GraphicsDevice.java index ee7b14624..e9dfd5a1d 100644 --- a/src/share/classes/java/awt/GraphicsDevice.java +++ b/src/share/classes/java/awt/GraphicsDevice.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems Microsystems, Inc. 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 @@ -236,6 +236,10 @@ public abstract class GraphicsDevice { */ public void setFullScreenWindow(Window w) { if (fullScreenWindow != null && windowedModeBounds != null) { + // if the window went into fs mode before it was realized it may + // have (0,0) dimensions + if (windowedModeBounds.width == 0) windowedModeBounds.width = 1; + if (windowedModeBounds.height == 0) windowedModeBounds.height = 1; fullScreenWindow.setBounds(windowedModeBounds); } // Set the full screen window diff --git a/src/share/classes/java/awt/Robot.java b/src/share/classes/java/awt/Robot.java index 636961101..95d383e5b 100644 --- a/src/share/classes/java/awt/Robot.java +++ b/src/share/classes/java/awt/Robot.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems Microsystems, Inc. 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 @@ -25,12 +25,18 @@ package java.awt; -import java.awt.peer.*; -import java.awt.image.*; -import java.awt.event.*; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import java.awt.image.DirectColorModel; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.awt.peer.RobotPeer; import java.lang.reflect.InvocationTargetException; import sun.awt.ComponentFactory; import sun.awt.SunToolkit; +import sun.awt.image.SunWritableRaster; import sun.security.util.SecurityConstants; /** @@ -335,6 +341,10 @@ public class Robot { /* blue mask */ 0x000000FF); } + // need to sync the toolkit prior to grabbing the pixels since in some + // cases rendering to the screen may be delayed + Toolkit.getDefaultToolkit().sync(); + int pixels[]; int[] bandmasks = new int[3]; @@ -346,6 +356,7 @@ public class Robot { bandmasks[2] = screenCapCM.getBlueMask(); raster = Raster.createPackedRaster(buffer, translatedRect.width, translatedRect.height, translatedRect.width, bandmasks, null); + SunWritableRaster.makeTrackable(buffer); image = new BufferedImage(screenCapCM, raster, false, null); diff --git a/src/share/classes/java/awt/image/DataBuffer.java b/src/share/classes/java/awt/image/DataBuffer.java index a2cbfbc19..c53707fab 100644 --- a/src/share/classes/java/awt/image/DataBuffer.java +++ b/src/share/classes/java/awt/image/DataBuffer.java @@ -1,5 +1,5 @@ /* - * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Portions Copyright 1997-2008 Sun Microsystems Microsystems, Inc. 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 @@ -530,6 +530,12 @@ public abstract class DataBuffer { public StateTrackableDelegate getTrackable(DataBuffer db) { return db.theTrackable; } + + public void setTrackable(DataBuffer db, + StateTrackableDelegate trackable) + { + db.theTrackable = trackable; + } }); } } diff --git a/src/share/classes/java/awt/peer/ComponentPeer.java b/src/share/classes/java/awt/peer/ComponentPeer.java index 603a83a3e..5abe647c9 100644 --- a/src/share/classes/java/awt/peer/ComponentPeer.java +++ b/src/share/classes/java/awt/peer/ComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1995-2008 Sun Microsystems Microsystems, Inc. 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 @@ -88,7 +88,7 @@ public interface ComponentPeer { boolean handlesWheelScrolling(); void createBuffers(int numBuffers, BufferCapabilities caps) throws AWTException; Image getBackBuffer(); - void flip(BufferCapabilities.FlipContents flipAction); + void flip(int x1, int y1, int x2, int y2, BufferCapabilities.FlipContents flipAction); void destroyBuffers(); /** diff --git a/src/share/classes/javax/swing/BufferStrategyPaintManager.java b/src/share/classes/javax/swing/BufferStrategyPaintManager.java index d28113b91..241ff3f4e 100644 --- a/src/share/classes/javax/swing/BufferStrategyPaintManager.java +++ b/src/share/classes/javax/swing/BufferStrategyPaintManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems Microsystems, Inc. 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 @@ -263,7 +263,7 @@ class BufferStrategyPaintManager extends RepaintManager.PaintManager { (SubRegionShowable)bufferStrategy; boolean paintAllOnExpose = info.getPaintAllOnExpose(); info.setPaintAllOnExpose(false); - if (bsSubRegion.validateAndShow(x, y, (x + w), (y + h))) { + if (bsSubRegion.showIfNotLost(x, y, (x + w), (y + h))) { return !paintAllOnExpose; } // Mark the buffer as needing to be repainted. We don't diff --git a/src/share/classes/sun/awt/NullComponentPeer.java b/src/share/classes/sun/awt/NullComponentPeer.java index e5939e4e2..f18699e95 100644 --- a/src/share/classes/sun/awt/NullComponentPeer.java +++ b/src/share/classes/sun/awt/NullComponentPeer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems Microsystems, Inc. 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 @@ -255,7 +255,9 @@ public class NullComponentPeer implements LightweightPeer, throw new IllegalStateException( "Page-flipping is not allowed on a lightweight component"); } - public void flip(BufferCapabilities.FlipContents flipAction) { + public void flip(int x1, int y1, int x2, int y2, + BufferCapabilities.FlipContents flipAction) + { throw new IllegalStateException( "Page-flipping is not allowed on a lightweight component"); } diff --git a/src/share/classes/sun/awt/SubRegionShowable.java b/src/share/classes/sun/awt/SubRegionShowable.java index 5b779a7ed..c279e7096 100644 --- a/src/share/classes/sun/awt/SubRegionShowable.java +++ b/src/share/classes/sun/awt/SubRegionShowable.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. 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 @@ -39,10 +39,11 @@ public interface SubRegionShowable { public void show(int x1, int y1, int x2, int y2); /** - * Validates the buffer and if successful shows the specified region. + * Shows the specified region if the buffer is not lost and the dimensions + * of the back-buffer match those of the component. * * @return true if successful */ // NOTE: this is invoked by swing on the toolkit thread! - public boolean validateAndShow(int x1, int y1, int x2, int y2); + public boolean showIfNotLost(int x1, int y1, int x2, int y2); } diff --git a/src/share/classes/sun/awt/image/SunVolatileImage.java b/src/share/classes/sun/awt/image/SunVolatileImage.java index d0c18f386..4f430af60 100644 --- a/src/share/classes/sun/awt/image/SunVolatileImage.java +++ b/src/share/classes/sun/awt/image/SunVolatileImage.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2008 Sun Microsystems Microsystems, Inc. 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 @@ -29,19 +29,18 @@ import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Component; import java.awt.Font; -import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.ImageCapabilities; import java.awt.Transparency; import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.VolatileImage; -import java.awt.image.WritableRaster; import sun.java2d.SunGraphics2D; -import sun.java2d.SurfaceData; import sun.java2d.SurfaceManagerFactory; +import sun.java2d.DestSurfaceProvider; +import sun.java2d.Surface; +import static sun.java2d.pipe.hw.AccelSurface.*; /** * This class is the base implementation of the VolatileImage @@ -52,23 +51,28 @@ import sun.java2d.SurfaceManagerFactory; * appropriate VolatileSurfaceManager for the GraphicsConfiguration * under which this SunVolatileImage was created. */ -public class SunVolatileImage extends VolatileImage { +public class SunVolatileImage extends VolatileImage + implements DestSurfaceProvider +{ protected VolatileSurfaceManager volSurfaceManager; protected Component comp; private GraphicsConfiguration graphicsConfig; private Font defaultFont; private int width, height; + private int forcedAccelSurfaceType; - private SunVolatileImage(Component comp, - GraphicsConfiguration graphicsConfig, - int width, int height, Object context, - int transparency, ImageCapabilities caps) + protected SunVolatileImage(Component comp, + GraphicsConfiguration graphicsConfig, + int width, int height, Object context, + int transparency, ImageCapabilities caps, + int accType) { this.comp = comp; this.graphicsConfig = graphicsConfig; this.width = width; this.height = height; + this.forcedAccelSurfaceType = accType; if (!(transparency == Transparency.OPAQUE || transparency == Transparency.BITMASK || transparency == Transparency.TRANSLUCENT)) @@ -92,7 +96,7 @@ public class SunVolatileImage extends VolatileImage { ImageCapabilities caps) { this(comp, graphicsConfig, - width, height, context, Transparency.OPAQUE, caps); + width, height, context, Transparency.OPAQUE, caps, UNDEFINED); } public SunVolatileImage(Component comp, int width, int height) { @@ -110,7 +114,8 @@ public class SunVolatileImage extends VolatileImage { int width, int height, int transparency, ImageCapabilities caps) { - this(null, graphicsConfig, width, height, null, transparency, caps); + this(null, graphicsConfig, width, height, null, transparency, + caps, UNDEFINED); } public int getWidth() { @@ -144,6 +149,10 @@ public class SunVolatileImage extends VolatileImage { return comp; } + public int getForcedAccelSurfaceType() { + return forcedAccelSurfaceType; + } + protected VolatileSurfaceManager createSurfaceManager(Object context, ImageCapabilities caps) { @@ -248,4 +257,14 @@ public class SunVolatileImage extends VolatileImage { public ImageCapabilities getCapabilities() { return volSurfaceManager.getCapabilities(graphicsConfig); } + + /** + * {@inheritDoc} + * + * @see sun.java2d.DestSurfaceProvider#getDestSurface + */ + @Override + public Surface getDestSurface() { + return volSurfaceManager.getPrimarySurfaceData(); + } } diff --git a/src/share/classes/sun/awt/image/SunWritableRaster.java b/src/share/classes/sun/awt/image/SunWritableRaster.java index 1c8df2710..b312add69 100644 --- a/src/share/classes/sun/awt/image/SunWritableRaster.java +++ b/src/share/classes/sun/awt/image/SunWritableRaster.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems Microsystems, Inc. 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 @@ -35,6 +35,7 @@ import java.awt.image.DataBufferInt; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; +import sun.java2d.StateTrackable.State; import sun.java2d.SurfaceData; import sun.java2d.StateTrackableDelegate; @@ -54,6 +55,7 @@ public class SunWritableRaster extends WritableRaster { public short[] getData(DataBufferUShort dbus, int bank); public int[] getData(DataBufferInt dbi, int bank); public StateTrackableDelegate getTrackable(DataBuffer db); + public void setTrackable(DataBuffer db, StateTrackableDelegate trackable); } public static void setDataStealer(DataStealer ds) { @@ -79,6 +81,14 @@ public class SunWritableRaster extends WritableRaster { return stealer.getTrackable(db); } + public static void setTrackable(DataBuffer db, StateTrackableDelegate trackable) { + stealer.setTrackable(db, trackable); + } + + public static void makeTrackable(DataBuffer db) { + stealer.setTrackable(db, StateTrackableDelegate.createInstance(State.STABLE)); + } + public static void markDirty(DataBuffer db) { stealer.getTrackable(db).markDirty(); } diff --git a/src/share/classes/sun/awt/image/VSyncedBSManager.java b/src/share/classes/sun/awt/image/VSyncedBSManager.java new file mode 100644 index 000000000..2a072e3ed --- /dev/null +++ b/src/share/classes/sun/awt/image/VSyncedBSManager.java @@ -0,0 +1,121 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.awt.image; + +import java.awt.image.BufferStrategy; +import java.lang.ref.WeakReference; + +/** + * Manages v-synced buffer strategies. + */ +public abstract class VSyncedBSManager { + + private static VSyncedBSManager theInstance; + + private static final boolean vSyncLimit = + Boolean.valueOf((String)java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction( + "sun.java2d.vsynclimit", "true"))); + + private static VSyncedBSManager getInstance(boolean create) { + if (theInstance == null && create) { + theInstance = + vSyncLimit ? new SingleVSyncedBSMgr() : new NoLimitVSyncBSMgr(); + } + return theInstance; + } + + abstract boolean checkAllowed(BufferStrategy bs); + abstract void relinquishVsync(BufferStrategy bs); + + /** + * Returns true if the buffer strategy is allowed to be created + * v-synced. + * + * @return true if the bs is allowed to be v-synced, false otherwise + */ + public static boolean vsyncAllowed(BufferStrategy bs) { + VSyncedBSManager bsm = getInstance(true); + return bsm.checkAllowed(bs); + } + + /** + * Lets the manager know that this buffer strategy is no longer interested + * in being v-synced. + */ + public static synchronized void releaseVsync(BufferStrategy bs) { + VSyncedBSManager bsm = getInstance(false); + if (bsm != null) { + bsm.relinquishVsync(bs); + } + } + + /** + * An instance of the manager which allows any buffer strategy to be + * v-synced. + */ + private static final class NoLimitVSyncBSMgr extends VSyncedBSManager { + @Override + boolean checkAllowed(BufferStrategy bs) { + return true; + } + + @Override + void relinquishVsync(BufferStrategy bs) { + } + } + + /** + * An instance of the manager which allows only one buffer strategy to + * be v-synced at any give moment in the vm. + */ + private static final class SingleVSyncedBSMgr extends VSyncedBSManager { + private WeakReference<BufferStrategy> strategy; + + @Override + public synchronized boolean checkAllowed(BufferStrategy bs) { + if (strategy != null) { + BufferStrategy current = strategy.get(); + if (current != null) { + return (current == bs); + } + } + strategy = new WeakReference<BufferStrategy>(bs); + return true; + } + + @Override + public synchronized void relinquishVsync(BufferStrategy bs) { + if (strategy != null) { + BufferStrategy b = strategy.get(); + if (b == bs) { + strategy.clear(); + strategy = null; + } + } + } + } +} diff --git a/src/share/classes/sun/awt/image/VolatileSurfaceManager.java b/src/share/classes/sun/awt/image/VolatileSurfaceManager.java index 9be25ee64..2b9cd73b0 100644 --- a/src/share/classes/sun/awt/image/VolatileSurfaceManager.java +++ b/src/share/classes/sun/awt/image/VolatileSurfaceManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems Microsystems, Inc. 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 @@ -37,6 +37,7 @@ import sun.awt.image.SunVolatileImage; import sun.java2d.SunGraphicsEnvironment; import sun.java2d.SurfaceData; import sun.java2d.loops.CompositeType; +import static sun.java2d.pipe.hw.AccelSurface.*; /** * This SurfaceManager variant manages an accelerated volatile surface, if it @@ -117,7 +118,11 @@ public abstract class VolatileSurfaceManager sdCurrent = sdAccel; } } - if (sdCurrent == null) { + // only initialize the backup surface for images with unforced + // acceleration type + if (sdCurrent == null && + vImg.getForcedAccelSurfaceType() == UNDEFINED) + { sdCurrent = getBackupSurface(); } } @@ -270,9 +275,13 @@ public abstract class VolatileSurfaceManager * the background). */ public void initContents() { - Graphics g = vImg.createGraphics(); - g.clearRect(0, 0, vImg.getWidth(), vImg.getHeight()); - g.dispose(); + // images with forced acceleration type may have a null sdCurrent + // because we do not create a backup surface for them + if (sdCurrent != null) { + Graphics g = vImg.createGraphics(); + g.clearRect(0, 0, vImg.getWidth(), vImg.getHeight()); + g.dispose(); + } } /** diff --git a/src/share/classes/sun/font/StrikeCache.java b/src/share/classes/sun/font/StrikeCache.java index bfcf032db..041c4ca59 100644 --- a/src/share/classes/sun/font/StrikeCache.java +++ b/src/share/classes/sun/font/StrikeCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems Microsystems, Inc. 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 @@ -25,16 +25,17 @@ package sun.font; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; -import java.awt.Font; -import java.awt.FontFormatException; -import java.util.logging.Level; -import java.util.logging.Logger; import sun.java2d.Disposer; +import sun.java2d.pipe.BufferedContext; +import sun.java2d.pipe.RenderQueue; +import sun.java2d.pipe.hw.AccelGraphicsConfig; import sun.misc.Unsafe; /** @@ -192,13 +193,13 @@ public final class StrikeCache { recentStrikeIndex = index; } - static void disposeStrike(FontStrikeDisposer disposer) { + private static final void doDispose(FontStrikeDisposer disposer) { if (disposer.intGlyphImages != null) { freeIntMemory(disposer.intGlyphImages, - disposer.pScalerContext); + disposer.pScalerContext); } else if (disposer.longGlyphImages != null) { freeLongMemory(disposer.longGlyphImages, - disposer.pScalerContext); + disposer.pScalerContext); } else if (disposer.segIntGlyphImages != null) { /* NB Now making multiple JNI calls in this case. * But assuming that there's a reasonable amount of locality @@ -207,7 +208,7 @@ public final class StrikeCache { for (int i=0; i<disposer.segIntGlyphImages.length; i++) { if (disposer.segIntGlyphImages[i] != null) { freeIntMemory(disposer.segIntGlyphImages[i], - disposer.pScalerContext); + disposer.pScalerContext); /* native will only free the scaler context once */ disposer.pScalerContext = 0L; disposer.segIntGlyphImages[i] = null; @@ -223,7 +224,7 @@ public final class StrikeCache { for (int i=0; i<disposer.segLongGlyphImages.length; i++) { if (disposer.segLongGlyphImages[i] != null) { freeLongMemory(disposer.segLongGlyphImages[i], - disposer.pScalerContext); + disposer.pScalerContext); disposer.pScalerContext = 0L; disposer.segLongGlyphImages[i] = null; } @@ -234,6 +235,44 @@ public final class StrikeCache { } } + static void disposeStrike(final FontStrikeDisposer disposer) { + // we need to execute the strike disposal on the rendering thread + // because they may be accessed on that thread at the time of the + // disposal (for example, when the accel. cache is invalidated) + + // REMIND: this look a bit heavyweight, but should be ok + // because strike disposal is a relatively infrequent operation, + // more worrisome is the necessity of getting a GC here. + RenderQueue rq = null; + GraphicsEnvironment ge = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + if (!ge.isHeadless()) { + GraphicsConfiguration gc = + ge.getDefaultScreenDevice().getDefaultConfiguration(); + if (gc instanceof AccelGraphicsConfig) { + AccelGraphicsConfig agc = (AccelGraphicsConfig)gc; + BufferedContext bc = agc.getContext(); + if (bc != null) { + rq = bc.getRenderQueue(); + } + } + } + if (rq != null) { + rq.lock(); + try { + rq.flushAndInvokeNow(new Runnable() { + public void run() { + doDispose(disposer); + } + }); + } finally { + rq.unlock(); + } + } else { + doDispose(disposer); + } + } + static native void freeIntPointer(int ptr); static native void freeLongPointer(long ptr); private static native void freeIntMemory(int[] glyphPtrs, long pContext); diff --git a/src/share/classes/sun/java2d/DestSurfaceProvider.java b/src/share/classes/sun/java2d/DestSurfaceProvider.java new file mode 100644 index 000000000..d06e05ef8 --- /dev/null +++ b/src/share/classes/sun/java2d/DestSurfaceProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d; + +import sun.java2d.pipe.hw.*; + +/** + * Classes implementing this interface provide access to their + * destination surfaces. + */ +public interface DestSurfaceProvider { + /** + * Returns a surface currently used as a destination surface for rendering. + * + * @return destination surface + */ + public Surface getDestSurface(); +} diff --git a/src/share/classes/sun/java2d/SunGraphics2D.java b/src/share/classes/sun/java2d/SunGraphics2D.java index 46896e311..b95d53a3b 100644 --- a/src/share/classes/sun/java2d/SunGraphics2D.java +++ b/src/share/classes/sun/java2d/SunGraphics2D.java @@ -1,5 +1,5 @@ /* - * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1996-2008 Sun Microsystems Microsystems, Inc. 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 @@ -41,24 +41,17 @@ import java.awt.image.renderable.RenderableImage; import java.awt.image.renderable.RenderContext; import java.awt.image.AffineTransformOp; import java.awt.image.Raster; -import java.awt.image.SampleModel; -import java.awt.image.VolatileImage; import java.awt.image.WritableRaster; import java.awt.Image; import java.awt.Composite; import java.awt.Color; -import java.awt.color.ColorSpace; -import java.awt.image.DataBuffer; import java.awt.image.ColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.DirectColorModel; import java.awt.GraphicsConfiguration; import java.awt.Paint; import java.awt.GradientPaint; import java.awt.LinearGradientPaint; import java.awt.RadialGradientPaint; import java.awt.TexturePaint; -import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.PathIterator; import java.awt.geom.GeneralPath; @@ -69,19 +62,16 @@ import java.awt.Rectangle; import java.text.AttributedCharacterIterator; import java.awt.Font; import java.awt.image.ImageObserver; -import java.awt.image.ColorConvertOp; import java.awt.Transparency; import java.awt.font.GlyphVector; import java.awt.font.TextLayout; import sun.font.FontDesignMetrics; -import sun.font.StandardGlyphVector; import sun.java2d.pipe.PixelDrawPipe; import sun.java2d.pipe.PixelFillPipe; import sun.java2d.pipe.ShapeDrawPipe; import sun.java2d.pipe.ValidatePipe; import sun.java2d.pipe.ShapeSpanIterator; import sun.java2d.pipe.Region; -import sun.java2d.pipe.RegionIterator; import sun.java2d.pipe.TextPipe; import sun.java2d.pipe.DrawImagePipe; import sun.java2d.pipe.LoopPipe; @@ -90,7 +80,6 @@ import sun.java2d.loops.RenderLoops; import sun.java2d.loops.CompositeType; import sun.java2d.loops.SurfaceType; import sun.java2d.loops.Blit; -import sun.java2d.loops.BlitBg; import sun.java2d.loops.MaskFill; import sun.font.FontManager; import java.awt.font.FontRenderContext; @@ -99,7 +88,7 @@ import sun.awt.ConstrainableGraphics; import sun.awt.SunHints; import java.util.Map; import java.util.Iterator; -import sun.awt.image.OffScreenImage; +import sun.java2d.DestSurfaceProvider; import sun.misc.PerformanceLogger; /** @@ -113,7 +102,7 @@ import sun.misc.PerformanceLogger; */ public final class SunGraphics2D extends Graphics2D - implements ConstrainableGraphics, Cloneable + implements ConstrainableGraphics, Cloneable, DestSurfaceProvider { /* * Attribute States @@ -3306,4 +3295,14 @@ public final class SunGraphics2D public Object getDestination() { return surfaceData.getDestination(); } + + /** + * {@inheritDoc} + * + * @see sun.java2d.DestSurfaceProvider#getDestSurface + */ + @Override + public Surface getDestSurface() { + return surfaceData; + } } diff --git a/src/share/classes/sun/java2d/SunGraphicsEnvironment.java b/src/share/classes/sun/java2d/SunGraphicsEnvironment.java index d4f9424ef..89f9e103c 100644 --- a/src/share/classes/sun/java2d/SunGraphicsEnvironment.java +++ b/src/share/classes/sun/java2d/SunGraphicsEnvironment.java @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2008 Sun Microsystems Microsystems, Inc. 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 @@ -36,6 +36,7 @@ import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.font.TextAttribute; import java.awt.image.BufferedImage; +import java.awt.peer.ComponentPeer; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -1313,4 +1314,18 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment /* * ----END DISPLAY CHANGE SUPPORT---- */ + + /** + * Returns true if FlipBufferStrategy with COPIED buffer contents + * is preferred for this peer's GraphicsConfiguration over + * BlitBufferStrategy, false otherwise. + * + * The reason FlipBS could be preferred is that in some configurations + * an accelerated copy to the screen is supported (like Direct3D 9) + * + * @return true if flip strategy should be used, false otherwise + */ + public boolean isFlipStrategyPreferred(ComponentPeer peer) { + return false; + } } diff --git a/src/share/classes/sun/java2d/Surface.java b/src/share/classes/sun/java2d/Surface.java new file mode 100644 index 000000000..7a0fa44c6 --- /dev/null +++ b/src/share/classes/sun/java2d/Surface.java @@ -0,0 +1,34 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d; + +/** + * This is a tag interface for a surface. + * @see sun.java2d.SurfaceData + * @see sun.java2d.pipe.hw.AccelSurface + */ +public interface Surface { +} diff --git a/src/share/classes/sun/java2d/SurfaceData.java b/src/share/classes/sun/java2d/SurfaceData.java index fa4429dd2..e5431679b 100644 --- a/src/share/classes/sun/java2d/SurfaceData.java +++ b/src/share/classes/sun/java2d/SurfaceData.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems Microsystems, Inc. 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 @@ -93,7 +93,7 @@ import sun.awt.image.SurfaceManager; * retrieved the tracker. */ public abstract class SurfaceData - implements Transparency, DisposerTarget, StateTrackable + implements Transparency, DisposerTarget, StateTrackable, Surface { private long pData; private boolean valid; diff --git a/src/share/classes/sun/java2d/SurfaceDataProxy.java b/src/share/classes/sun/java2d/SurfaceDataProxy.java index 66ee63444..f94419ca4 100644 --- a/src/share/classes/sun/java2d/SurfaceDataProxy.java +++ b/src/share/classes/sun/java2d/SurfaceDataProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. 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 @@ -521,7 +521,7 @@ public abstract class SurfaceDataProxy CompositeType.SrcNoEa, dstType); blitbg.BlitBg(srcData, dstData, - AlphaComposite.Src, null, bgColor, + AlphaComposite.Src, null, bgColor.getRGB(), 0, 0, 0, 0, w, h); dstData.markDirty(); } diff --git a/src/share/classes/sun/java2d/loops/BlitBg.java b/src/share/classes/sun/java2d/loops/BlitBg.java index a64e8e81f..7385bbd0f 100644 --- a/src/share/classes/sun/java2d/loops/BlitBg.java +++ b/src/share/classes/sun/java2d/loops/BlitBg.java @@ -1,5 +1,5 @@ /* - * Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2008 Sun Microsystems Microsystems, Inc. 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 @@ -109,7 +109,7 @@ public class BlitBg extends GraphicsPrimitive */ public native void BlitBg(SurfaceData src, SurfaceData dst, Composite comp, Region clip, - Color bgColor, + int bgColor, int srcx, int srcy, int dstx, int dsty, int width, int height); @@ -142,19 +142,19 @@ public class BlitBg extends GraphicsPrimitive compositeType = comptype; } + @Override public void BlitBg(SurfaceData srcData, SurfaceData dstData, Composite comp, Region clip, - Color bgColor, + int bgArgb, int srcx, int srcy, int dstx, int dsty, int width, int height) { ColorModel dstModel = dstData.getColorModel(); - if (!dstModel.hasAlpha() && - bgColor.getTransparency() != Transparency.OPAQUE) - { + boolean bgHasAlpha = (bgArgb >>> 24) != 0xff; + if (!dstModel.hasAlpha() && bgHasAlpha) { dstModel = ColorModel.getRGBdefault(); } WritableRaster wr = @@ -163,6 +163,7 @@ public class BlitBg extends GraphicsPrimitive BufferedImage bimg = new BufferedImage(dstModel, wr, isPremult, null); SurfaceData tmpData = BufImgSurfaceData.createData(bimg); + Color bgColor = new Color(bgArgb, bgHasAlpha); SunGraphics2D sg2d = new SunGraphics2D(tmpData, bgColor, bgColor, defaultFont); FillRect fillop = FillRect.locate(SurfaceType.AnyColor, @@ -201,9 +202,10 @@ public class BlitBg extends GraphicsPrimitive return this; } + @Override public void BlitBg(SurfaceData src, SurfaceData dst, Composite comp, Region clip, - Color bgColor, + int bgColor, int srcx, int srcy, int dstx, int dsty, int width, int height) { diff --git a/src/share/classes/sun/java2d/loops/GeneralRenderer.java b/src/share/classes/sun/java2d/loops/GeneralRenderer.java index 8c7a4862a..57d1e373b 100644 --- a/src/share/classes/sun/java2d/loops/GeneralRenderer.java +++ b/src/share/classes/sun/java2d/loops/GeneralRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2008 Sun Microsystems Microsystems, Inc. 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 @@ -159,6 +159,10 @@ public final class GeneralRenderer { { int mx, my, x1, y1; int[] tmp = null; + + if (nPoints <= 0) { + return; + } mx = x1 = xPoints[off] + transx; my = y1 = yPoints[off] + transy; while (--nPoints > 0) { diff --git a/src/share/classes/sun/java2d/opengl/OGLBufImgOps.java b/src/share/classes/sun/java2d/opengl/OGLBufImgOps.java index 2b62bd473..1becb763c 100644 --- a/src/share/classes/sun/java2d/opengl/OGLBufImgOps.java +++ b/src/share/classes/sun/java2d/opengl/OGLBufImgOps.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. 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 @@ -35,6 +35,7 @@ import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; import sun.java2d.loops.CompositeType; import sun.java2d.pipe.BufferedBufImgOps; +import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; class OGLBufImgOps extends BufferedBufImgOps { @@ -94,7 +95,7 @@ class OGLBufImgOps extends BufferedBufImgOps { OGLSurfaceData oglSrc = (OGLSurfaceData)srcData; OGLGraphicsConfig gc = oglSrc.getOGLGraphicsConfig(); if (oglSrc.getType() != OGLSurfaceData.TEXTURE || - !gc.isCapPresent(OGLContext.CAPS_EXT_BIOP_SHADER)) + !gc.isCapPresent(CAPS_EXT_BIOP_SHADER)) { return false; } diff --git a/src/share/classes/sun/java2d/opengl/OGLContext.java b/src/share/classes/sun/java2d/opengl/OGLContext.java index 99bff126f..9b0bc46db 100644 --- a/src/share/classes/sun/java2d/opengl/OGLContext.java +++ b/src/share/classes/sun/java2d/opengl/OGLContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2004-2008 Sun Microsystems Microsystems, Inc. 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 @@ -25,91 +25,24 @@ package sun.java2d.opengl; -import java.awt.AlphaComposite; -import java.awt.Composite; -import java.awt.Paint; -import java.awt.geom.AffineTransform; -import sun.java2d.SunGraphics2D; import sun.java2d.pipe.BufferedContext; -import sun.java2d.pipe.Region; import sun.java2d.pipe.RenderBuffer; import sun.java2d.pipe.RenderQueue; +import sun.java2d.pipe.hw.ContextCapabilities; import static sun.java2d.pipe.BufferedOpCodes.*; +import static sun.java2d.pipe.hw.ContextCapabilities.*; /** * Note that the RenderQueue lock must be acquired before calling any of * the methods in this class. */ -class OGLContext extends BufferedContext { - - /** Indicates that the context has no capabilities. */ - static final int CAPS_EMPTY = (0 << 0); - /** Indicates that the context is doublebuffered. */ - static final int CAPS_DOUBLEBUFFERED = (1 << 0); - /** Indicates that the context supports a stored alpha channel. */ - static final int CAPS_STORED_ALPHA = (1 << 1); - /** Indicates the presence of the GL_ARB_multitexture extension. */ - static final int CAPS_EXT_MULTITEXTURE = (1 << 2); - /** Indicates the presence of the GL_ARB_texture_non_power_of_two ext. */ - static final int CAPS_EXT_TEXNONPOW2 = (1 << 3); - /** - * Indicates the presence of the GL_EXT_framebuffer_object extension. - * This cap will only be set if the fbobject system property has been - * enabled and we are able to create an FBO with depth buffer. - */ - static final int CAPS_EXT_FBOBJECT = (1 << 4); - /** - * Indicates the presence of the GL_ARB_fragment_shader extension. - * This cap will only be set if the lcdshader system property has been - * enabled and the hardware supports the minimum number of texture units. - */ - static final int CAPS_EXT_LCD_SHADER = (1 << 5); - /** Indicates the presence of the GL_ARB_texture_rectangle extension. */ - static final int CAPS_EXT_TEXRECT = (1 << 6); - /** - * Indicates the presence of the GL_ARB_fragment_shader extension. - * This cap will only be set if the biopshader system property has been - * enabled and the hardware meets our minimum requirements. - */ - static final int CAPS_EXT_BIOP_SHADER = (1 << 7); - /** - * Indicates the presence of the GL_ARB_fragment_shader extension. - * This cap will only be set if the gradshader system property has been - * enabled and the hardware meets our minimum requirements. - */ - static final int CAPS_EXT_GRAD_SHADER = (1 << 8); +public class OGLContext extends BufferedContext { - OGLContext(RenderQueue rq) { - super(rq); - } + private final OGLGraphicsConfig config; - /** - * Fetches the OGLContext associated with the current GraphicsConfig - * and validates the context using the given parameters. Most rendering - * operations will call this method first in order to set the necessary - * state before issuing rendering commands. - */ - static void validateContext(OGLSurfaceData srcData, - OGLSurfaceData dstData, - Region clip, Composite comp, - AffineTransform xform, - Paint paint, SunGraphics2D sg2d, - int flags) - { - // assert rq.lock.isHeldByCurrentThread(); - OGLContext oglc = dstData.getContext(); - oglc.validate(srcData, dstData, - clip, comp, xform, paint, sg2d, flags); - } - - /** - * Simplified version of validateContext() that disables all context - * state settings. - */ - static void validateContext(OGLSurfaceData dstData) { - // assert rq.lock.isHeldByCurrentThread(); - validateContext(dstData, dstData, - null, null, null, null, null, NO_CONTEXT_FLAGS); + OGLContext(RenderQueue rq, OGLGraphicsConfig config) { + super(rq); + this.config = config; } /** @@ -160,19 +93,128 @@ class OGLContext extends BufferedContext { static void invalidateCurrentContext() { // assert OGLRenderQueue.getInstance().lock.isHeldByCurrentThread(); - // first invalidate the context reference at the native level, and + // invalidate the current Java-level context so that we + // revalidate everything the next time around + if (currentContext != null) { + currentContext.invalidateContext(); + currentContext = null; + } + + // invalidate the context reference at the native level, and // then flush the queue so that we have no pending operations // dependent on the current context OGLRenderQueue rq = OGLRenderQueue.getInstance(); rq.ensureCapacity(4); rq.getBuffer().putInt(INVALIDATE_CONTEXT); rq.flushNow(); + } - // then invalidate the current Java-level context so that we - // revalidate everything the next time around - if (currentContext != null) { - currentContext.invalidateSurfaces(); - currentContext = null; + public RenderQueue getRenderQueue() { + return OGLRenderQueue.getInstance(); + } + + /** + * Returns a string representing adapter id (vendor, renderer, version). + * Must be called on the rendering thread. + * + * @return an id string for the adapter + */ + static final native String getOGLIdString(); + + @Override + public void saveState() { + // assert rq.lock.isHeldByCurrentThread(); + + // reset all attributes of this and current contexts + invalidateContext(); + invalidateCurrentContext(); + + setScratchSurface(config); + + // save the state on the native level + rq.ensureCapacity(4); + buf.putInt(SAVE_STATE); + rq.flushNow(); + } + + @Override + public void restoreState() { + // assert rq.lock.isHeldByCurrentThread(); + + // reset all attributes of this and current contexts + invalidateContext(); + invalidateCurrentContext(); + + setScratchSurface(config); + + // restore the state on the native level + rq.ensureCapacity(4); + buf.putInt(RESTORE_STATE); + rq.flushNow(); + } + + static class OGLContextCaps extends ContextCapabilities { + /** + * Indicates the presence of the GL_EXT_framebuffer_object extension. + * This cap will only be set if the fbobject system property has been + * enabled and we are able to create an FBO with depth buffer. + */ + static final int CAPS_EXT_FBOBJECT = + (CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE); + /** Indicates that the context supports a stored alpha channel. */ + static final int CAPS_STORED_ALPHA = CAPS_RT_PLAIN_ALPHA; + /** Indicates that the context is doublebuffered. */ + static final int CAPS_DOUBLEBUFFERED = (FIRST_PRIVATE_CAP << 0); + /** + * Indicates the presence of the GL_ARB_fragment_shader extension. + * This cap will only be set if the lcdshader system property has been + * enabled and the hardware supports the minimum number of texture units + */ + static final int CAPS_EXT_LCD_SHADER = (FIRST_PRIVATE_CAP << 1); + /** + * Indicates the presence of the GL_ARB_fragment_shader extension. + * This cap will only be set if the biopshader system property has been + * enabled and the hardware meets our minimum requirements. + */ + static final int CAPS_EXT_BIOP_SHADER = (FIRST_PRIVATE_CAP << 2); + /** + * Indicates the presence of the GL_ARB_fragment_shader extension. + * This cap will only be set if the gradshader system property has been + * enabled and the hardware meets our minimum requirements. + */ + static final int CAPS_EXT_GRAD_SHADER = (FIRST_PRIVATE_CAP << 3); + /** Indicates the presence of the GL_ARB_texture_rectangle extension. */ + static final int CAPS_EXT_TEXRECT = (FIRST_PRIVATE_CAP << 4); + + OGLContextCaps(int caps, String adapterId) { + super(caps, adapterId); + } + + @Override + public String toString() { + StringBuffer buf = new StringBuffer(super.toString()); + if ((caps & CAPS_EXT_FBOBJECT) != 0) { + buf.append("CAPS_EXT_FBOBJECT|"); + } + if ((caps & CAPS_STORED_ALPHA) != 0) { + buf.append("CAPS_STORED_ALPHA|"); + } + if ((caps & CAPS_DOUBLEBUFFERED) != 0) { + buf.append("CAPS_DOUBLEBUFFERED|"); + } + if ((caps & CAPS_EXT_LCD_SHADER) != 0) { + buf.append("CAPS_EXT_LCD_SHADER|"); + } + if ((caps & CAPS_EXT_BIOP_SHADER) != 0) { + buf.append("CAPS_BIOP_SHADER|"); + } + if ((caps & CAPS_EXT_GRAD_SHADER) != 0) { + buf.append("CAPS_EXT_GRAD_SHADER|"); + } + if ((caps & CAPS_EXT_TEXRECT) != 0) { + buf.append("CAPS_EXT_TEXRECT|"); + } + return buf.toString(); } } } diff --git a/src/share/classes/sun/java2d/opengl/OGLGraphicsConfig.java b/src/share/classes/sun/java2d/opengl/OGLGraphicsConfig.java index 32de60627..b8b8cf46c 100644 --- a/src/share/classes/sun/java2d/opengl/OGLGraphicsConfig.java +++ b/src/share/classes/sun/java2d/opengl/OGLGraphicsConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems Microsystems, Inc. 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 @@ -27,13 +27,16 @@ package sun.java2d.opengl; import sun.java2d.SurfaceData; import sun.awt.image.SurfaceManager; +import sun.java2d.pipe.hw.AccelGraphicsConfig; /** * This interface collects the methods that are provided by both * GLXGraphicsConfig and WGLGraphicsConfig, making it easier to invoke these * methods directly from OGLSurfaceData. */ -interface OGLGraphicsConfig extends SurfaceManager.ProxiedGraphicsConfig { +interface OGLGraphicsConfig extends + AccelGraphicsConfig, SurfaceManager.ProxiedGraphicsConfig +{ OGLContext getContext(); long getNativeConfigInfo(); boolean isCapPresent(int cap); diff --git a/src/share/classes/sun/java2d/opengl/OGLPaints.java b/src/share/classes/sun/java2d/opengl/OGLPaints.java index 4dc828e99..472063482 100644 --- a/src/share/classes/sun/java2d/opengl/OGLPaints.java +++ b/src/share/classes/sun/java2d/opengl/OGLPaints.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2008 Sun Microsystems, Inc. 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 @@ -39,6 +39,7 @@ import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; import sun.java2d.loops.CompositeType; import static sun.java2d.pipe.BufferedPaints.*; +import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; abstract class OGLPaints { @@ -170,7 +171,7 @@ abstract class OGLPaints { OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; OGLGraphicsConfig gc = dstData.getOGLGraphicsConfig(); - if (!gc.isCapPresent(OGLContext.CAPS_EXT_GRAD_SHADER)) { + if (!gc.isCapPresent(CAPS_EXT_GRAD_SHADER)) { return false; } diff --git a/src/share/classes/sun/java2d/opengl/OGLRenderer.java b/src/share/classes/sun/java2d/opengl/OGLRenderer.java index a3afd13e3..9df727327 100644 --- a/src/share/classes/sun/java2d/opengl/OGLRenderer.java +++ b/src/share/classes/sun/java2d/opengl/OGLRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems Microsystems, Inc. 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 @@ -30,6 +30,7 @@ import java.awt.geom.Path2D; import sun.java2d.SunGraphics2D; import sun.java2d.loops.GraphicsPrimitive; import sun.java2d.pipe.BufferedRenderPipe; +import sun.java2d.pipe.ParallelogramPipe; import sun.java2d.pipe.RenderQueue; import sun.java2d.pipe.SpanIterator; import static sun.java2d.pipe.BufferedOpCodes.*; @@ -51,6 +52,15 @@ class OGLRenderer extends BufferedRenderPipe { null, sg2d.paint, sg2d, ctxflags); } + @Override + protected void validateContextAA(SunGraphics2D sg2d) { + int ctxflags = OGLContext.NO_CONTEXT_FLAGS; + OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; + OGLContext.validateContext(dstData, dstData, + sg2d.getCompClip(), sg2d.composite, + null, sg2d.paint, sg2d, ctxflags); + } + void copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) { @@ -88,6 +98,31 @@ class OGLRenderer extends BufferedRenderPipe { super(oglr.rq); this.oglr = oglr; } + public ParallelogramPipe getAAParallelogramPipe() { + final ParallelogramPipe realpipe = oglr.getAAParallelogramPipe(); + return new ParallelogramPipe() { + public void fillParallelogram(SunGraphics2D sg2d, + double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + GraphicsPrimitive.tracePrimitive("OGLFillAAParallelogram"); + realpipe.fillParallelogram(sg2d, + x, y, dx1, dy1, dx2, dy2); + } + public void drawParallelogram(SunGraphics2D sg2d, + double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2) + { + GraphicsPrimitive.tracePrimitive("OGLDrawAAParallelogram"); + realpipe.drawParallelogram(sg2d, + x, y, dx1, dy1, dx2, dy2, + lw1, lw2); + } + }; + } protected void validateContext(SunGraphics2D sg2d) { oglr.validateContext(sg2d); } @@ -130,6 +165,23 @@ class OGLRenderer extends BufferedRenderPipe { GraphicsPrimitive.tracePrimitive("OGLFillSpans"); oglr.fillSpans(sg2d, si, transx, transy); } + public void fillParallelogram(SunGraphics2D sg2d, + double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + GraphicsPrimitive.tracePrimitive("OGLFillParallelogram"); + oglr.fillParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2); + } + public void drawParallelogram(SunGraphics2D sg2d, + double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2) + { + GraphicsPrimitive.tracePrimitive("OGLDrawParallelogram"); + oglr.drawParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2, lw1, lw2); + } public void copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) { diff --git a/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java b/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java index a47918700..3b721082a 100644 --- a/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java +++ b/src/share/classes/sun/java2d/opengl/OGLSurfaceData.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2008 Sun Microsystems Microsystems, Inc. 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 @@ -27,23 +27,26 @@ package sun.java2d.opengl; import java.awt.AlphaComposite; import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; import java.awt.Transparency; import java.awt.image.ColorModel; import java.awt.image.Raster; import sun.awt.SunHints; import sun.awt.image.PixelConverter; +import sun.java2d.pipe.hw.AccelSurface; import sun.java2d.SunGraphics2D; import sun.java2d.SurfaceData; import sun.java2d.SurfaceDataProxy; +import sun.java2d.loops.CompositeType; import sun.java2d.loops.GraphicsPrimitive; import sun.java2d.loops.MaskFill; import sun.java2d.loops.SurfaceType; -import sun.java2d.pipe.PixelToShapeConverter; +import sun.java2d.pipe.ParallelogramPipe; +import sun.java2d.pipe.PixelToParallelogramConverter; import sun.java2d.pipe.RenderBuffer; -import sun.java2d.pipe.RenderQueue; import sun.java2d.pipe.TextPipe; import static sun.java2d.pipe.BufferedOpCodes.*; -import static sun.java2d.opengl.OGLContext.*; +import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; /** * This class describes an OpenGL "surface", that is, a region of pixels @@ -92,17 +95,16 @@ import static sun.java2d.opengl.OGLContext.*; * FLIP_BACKBUFFER OpenGLSurface * FBOBJECT OpenGLSurfaceRTT */ -public abstract class OGLSurfaceData extends SurfaceData { +public abstract class OGLSurfaceData extends SurfaceData + implements AccelSurface { /** * OGL-specific surface types + * + * @see sun.java2d.pipe.hw.AccelSurface */ - public static final int UNDEFINED = 0; - public static final int WINDOW = 1; - public static final int PBUFFER = 2; - public static final int TEXTURE = 3; - public static final int FLIP_BACKBUFFER = 4; - public static final int FBOBJECT = 5; + public static final int PBUFFER = RT_PLAIN; + public static final int FBOBJECT = RT_TEXTURE; /** * Pixel formats @@ -148,11 +150,14 @@ public abstract class OGLSurfaceData extends SurfaceData { private static boolean isGradShaderEnabled; private OGLGraphicsConfig graphicsConfig; - private int textureTarget; protected int type; + // these fields are set from the native code when the surface is + // initialized + private int nativeWidth, nativeHeight; protected static OGLRenderer oglRenderPipe; - protected static PixelToShapeConverter oglTxRenderPipe; + protected static PixelToParallelogramConverter oglTxRenderPipe; + protected static ParallelogramPipe oglAAPgramPipe; protected static OGLTextRenderer oglTextPipe; protected static OGLDrawImage oglImagePipe; @@ -170,6 +175,7 @@ public abstract class OGLSurfaceData extends SurfaceData { int width, int height); private native int getTextureTarget(long pData); + private native int getTextureID(long pData); static { if (!GraphicsEnvironment.isHeadless()) { @@ -203,9 +209,14 @@ public abstract class OGLSurfaceData extends SurfaceData { oglRenderPipe = new OGLRenderer(rq); if (GraphicsPrimitive.tracingEnabled()) { oglTextPipe = oglTextPipe.traceWrap(); - oglRenderPipe = oglRenderPipe.traceWrap(); + //The wrapped oglRenderPipe will wrap the AA pipe as well... + //oglAAPgramPipe = oglRenderPipe.traceWrap(); } - oglTxRenderPipe = new PixelToShapeConverter(oglRenderPipe); + oglAAPgramPipe = oglRenderPipe.getAAParallelogramPipe(); + oglTxRenderPipe = + new PixelToParallelogramConverter(oglRenderPipe, + oglRenderPipe, + 1.0, 0.25, true); OGLBlitLoops.register(); OGLMaskFill.register(); @@ -282,9 +293,7 @@ public abstract class OGLSurfaceData extends SurfaceData { break; } - if (success) { - textureTarget = getTextureTarget(getNativeOps()); - } else { + if (!success) { throw new OutOfMemoryError("can't create offscreen surface"); } } @@ -323,7 +332,7 @@ public abstract class OGLSurfaceData extends SurfaceData { * Returns the OGLContext for the GraphicsConfig associated with this * surface. */ - final OGLContext getContext() { + public final OGLContext getContext() { return graphicsConfig.getContext(); } @@ -337,7 +346,7 @@ public abstract class OGLSurfaceData extends SurfaceData { /** * Returns one of the surface type constants defined above. */ - final int getType() { + public final int getType() { return type; } @@ -346,8 +355,41 @@ public abstract class OGLSurfaceData extends SurfaceData { * for that texture (either GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB). * Otherwise, this method will return zero. */ - final int getTextureTarget() { - return textureTarget; + public final int getTextureTarget() { + return getTextureTarget(getNativeOps()); + } + + /** + * If this surface is backed by a texture object, returns the texture ID + * for that texture. + * Otherwise, this method will return zero. + */ + public final int getTextureID() { + return getTextureID(getNativeOps()); + } + + /** + * Returns native resource of specified {@code resType} associated with + * this surface. + * + * Specifically, for {@code OGLSurfaceData} this method returns the + * the following: + * <pre> + * TEXTURE - texture id + * </pre> + * + * Note: the resource returned by this method is only valid on the rendering + * thread. + * + * @return native resource of specified type or 0L if + * such resource doesn't exist or can not be retrieved. + * @see sun.java2d.pipe.hw.AccelSurface#getNativeResource + */ + public long getNativeResource(int resType) { + if (resType == TEXTURE) { + return getTextureID(); + } + return 0L; } public Raster getRaster(int x, int y, int w, int h) { @@ -366,7 +408,7 @@ public abstract class OGLSurfaceData extends SurfaceData { */ public boolean canRenderLCDText(SunGraphics2D sg2d) { return - graphicsConfig.isCapPresent(OGLContext.CAPS_EXT_LCD_SHADER) && + graphicsConfig.isCapPresent(CAPS_EXT_LCD_SHADER) && sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY && sg2d.paintState <= SunGraphics2D.PAINT_OPAQUECOLOR; } @@ -405,7 +447,7 @@ public abstract class OGLSurfaceData extends SurfaceData { validated = true; } - PixelToShapeConverter txPipe = null; + PixelToParallelogramConverter txPipe = null; OGLRenderer nonTxPipe = null; if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) { @@ -422,12 +464,28 @@ public abstract class OGLSurfaceData extends SurfaceData { // custom paints handled by super.validatePipe() below } } else { - if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR && - sg2d.compositeState == sg2d.COMP_XOR) - { - // install the solid pipes when AA and XOR are both enabled - txPipe = oglTxRenderPipe; - nonTxPipe = oglRenderPipe; + if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) { + if (graphicsConfig.isCapPresent(CAPS_PS30) && + (sg2d.imageComp == CompositeType.SrcOverNoEa || + sg2d.imageComp == CompositeType.SrcOver)) + { + if (!validated) { + super.validatePipe(sg2d); + validated = true; + } + PixelToParallelogramConverter aaConverter = + new PixelToParallelogramConverter(sg2d.shapepipe, + oglAAPgramPipe, + 1.0/8.0, 0.499, + false); + sg2d.drawpipe = aaConverter; + sg2d.fillpipe = aaConverter; + sg2d.shapepipe = aaConverter; + } else if (sg2d.compositeState == sg2d.COMP_XOR) { + // install the solid pipes when AA and XOR are both enabled + txPipe = oglTxRenderPipe; + nonTxPipe = oglRenderPipe; + } } // other cases handled by super.validatePipe() below } @@ -443,7 +501,11 @@ public abstract class OGLSurfaceData extends SurfaceData { sg2d.drawpipe = nonTxPipe; sg2d.fillpipe = nonTxPipe; } - sg2d.shapepipe = nonTxPipe; + // Note that we use the transforming pipe here because it + // will examine the shape and possibly perform an optimized + // operation if it can be simplified. The simplifications + // will be valid for all STROKE and TRANSFORM types. + sg2d.shapepipe = txPipe; } else { if (!validated) { super.validatePipe(sg2d); @@ -472,7 +534,7 @@ public abstract class OGLSurfaceData extends SurfaceData { * validation code will choose a more general software-based loop. */ if (!OGLPaints.isValid(sg2d) || - !graphicsConfig.isCapPresent(CAPS_EXT_MULTITEXTURE)) + !graphicsConfig.isCapPresent(CAPS_MULTITEXTURE)) { return null; } @@ -564,7 +626,7 @@ public abstract class OGLSurfaceData extends SurfaceData { * when using the basic GL_TEXTURE_2D target. */ boolean isTexNonPow2Available() { - return graphicsConfig.isCapPresent(OGLContext.CAPS_EXT_TEXNONPOW2); + return graphicsConfig.isCapPresent(CAPS_TEXNONPOW2); } /** @@ -573,6 +635,16 @@ public abstract class OGLSurfaceData extends SurfaceData { * GL_ARB_texture_rectangle extension is present). */ boolean isTexRectAvailable() { - return graphicsConfig.isCapPresent(OGLContext.CAPS_EXT_TEXRECT); + return graphicsConfig.isCapPresent(CAPS_EXT_TEXRECT); + } + + public Rectangle getNativeBounds() { + OGLRenderQueue rq = OGLRenderQueue.getInstance(); + rq.lock(); + try { + return new Rectangle(nativeWidth, nativeHeight); + } finally { + rq.unlock(); + } } } diff --git a/src/share/classes/sun/java2d/pipe/BufferedContext.java b/src/share/classes/sun/java2d/pipe/BufferedContext.java index d14b4277d..059895230 100644 --- a/src/share/classes/sun/java2d/pipe/BufferedContext.java +++ b/src/share/classes/sun/java2d/pipe/BufferedContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems, Inc. 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 @@ -26,12 +26,13 @@ package sun.java2d.pipe; import java.awt.AlphaComposite; +import java.awt.Color; import java.awt.Composite; import java.awt.Paint; import java.awt.geom.AffineTransform; +import sun.java2d.pipe.hw.AccelSurface; import sun.java2d.InvalidPipeException; import sun.java2d.SunGraphics2D; -import sun.java2d.SurfaceData; import sun.java2d.loops.XORComposite; import static sun.java2d.pipe.BufferedOpCodes.*; import static sun.java2d.pipe.BufferedRenderPipe.BYTES_PER_SPAN; @@ -43,8 +44,10 @@ import static sun.java2d.pipe.BufferedRenderPipe.BYTES_PER_SPAN; * single thread. Note that the RenderQueue lock must be acquired before * calling the validate() method (or any other method in this class). See * the RenderQueue class comments for a sample usage scenario. + * + * @see RenderQueue */ -public class BufferedContext { +public abstract class BufferedContext { /* * The following flags help the internals of validate() determine @@ -82,13 +85,17 @@ public class BufferedContext { */ protected static BufferedContext currentContext; - private SurfaceData validatedSrcData; - private SurfaceData validatedDstData; + private AccelSurface validatedSrcData; + private AccelSurface validatedDstData; private Region validatedClip; private Composite validatedComp; private Paint validatedPaint; + private boolean isValidatedPaintAColor; + private int validatedRGB; private int validatedFlags; private boolean xformInUse; + private int transX; + private int transY; protected BufferedContext(RenderQueue rq) { this.rq = rq; @@ -96,6 +103,49 @@ public class BufferedContext { } /** + * Fetches the BufferedContextContext associated with the dst. surface + * and validates the context using the given parameters. Most rendering + * operations will call this method first in order to set the necessary + * state before issuing rendering commands. + * + * Note: must be called while the RenderQueue lock is held. + * + * @throws InvalidPipeException if either src or dest surface is not valid + * or lost + * @see RenderQueue#lock + * @see RenderQueue#unlock + */ + public static void validateContext(AccelSurface srcData, + AccelSurface dstData, + Region clip, Composite comp, + AffineTransform xform, + Paint paint, SunGraphics2D sg2d, + int flags) + { + // assert rq.lock.isHeldByCurrentThread(); + BufferedContext d3dc = dstData.getContext(); + d3dc.validate(srcData, dstData, + clip, comp, xform, paint, sg2d, flags); + } + + /** + * Fetches the BufferedContextassociated with the surface + * and disables all context state settings. + * + * Note: must be called while the RenderQueue lock is held. + * + * @throws InvalidPipeException if the surface is not valid + * or lost + * @see RenderQueue#lock + * @see RenderQueue#unlock + */ + public static void validateContext(AccelSurface surface) { + // assert rt.lock.isHeldByCurrentThread(); + validateContext(surface, surface, + null, null, null, null, null, NO_CONTEXT_FLAGS); + } + + /** * Validates the given parameters against the current state for this * context. If this context is not current, it will be made current * for the given source and destination surfaces, and the viewport will @@ -106,19 +156,47 @@ public class BufferedContext { * Note that the SunGraphics2D parameter is only used for the purposes * of validating a (non-null) Paint parameter. In all other cases it * is safe to pass a null SunGraphics2D and it will be ignored. + * + * Note: must be called while the RenderQueue lock is held. + * + * @throws InvalidPipeException if either src or dest surface is not valid + * or lost */ - public void validate(SurfaceData srcData, SurfaceData dstData, + public void validate(AccelSurface srcData, AccelSurface dstData, Region clip, Composite comp, AffineTransform xform, Paint paint, SunGraphics2D sg2d, int flags) { // assert rq.lock.isHeldByCurrentThread(); - boolean updateClip = (clip != validatedClip); - boolean updatePaint = (paint != validatedPaint); + boolean updateClip = false; + boolean updatePaint = false; - if (!dstData.isValid()) { - throw new InvalidPipeException("bounds changed"); + if (!dstData.isValid() || + dstData.isSurfaceLost() || srcData.isSurfaceLost()) + { + invalidateContext(); + throw new InvalidPipeException("bounds changed or surface lost"); + } + + if (paint instanceof Color) { + // REMIND: not 30-bit friendly + int newRGB = ((Color)paint).getRGB(); + if (isValidatedPaintAColor) { + if (newRGB != validatedRGB) { + validatedRGB = newRGB; + updatePaint = true; + } + } else { + validatedRGB = newRGB; + updatePaint = true; + isValidatedPaintAColor = true; + } + } else if (validatedPaint != paint) { + updatePaint = true; + // this should be set when we are switching from paint to color + // in which case this condition will be true + isValidatedPaintAColor = false; } if ((currentContext != this) || @@ -147,9 +225,18 @@ public class BufferedContext { } // validate clip - if (updateClip) { + if ((clip != validatedClip) || updateClip) { if (clip != null) { - setClip(clip); + if (updateClip || + validatedClip == null || + !(validatedClip.isRectangular() && clip.isRectangular()) || + ((clip.getLoX() != validatedClip.getLoX() || + clip.getLoY() != validatedClip.getLoY() || + clip.getHiX() != validatedClip.getHiX() || + clip.getHiY() != validatedClip.getHiY()))) + { + setClip(clip); + } } else { resetClip(); } @@ -173,14 +260,29 @@ public class BufferedContext { } // validate transform + boolean txChanged = false; if (xform == null) { if (xformInUse) { resetTransform(); xformInUse = false; + txChanged = true; + } else if (sg2d != null) { + if (transX != sg2d.transX || transY != sg2d.transY) { + txChanged = true; + } + } + if (sg2d != null) { + transX = sg2d.transX; + transY = sg2d.transY; } } else { setTransform(xform); xformInUse = true; + txChanged = true; + } + // non-Color paints may require paint revalidation + if (!isValidatedPaintAColor && txChanged) { + updatePaint = true; } // validate paint @@ -194,6 +296,7 @@ public class BufferedContext { } // mark dstData dirty + // REMIND: is this really needed now? we do it in SunGraphics2D.. dstData.markDirty(); } @@ -201,13 +304,20 @@ public class BufferedContext { * Invalidates the surfaces associated with this context. This is * useful when the context is no longer needed, and we want to break * the chain caused by these surface references. + * + * Note: must be called while the RenderQueue lock is held. + * + * @see RenderQueue#lock + * @see RenderQueue#unlock */ public void invalidateSurfaces() { validatedSrcData = null; validatedDstData = null; } - private void setSurfaces(SurfaceData srcData, SurfaceData dstData) { + private void setSurfaces(AccelSurface srcData, + AccelSurface dstData) + { // assert rq.lock.isHeldByCurrentThread(); rq.ensureCapacityAndAlignment(20, 4); buf.putInt(SET_SURFACES); @@ -304,4 +414,54 @@ public class BufferedContext { buf.putDouble(xform.getTranslateX()); buf.putDouble(xform.getTranslateY()); } + + /** + * Resets this context's surfaces and all attributes. + * + * Note: must be called while the RenderQueue lock is held. + * + * @see RenderQueue#lock + * @see RenderQueue#unlock + */ + public void invalidateContext() { + resetTransform(); + resetComposite(); + resetClip(); + invalidateSurfaces(); + validatedComp = null; + validatedClip = null; + validatedPaint = null; + xformInUse = false; + } + + /** + * Returns a singleton {@code RenderQueue} object used by the rendering + * pipeline. + * + * @return a render queue + * @see RenderQueue + */ + public abstract RenderQueue getRenderQueue(); + + /** + * Saves the the state of this context. + * It may reset the current context. + * + * Note: must be called while the RenderQueue lock is held. + * + * @see RenderQueue#lock + * @see RenderQueue#unlock + */ + public abstract void saveState(); + + /** + * Restores the native state of this context. + * It may reset the current context. + * + * Note: must be called while the RenderQueue lock is held. + * + * @see RenderQueue#lock + * @see RenderQueue#unlock + */ + public abstract void restoreState(); } diff --git a/src/share/classes/sun/java2d/pipe/BufferedOpCodes.java b/src/share/classes/sun/java2d/pipe/BufferedOpCodes.java index 0523d27bd..450ea4a27 100644 --- a/src/share/classes/sun/java2d/pipe/BufferedOpCodes.java +++ b/src/share/classes/sun/java2d/pipe/BufferedOpCodes.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems Microsystems, Inc. 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 @@ -32,10 +32,14 @@ public class BufferedOpCodes { public static final int DRAW_POLY = 12; public static final int DRAW_PIXEL = 13; public static final int DRAW_SCANLINES = 14; + public static final int DRAW_PARALLELOGRAM = 15; + public static final int DRAW_AAPARALLELOGRAM = 16; // fill ops public static final int FILL_RECT = 20; public static final int FILL_SPANS = 21; + public static final int FILL_PARALLELOGRAM = 22; + public static final int FILL_AAPARALLELOGRAM = 23; // copy-related ops public static final int COPY_AREA = 30; @@ -67,6 +71,9 @@ public class BufferedOpCodes { public static final int DISPOSE_CONFIG = 74; public static final int INVALIDATE_CONTEXT = 75; public static final int SYNC = 76; + public static final int RESTORE_DEVICES = 77; + public static final int SAVE_STATE = 78; + public static final int RESTORE_STATE = 79; // multibuffering ops public static final int SWAP_BUFFERS = 80; diff --git a/src/share/classes/sun/java2d/pipe/BufferedRenderPipe.java b/src/share/classes/sun/java2d/pipe/BufferedRenderPipe.java index 71feb4b9b..e9f418a96 100644 --- a/src/share/classes/sun/java2d/pipe/BufferedRenderPipe.java +++ b/src/share/classes/sun/java2d/pipe/BufferedRenderPipe.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2008 Sun Microsystems Microsystems, Inc. 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 @@ -25,6 +25,7 @@ package sun.java2d.pipe; +import java.awt.BasicStroke; import java.awt.Polygon; import java.awt.Shape; import java.awt.geom.AffineTransform; @@ -33,6 +34,7 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.Path2D; import java.awt.geom.IllegalPathStateException; import java.awt.geom.PathIterator; +import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import sun.java2d.SunGraphics2D; import sun.java2d.loops.ProcessPath; @@ -51,8 +53,10 @@ import static sun.java2d.pipe.BufferedOpCodes.*; * simply delegate to draw(Shape) and fill(Shape), respectively. */ public abstract class BufferedRenderPipe - implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe + implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe, ParallelogramPipe { + ParallelogramPipe aapgrampipe = new AAParallelogramPipe(); + static final int BYTES_PER_POLY_POINT = 8; static final int BYTES_PER_SCANLINE = 12; static final int BYTES_PER_SPAN = 16; @@ -67,12 +71,17 @@ public abstract class BufferedRenderPipe this.drawHandler = new BufferedDrawHandler(); } + public ParallelogramPipe getAAParallelogramPipe() { + return aapgrampipe; + } + /** * Validates the state in the provided SunGraphics2D object and sets up * any special resources for this operation (e.g. enabling gradient * shading). */ protected abstract void validateContext(SunGraphics2D sg2d); + protected abstract void validateContextAA(SunGraphics2D sg2d); public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) @@ -398,6 +407,98 @@ public abstract class BufferedRenderPipe } } + public void fillParallelogram(SunGraphics2D sg2d, + double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + rq.lock(); + try { + validateContext(sg2d); + rq.ensureCapacity(28); + buf.putInt(FILL_PARALLELOGRAM); + buf.putFloat((float) x); + buf.putFloat((float) y); + buf.putFloat((float) dx1); + buf.putFloat((float) dy1); + buf.putFloat((float) dx2); + buf.putFloat((float) dy2); + } finally { + rq.unlock(); + } + } + + public void drawParallelogram(SunGraphics2D sg2d, + double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2) + { + rq.lock(); + try { + validateContext(sg2d); + rq.ensureCapacity(36); + buf.putInt(DRAW_PARALLELOGRAM); + buf.putFloat((float) x); + buf.putFloat((float) y); + buf.putFloat((float) dx1); + buf.putFloat((float) dy1); + buf.putFloat((float) dx2); + buf.putFloat((float) dy2); + buf.putFloat((float) lw1); + buf.putFloat((float) lw2); + } finally { + rq.unlock(); + } + } + + private class AAParallelogramPipe implements ParallelogramPipe { + public void fillParallelogram(SunGraphics2D sg2d, + double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + rq.lock(); + try { + validateContextAA(sg2d); + rq.ensureCapacity(28); + buf.putInt(FILL_AAPARALLELOGRAM); + buf.putFloat((float) x); + buf.putFloat((float) y); + buf.putFloat((float) dx1); + buf.putFloat((float) dy1); + buf.putFloat((float) dx2); + buf.putFloat((float) dy2); + } finally { + rq.unlock(); + } + } + + public void drawParallelogram(SunGraphics2D sg2d, + double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2) + { + rq.lock(); + try { + validateContextAA(sg2d); + rq.ensureCapacity(36); + buf.putInt(DRAW_AAPARALLELOGRAM); + buf.putFloat((float) x); + buf.putFloat((float) y); + buf.putFloat((float) dx1); + buf.putFloat((float) dy1); + buf.putFloat((float) dx2); + buf.putFloat((float) dy2); + buf.putFloat((float) lw1); + buf.putFloat((float) lw2); + } finally { + rq.unlock(); + } + } + } + public void draw(SunGraphics2D sg2d, Shape s) { if (sg2d.strokeState == sg2d.STROKE_THIN) { if (s instanceof Polygon) { diff --git a/src/share/classes/sun/java2d/pipe/DrawImage.java b/src/share/classes/sun/java2d/pipe/DrawImage.java index 21397906d..15ade8dd3 100644 --- a/src/share/classes/sun/java2d/pipe/DrawImage.java +++ b/src/share/classes/sun/java2d/pipe/DrawImage.java @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2001-2008 Sun Microsystems Microsystems, Inc. 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 @@ -955,7 +955,7 @@ public class DrawImage implements DrawImagePipe } else { BlitBg blit = BlitBg.getFromCache(srcType, comp, dstType); blit.BlitBg(srcData, dstData, sg.composite, clipRegion, - bgColor, sx, sy, dx, dy, w, h); + bgColor.getRGB(), sx, sy, dx, dy, w, h); } } diff --git a/src/share/classes/sun/java2d/pipe/ParallelogramPipe.java b/src/share/classes/sun/java2d/pipe/ParallelogramPipe.java new file mode 100644 index 000000000..33278dd90 --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/ParallelogramPipe.java @@ -0,0 +1,66 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe; + +import sun.java2d.SunGraphics2D; + +/** + * This interface defines the set of calls that pipeline objects + * can use to pass on responsibility for drawing arbitrary + * parallelogram shapes. + * Six floating point numbers are provided and the parallelogram + * is defined as the quadrilateral with the following vertices: + * <pre> + * origin: (x, y) + * => (x+dx1, y+dy1) + * => (x+dx1+dx2, y+dy1+dy2) + * => (x+dx2, y+dy2) + * => origin + * </pre> + */ +public interface ParallelogramPipe { + public void fillParallelogram(SunGraphics2D sg, + double x, double y, + double dx1, double dy1, + double dx2, double dy2); + + /** + * Draw a Parallelogram with the indicated line widths + * assuming a standard BasicStroke with MITER joins. + * lw1 specifies the width of the stroke along the dx1,dy1 + * vector and lw2 specifies the width of the stroke along + * the dx2,dy2 vector. + * This is equivalent to outsetting the indicated + * parallelogram by lw/2 pixels, then insetting the + * same parallelogram by lw/2 pixels and filling the + * difference between the outer and inner parallelograms. + */ + public void drawParallelogram(SunGraphics2D sg, + double x, double y, + double dx1, double dy1, + double dx2, double dy2, + double lw1, double lw2); +} diff --git a/src/share/classes/sun/java2d/pipe/PixelToParallelogramConverter.java b/src/share/classes/sun/java2d/pipe/PixelToParallelogramConverter.java new file mode 100644 index 000000000..dcbebb2fb --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/PixelToParallelogramConverter.java @@ -0,0 +1,417 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe; + +import java.awt.Shape; +import java.awt.BasicStroke; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.AffineTransform; +import sun.java2d.SunGraphics2D; +import sun.awt.SunHints; + +/** + * This class converts calls to the basic pixel rendering methods + * into calls to the methods on a ParallelogramPipe. + * Most calls are transformed into calls to the fill(Shape) method + * by the parent PixelToShapeConverter class, but some calls are + * transformed into calls to fill/drawParallelogram(). + */ +public class PixelToParallelogramConverter extends PixelToShapeConverter + implements ShapeDrawPipe +{ + ParallelogramPipe outrenderer; + double minPenSize; + double normPosition; + double normRoundingBias; + boolean adjustfill; + + /** + * @param shapepipe pipeline to forward shape calls to + * @param pgrampipe pipeline to forward parallelogram calls to + * (and drawLine calls if possible) + * @param minPenSize minimum pen size for dropout control + * @param normPosition sub-pixel location to normalize endpoints + * for STROKE_NORMALIZE cases + * @param adjustFill boolean to control whethere normalization + * constants are also applied to fill operations + * (normally true for non-AA, false for AA) + */ + public PixelToParallelogramConverter(ShapeDrawPipe shapepipe, + ParallelogramPipe pgrampipe, + double minPenSize, + double normPosition, + boolean adjustfill) + { + super(shapepipe); + outrenderer = pgrampipe; + this.minPenSize = minPenSize; + this.normPosition = normPosition; + this.normRoundingBias = 0.5 - normPosition; + this.adjustfill = adjustfill; + } + + public void drawLine(SunGraphics2D sg2d, + int x1, int y1, int x2, int y2) + { + if (!drawGeneralLine(sg2d, x1, y1, x2, y2)) { + super.drawLine(sg2d, x1, y1, x2, y2); + } + } + + public void drawRect(SunGraphics2D sg2d, + int x, int y, int w, int h) + { + if (w >= 0 && h >= 0) { + if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) { + BasicStroke bs = ((BasicStroke) sg2d.stroke); + if (w > 0 && h > 0) { + if (bs.getLineJoin() == BasicStroke.JOIN_MITER && + bs.getDashArray() == null) + { + double lw = bs.getLineWidth(); + drawRectangle(sg2d, x, y, w, h, lw); + return; + } + } else { + // Note: This calls the integer version which + // will verify that the local drawLine optimizations + // work and call super.drawLine(), if not. + drawLine(sg2d, x, y, x+w, y+h); + return; + } + } + super.drawRect(sg2d, x, y, w, h); + } + } + + public void fillRect(SunGraphics2D sg2d, + int x, int y, int w, int h) + { + if (w > 0 && h > 0) { + fillRectangle(sg2d, x, y, w, h); + } + } + + public void draw(SunGraphics2D sg2d, Shape s) { + if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) { + BasicStroke bs = ((BasicStroke) sg2d.stroke); + if (s instanceof Rectangle2D) { + if (bs.getLineJoin() == BasicStroke.JOIN_MITER && + bs.getDashArray() == null) + { + Rectangle2D r2d = (Rectangle2D) s; + double w = r2d.getWidth(); + double h = r2d.getHeight(); + double x = r2d.getX(); + double y = r2d.getY(); + if (w >= 0 && h >= 0) { + double lw = bs.getLineWidth(); + drawRectangle(sg2d, x, y, w, h, lw); + } + return; + } + } else if (s instanceof Line2D) { + Line2D l2d = (Line2D) s; + if (drawGeneralLine(sg2d, + l2d.getX1(), l2d.getY1(), + l2d.getX2(), l2d.getY2())) + { + return; + } + } + } + + outpipe.draw(sg2d, s); + } + + public void fill(SunGraphics2D sg2d, Shape s) { + if (s instanceof Rectangle2D) { + Rectangle2D r2d = (Rectangle2D) s; + double w = r2d.getWidth(); + double h = r2d.getHeight(); + if (w > 0 && h > 0) { + double x = r2d.getX(); + double y = r2d.getY(); + fillRectangle(sg2d, x, y, w, h); + } + return; + } + + outpipe.fill(sg2d, s); + } + + static double len(double x, double y) { + return ((x == 0) ? Math.abs(y) + : ((y == 0) ? Math.abs(x) + : Math.sqrt(x * x + y * y))); + } + + double normalize(double v) { + return Math.floor(v + normRoundingBias) + normPosition; + } + + public boolean drawGeneralLine(SunGraphics2D sg2d, + double x1, double y1, + double x2, double y2) + { + if (sg2d.strokeState == SunGraphics2D.STROKE_CUSTOM || + sg2d.strokeState == SunGraphics2D.STROKE_THINDASHED) + { + return false; + } + BasicStroke bs = (BasicStroke) sg2d.stroke; + int cap = bs.getEndCap(); + if (cap == BasicStroke.CAP_ROUND || bs.getDashArray() != null) { + // TODO: we could construct the GeneralPath directly + // for CAP_ROUND and save a lot of processing in that case... + // And again, we would need to deal with dropout control... + return false; + } + double lw = bs.getLineWidth(); + // Save the original dx, dy in case we need it to transform + // the linewidth as a perpendicular vector below + double dx = x2 - x1; + double dy = y2 - y1; + switch (sg2d.transformState) { + case SunGraphics2D.TRANSFORM_GENERIC: + case SunGraphics2D.TRANSFORM_TRANSLATESCALE: + { + double coords[] = {x1, y1, x2, y2}; + sg2d.transform.transform(coords, 0, coords, 0, 2); + x1 = coords[0]; + y1 = coords[1]; + x2 = coords[2]; + y2 = coords[3]; + } + break; + case SunGraphics2D.TRANSFORM_ANY_TRANSLATE: + case SunGraphics2D.TRANSFORM_INT_TRANSLATE: + { + double tx = sg2d.transform.getTranslateX(); + double ty = sg2d.transform.getTranslateY(); + x1 += tx; + y1 += ty; + x2 += tx; + y2 += ty; + } + break; + case SunGraphics2D.TRANSFORM_ISIDENT: + break; + default: + throw new InternalError("unknown TRANSFORM state..."); + } + if (sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE) { + if (sg2d.strokeState == SunGraphics2D.STROKE_THIN && + outrenderer instanceof PixelDrawPipe) + { + // PixelDrawPipes will add sg2d.transXY so we need to factor + // that out... + int ix1 = (int) Math.floor(x1 - sg2d.transX); + int iy1 = (int) Math.floor(y1 - sg2d.transY); + int ix2 = (int) Math.floor(x2 - sg2d.transX); + int iy2 = (int) Math.floor(y2 - sg2d.transY); + ((PixelDrawPipe)outrenderer).drawLine(sg2d, ix1, iy1, ix2, iy2); + return true; + } + x1 = normalize(x1); + y1 = normalize(y1); + x2 = normalize(x2); + y2 = normalize(y2); + } + if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) { + // Transform the linewidth... + // calculate the scaling factor for a unit vector + // perpendicular to the original user space line. + double len = len(dx, dy); + if (len == 0) { + dx = len = 1; + // dy = 0; already + } + // delta transform the transposed (90 degree rotated) unit vector + double unitvector[] = {dy/len, -dx/len}; + sg2d.transform.deltaTransform(unitvector, 0, unitvector, 0, 1); + lw *= len(unitvector[0], unitvector[1]); + } + lw = Math.max(lw, minPenSize); + dx = x2 - x1; + dy = y2 - y1; + double len = len(dx, dy); + double udx, udy; + if (len == 0) { + if (cap == BasicStroke.CAP_BUTT) { + return true; + } + udx = lw; + udy = 0; + } else { + udx = lw * dx / len; + udy = lw * dy / len; + } + double px = x1 + udy / 2.0; + double py = y1 - udx / 2.0; + if (cap == BasicStroke.CAP_SQUARE) { + px -= udx / 2.0; + py -= udy / 2.0; + dx += udx; + dy += udy; + } + outrenderer.fillParallelogram(sg2d, px, py, -udy, udx, dx, dy); + return true; + } + + public void fillRectangle(SunGraphics2D sg2d, + double rx, double ry, + double rw, double rh) + { + double px, py; + double dx1, dy1, dx2, dy2; + AffineTransform txform = sg2d.transform; + dx1 = txform.getScaleX(); + dy1 = txform.getShearY(); + dx2 = txform.getShearX(); + dy2 = txform.getScaleY(); + px = rx * dx1 + ry * dx2 + txform.getTranslateX(); + py = rx * dy1 + ry * dy2 + txform.getTranslateY(); + dx1 *= rw; + dy1 *= rw; + dx2 *= rh; + dy2 *= rh; + if (adjustfill && + sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM && + sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE) + { + double newx = normalize(px); + double newy = normalize(py); + dx1 = normalize(px + dx1) - newx; + dy1 = normalize(py + dy1) - newy; + dx2 = normalize(px + dx2) - newx; + dy2 = normalize(py + dy2) - newy; + px = newx; + py = newy; + } + outrenderer.fillParallelogram(sg2d, px, py, dx1, dy1, dx2, dy2); + } + + public void drawRectangle(SunGraphics2D sg2d, + double rx, double ry, + double rw, double rh, + double lw) + { + double px, py; + double dx1, dy1, dx2, dy2; + double lw1, lw2; + AffineTransform txform = sg2d.transform; + dx1 = txform.getScaleX(); + dy1 = txform.getShearY(); + dx2 = txform.getShearX(); + dy2 = txform.getScaleY(); + px = rx * dx1 + ry * dx2 + txform.getTranslateX(); + py = rx * dy1 + ry * dy2 + txform.getTranslateY(); + // lw along dx1,dy1 scale by transformed length of dx2,dy2 vectors + // and vice versa + lw1 = len(dx1, dy1) * lw; + lw2 = len(dx2, dy2) * lw; + dx1 *= rw; + dy1 *= rw; + dx2 *= rh; + dy2 *= rh; + if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM && + sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE) + { + double newx = normalize(px); + double newy = normalize(py); + dx1 = normalize(px + dx1) - newx; + dy1 = normalize(py + dy1) - newy; + dx2 = normalize(px + dx2) - newx; + dy2 = normalize(py + dy2) - newy; + px = newx; + py = newy; + } + lw1 = Math.max(lw1, minPenSize); + lw2 = Math.max(lw2, minPenSize); + double len1 = len(dx1, dy1); + double len2 = len(dx2, dy2); + if (lw1 >= len1 || lw2 >= len2) { + // The line widths are large enough to consume the + // entire hole in the middle of the parallelogram + // so we can just fill the outer parallelogram. + fillOuterParallelogram(sg2d, + px, py, dx1, dy1, dx2, dy2, + len1, len2, lw1, lw2); + } else { + outrenderer.drawParallelogram(sg2d, + px, py, dx1, dy1, dx2, dy2, + lw1 / len1, lw2 / len2); + } + } + + /** + * This utility function handles the case where a drawRectangle + * operation discovered that the interior hole in the rectangle + * or parallelogram has been completely filled in by the stroke + * width. It calculates the outer parallelogram of the stroke + * and issues a single fillParallelogram request to fill it. + */ + public void fillOuterParallelogram(SunGraphics2D sg2d, + double px, double py, + double dx1, double dy1, + double dx2, double dy2, + double len1, double len2, + double lw1, double lw2) + { + double udx1 = dx1 / len1; + double udy1 = dy1 / len1; + double udx2 = dx2 / len2; + double udy2 = dy2 / len2; + if (len1 == 0) { + // len1 is 0, replace udxy1 with perpendicular of udxy2 + if (len2 == 0) { + // both are 0, use a unit Y vector for udxy2 + udx2 = 0; + udy2 = 1; + } + udx1 = udy2; + udy1 = -udx2; + } else if (len2 == 0) { + // len2 is 0, replace udxy2 with perpendicular of udxy1 + udx2 = udy1; + udy2 = -udx1; + } + udx1 *= lw1; + udy1 *= lw1; + udx2 *= lw2; + udy2 *= lw2; + px -= (udx1 + udx2) / 2; + py -= (udy1 + udy2) / 2; + dx1 += udx1; + dy1 += udy1; + dx2 += udx2; + dy2 += udy2; + + outrenderer.fillParallelogram(sg2d, px, py, dx1, dy1, dx2, dy2); + } +} diff --git a/src/share/classes/sun/java2d/pipe/hw/AccelDeviceEventListener.java b/src/share/classes/sun/java2d/pipe/hw/AccelDeviceEventListener.java new file mode 100644 index 000000000..a6cacbdee --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/hw/AccelDeviceEventListener.java @@ -0,0 +1,59 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe.hw; + +/** + * An interface for receiving notifications about imminent accelerated device's + * events. Upon receiving such event appropriate actions can be taken (for + * example, resources associated with the device can be freed). + */ +public interface AccelDeviceEventListener { + /** + * Called when the device is about to be reset. + * + * One must release all native resources associated with the device which + * prevent the device from being reset (such as Default Pool resources for + * the D3D pipeline). + * + * It is safe to remove the listener while in the call back. + * + * Note: this method is called on the rendering thread, + * do not call into user code, do not take RQ lock! + */ + public void onDeviceReset(); + + /** + * Called when the device is about to be disposed of. + * + * One must release all native resources associated with the device. + * + * It is safe to remove the listener while in the call back. + * + * Note: this method is called on the rendering thread, + * do not call into user code, do not take RQ lock! + */ + public void onDeviceDispose(); +} diff --git a/src/share/classes/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java b/src/share/classes/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java new file mode 100644 index 000000000..73a387a6c --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/hw/AccelDeviceEventNotifier.java @@ -0,0 +1,167 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe.hw; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * This class is used to notify listeners about accelerated device's + * events such as device reset or dispose that are about to occur. + */ +public class AccelDeviceEventNotifier { + + private static AccelDeviceEventNotifier theInstance; + + /** + * A device is about to be reset. The listeners have to release all + * resources associated with the device which are required for the device + * to be reset. + */ + public static final int DEVICE_RESET = 0; + + /** + * A device is about to be disposed. The listeners have to release all + * resources associated with the device. + */ + public static final int DEVICE_DISPOSED = 1; + + private final Map<AccelDeviceEventListener, Integer> listeners; + + private AccelDeviceEventNotifier() { + listeners = Collections.synchronizedMap( + new HashMap<AccelDeviceEventListener, Integer>(1)); + } + + /** + * Returns a singleton of AccelDeviceEventNotifier if it exists. If the + * passed boolean is false and singleton doesn't exist yet, null is + * returned. If the passed boolean is {@code true} and singleton doesn't + * exist it will be created and returned. + * + * @param create whether to create a singleton instance if doesn't yet + * exist + * @return a singleton instance or null + */ + private static synchronized + AccelDeviceEventNotifier getInstance(boolean create) + { + if (theInstance == null && create) { + theInstance = new AccelDeviceEventNotifier(); + } + return theInstance; + } + + /** + * Called to indicate that a device event had occured. + * If a singleton exists, the listeners (those associated with + * the device) will be notified. + * + * @param screen a screen number of the device which is a source of + * the event + * @param eventType a type of the event + * @see #DEVICE_DISPOSED + * @see #DEVICE_RESET + */ + public static final void eventOccured(int screen, int eventType) { + AccelDeviceEventNotifier notifier = getInstance(false); + if (notifier != null) { + notifier.notifyListeners(eventType, screen); + } + } + + /** + * Adds the listener associated with a device on particular screen. + * + * Note: the listener must be removed as otherwise it will forever + * be referenced by the notifier. + * + * @param l the listener + * @param screen the screen number indicating which device the listener is + * interested in. + */ + public static final void addListener(AccelDeviceEventListener l,int screen){ + getInstance(true).add(l, screen); + } + + /** + * Removes the listener. + * + * @param l the listener + */ + public static final void removeListener(AccelDeviceEventListener l) { + getInstance(true).remove(l); + } + + private final void add(AccelDeviceEventListener theListener, int screen) { + listeners.put(theListener, screen); + } + private final void remove(AccelDeviceEventListener theListener) { + listeners.remove(theListener); + } + + /** + * Notifies the listeners associated with the screen's device about the + * event. + * + * Implementation note: the current list of listeners is first duplicated + * which allows the listeners to remove themselves during the iteration. + * + * @param screen a screen number with which the device which is a source of + * the event is associated with + * @param eventType a type of the event + * @see #DEVICE_DISPOSED + * @see #DEVICE_RESET + */ + private final void notifyListeners(int deviceEventType, int screen) { + HashMap<AccelDeviceEventListener, Integer> listClone; + Set<AccelDeviceEventListener> cloneSet; + + synchronized(listeners) { + listClone = + new HashMap<AccelDeviceEventListener, Integer>(listeners); + } + + cloneSet = listClone.keySet(); + Iterator<AccelDeviceEventListener> itr = cloneSet.iterator(); + while (itr.hasNext()) { + AccelDeviceEventListener current = itr.next(); + Integer i = listClone.get(current); + // only notify listeners which are interested in this device + if (i != null && i.intValue() != screen) { + continue; + } + if (deviceEventType == DEVICE_RESET) { + current.onDeviceReset(); + } else if (deviceEventType == DEVICE_DISPOSED) { + current.onDeviceDispose(); + } + } + } +} diff --git a/src/share/classes/sun/java2d/pipe/hw/AccelGraphicsConfig.java b/src/share/classes/sun/java2d/pipe/hw/AccelGraphicsConfig.java new file mode 100644 index 000000000..ab799d947 --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/hw/AccelGraphicsConfig.java @@ -0,0 +1,95 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe.hw; + +import java.awt.image.VolatileImage; + +/** + * Implementors of this interface provida a way to create a + * {@code VolatileImage} whose destination surface is an + * {@link AccelSurface} of specified type. + * + * @see AccelSurface + */ +public interface AccelGraphicsConfig extends BufferedContextProvider { + /** + * Returns a VolatileImage with specified width, height, transparency + * and guaranteed accelerated surface type. If such image can not be created + * (out of vram error, specific surface type is not supported) null + * is returned. + * + * Note: if {@link AccelSurface#TEXTURE} type is requested, rendering + * to the image will be denied by throwing + * {@code UnsupportedOperationException } + * from {@link java.awt.image.VolatileImage#getGraphics} and + * {@link java.awt.image.VolatileImage#createGraphics} + * + * @param width the width of the returned {@code VolatileImage} + * @param height the height of the returned {@code VolatileImage} + * @param transparency the specified transparency mode + * @param type requested accelerated surface type as specified by constants + * in AccelSurface interface + * @return a {@code VolatileImage} backed up by requested accelerated + * surface type or null + * @throws IllegalArgumentException if the transparency is not a valid value + * @see AccelSurface#TEXTURE + * @see AccelSurface#RT_PLAIN + * @see AccelSurface#RT_TEXTURE + */ + public VolatileImage createCompatibleVolatileImage(int width, int height, + int transparency, + int type); + /** + * Returns object representing capabilities of the context associated + * with this {@code AccelGraphicsConfig}. + * + * @return ContextCapabilities object representing caps + * @see ContextCapabilities + */ + public ContextCapabilities getContextCapabilities(); + + /** + * Adds an {@code AccelDeviceEventListener} to listen to accelerated + * device's (which is associated with this {@code AccelGraphicsConfig}) + * events. + * + * Note: a hard link to the listener may be kept so it must be explicitly + * removed via {@link #removeDeviceEventListener()}. + * + * @param l the listener + * @see AccelDeviceEventListener + */ + public void addDeviceEventListener(AccelDeviceEventListener l); + + /** + * Removes an {@code AccelDeviceEventListener} from the list of listeners + * for this device's events. + * + * @param l the listener + * @see AccelDeviceEventListener + */ + public void removeDeviceEventListener(AccelDeviceEventListener l); +} diff --git a/src/share/classes/sun/java2d/pipe/hw/AccelSurface.java b/src/share/classes/sun/java2d/pipe/hw/AccelSurface.java new file mode 100644 index 000000000..c8692cb5e --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/hw/AccelSurface.java @@ -0,0 +1,136 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe.hw; + +import java.awt.Rectangle; +import sun.java2d.Surface; + +/** + * Abstraction for a hardware accelerated surface. + */ +public interface AccelSurface extends BufferedContextProvider, Surface { + /** + * Undefined + */ + public static final int UNDEFINED = 0; + /** + * Window (or window substitute) surface + */ + public static final int WINDOW = 1; + /** + * Render-To Plain surface (pbuffer for OpenGL, Render Target surface + * for Direct3D) + */ + public static final int RT_PLAIN = 2; + /** + * Texture surface + */ + public static final int TEXTURE = 3; + /** + * A back-buffer surface (SwapChain surface for Direct3D, backbuffer for + * OpenGL) + */ + public static final int FLIP_BACKBUFFER = 4; + /** + * Render-To Texture surface (fbobject for OpenGL, texture with render-to + * attribute for Direct3D) + */ + public static final int RT_TEXTURE = 5; + + /** + * Returns {@code int} representing surface's type as defined by constants + * in this interface. + * + * @return an integer representing this surface's type + * @see AccelSurface#UNDEFINED + * @see AccelSurface#WINDOW + * @see AccelSurface#RT_PLAIN + * @see AccelSurface#TEXTURE + * @see AccelSurface#FLIP_BACKBUFFER + * @see AccelSurface#RT_TEXTURE + */ + public int getType(); + + /** + * Returns a pointer to the native surface data associated with this + * surface. + * Note: this pointer is only valid on the rendering thread. + * + * @return pointer to the native surface's data + */ + public long getNativeOps(); + + /** + * Returns a pointer to the real native resource + * of the specified type associated with this AccelSurface. + * Note: this pointer is only valid on the rendering thread. + * + * @param resType the type of the requested resource + * @return a long containing a pointer to the native resource of the + * specified type or 0L if such resource doesn't exist for this surface + */ + public long getNativeResource(int resType); + + /** + * Marks this surface dirty. + */ + public void markDirty(); + + /** + * Returns whether the pipeline considers this surface valid. A surface + * may become invalid if it is disposed of, or resized. + * + * @return true if valid, false otherwise + */ + public boolean isValid(); + + /** + * Returns whether this surface is lost. The return value is only valid + * on the render thread, meaning that even if this method returns + * {@code true} it could be lost in the next moment unless it is called + * on the rendering thread. + * + * @return true if the surface is known to be lost, false otherwise + */ + public boolean isSurfaceLost(); + + /** + * Returns the requested bounds of the destination surface. The real bounds + * of the native accelerated surface may differ. Use + * {@link #getNativeBounds} to get the bounds of the native surface. + * + * @return Rectangle representing java surface's bounds + */ + public Rectangle getBounds(); + + /** + * Returns real bounds of the native surface, which may differ from those + * returned by {@link #getBounds}. + * + * @return Rectangle representing native surface's bounds + */ + public Rectangle getNativeBounds(); +} diff --git a/src/share/classes/sun/java2d/pipe/hw/AccelTypedVolatileImage.java b/src/share/classes/sun/java2d/pipe/hw/AccelTypedVolatileImage.java new file mode 100644 index 000000000..e855201d7 --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/hw/AccelTypedVolatileImage.java @@ -0,0 +1,74 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe.hw; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import sun.awt.image.SunVolatileImage; +import static sun.java2d.pipe.hw.AccelSurface.*; + +/** + * This is an image with forced type of the accelerated surface. + */ +public class AccelTypedVolatileImage extends SunVolatileImage { + + /** + * Creates a volatile image with specified type of accelerated surface. + * + * @param graphicsConfig a GraphicsConfiguration for which this image should + * be created. + * @param width width + * @param height width + * @param transparency type of {@link java.awt.Transparency transparency} + * requested for the image + * @param accType type of the desired accelerated surface as defined in + * AccelSurface interface + * @see sun.java2d.pipe.hw.AccelSurface + */ + public AccelTypedVolatileImage(GraphicsConfiguration graphicsConfig, + int width, int height, int transparency, + int accType) + { + super(null, graphicsConfig, width, height, null, transparency, + null, accType); + } + + /** + * {@inheritDoc} + * + * This method will throw {@code UnsupportedOperationException} if it this + * image's destination surface can not be rendered to. + */ + @Override + public Graphics2D createGraphics() { + if (getForcedAccelSurfaceType() == TEXTURE) { + throw new UnsupportedOperationException("Can't render " + + "to a non-RT Texture"); + } + return super.createGraphics(); + } +} diff --git a/src/share/classes/sun/java2d/pipe/hw/BufferedContextProvider.java b/src/share/classes/sun/java2d/pipe/hw/BufferedContextProvider.java new file mode 100644 index 000000000..86df94442 --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/hw/BufferedContextProvider.java @@ -0,0 +1,45 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe.hw; + +import sun.java2d.pipe.BufferedContext; + +/** + * Classes implementing this interface can provide the {@code BufferedContext} + * associated with or used by them. + * + * @see sun.java2d.pipe.BufferedContext + */ +public interface BufferedContextProvider { + /** + * Retrieves a context associated with object implementing this + * interface. + * + * @return associated context + * @see sun.java2d.pipe.BufferedContext + */ + public BufferedContext getContext(); +} diff --git a/src/share/classes/sun/java2d/pipe/hw/ContextCapabilities.java b/src/share/classes/sun/java2d/pipe/hw/ContextCapabilities.java new file mode 100644 index 000000000..5f17028b0 --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/hw/ContextCapabilities.java @@ -0,0 +1,128 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe.hw; + +/** + * Represents a set of capabilities of a BufferedContext and associated + * AccelGraphicsConfig. + * + * @see AccelGraphicsConfig + */ +public class ContextCapabilities { + /** Indicates that the context has no capabilities. */ + public static final int CAPS_EMPTY = (0 << 0); + /** Indicates that the context supports RT surfaces with alpha channel. */ + public static final int CAPS_RT_PLAIN_ALPHA = (1 << 1); + /** Indicates that the context supports RT textures with alpha channel. */ + public static final int CAPS_RT_TEXTURE_ALPHA = (1 << 2); + /** Indicates that the context supports opaque RT textures. */ + public static final int CAPS_RT_TEXTURE_OPAQUE = (1 << 3); + /** Indicates that the context supports multitexturing. */ + public static final int CAPS_MULTITEXTURE = (1 << 4); + /** Indicates that the context supports non-pow2 texture dimensions. */ + public static final int CAPS_TEXNONPOW2 = (1 << 5); + /** Indicates that the context supports non-square textures. */ + public static final int CAPS_TEXNONSQUARE = (1 << 6); + /** Indicates that the context supports pixel shader 2.0 or better. */ + public static final int CAPS_PS20 = (1 << 7); + /** Indicates that the context supports pixel shader 3.0 or better. */ + public static final int CAPS_PS30 = (1 << 8); + /* + * Pipeline contexts should use this for defining pipeline-specific + * capabilities, for example: + * int CAPS_D3D_1 = (FIRST_PRIVATE_CAP << 0); + * int CAPS_D3D_2 = (FIRST_PRIVATE_CAP << 1); + */ + protected static final int FIRST_PRIVATE_CAP = (1 << 16); + + protected final int caps; + protected final String adapterId; + + /** + * Constructs a {@code ContextCapabilities} object. + * @param caps an {@code int} representing the capabilities + * @param a {@code String} representing the name of the adapter, or null, + * in which case the adapterId will be set to "unknown adapter". + */ + protected ContextCapabilities(int caps, String adapterId) { + this.caps = caps; + this.adapterId = adapterId != null ? adapterId : "unknown adapter"; + } + + /** + * Returns a string representing the name of the graphics adapter if such + * could be determined. It is guaranteed to never return {@code null}. + * @return string representing adapter id + */ + public String getAdapterId() { + return adapterId; + } + + /** + * Returns an {@code int} with capabilities (OR-ed constants defined in + * this class and its pipeline-specific subclasses). + * @return capabilities as {@code int} + */ + public int getCaps() { + return caps; + } + + @Override + public String toString() { + StringBuffer buf = + new StringBuffer("ContextCapabilities: adapter=" + + adapterId+", caps="); + if (caps == CAPS_EMPTY) { + buf.append("CAPS_EMPTY"); + } else { + if ((caps & CAPS_RT_PLAIN_ALPHA) != 0) { + buf.append("CAPS_RT_PLAIN_ALPHA|"); + } + if ((caps & CAPS_RT_TEXTURE_ALPHA) != 0) { + buf.append("CAPS_RT_TEXTURE_ALPHA|"); + } + if ((caps & CAPS_RT_TEXTURE_OPAQUE) != 0) { + buf.append("CAPS_RT_TEXTURE_OPAQUE|"); + } + if ((caps & CAPS_MULTITEXTURE) != 0) { + buf.append("CAPS_MULTITEXTURE|"); + } + if ((caps & CAPS_TEXNONPOW2) != 0) { + buf.append("CAPS_TEXNONPOW2|"); + } + if ((caps & CAPS_TEXNONSQUARE) != 0) { + buf.append("CAPS_TEXNONSQUARE|"); + } + if ((caps & CAPS_PS20) != 0) { + buf.append("CAPS_PS20|"); + } + if ((caps & CAPS_PS30) != 0) { + buf.append("CAPS_PS30|"); + } + } + return buf.toString(); + } +} diff --git a/src/share/classes/sun/java2d/pipe/hw/ExtendedBufferCapabilities.java b/src/share/classes/sun/java2d/pipe/hw/ExtendedBufferCapabilities.java new file mode 100644 index 000000000..65eb305ab --- /dev/null +++ b/src/share/classes/sun/java2d/pipe/hw/ExtendedBufferCapabilities.java @@ -0,0 +1,154 @@ +/* + * Copyright 2007-2008 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe.hw; + +import java.awt.BufferCapabilities; +import java.awt.ImageCapabilities; + +/** + * Provides extended BufferStrategy capabilities, allowing to specify + * the type of vertical refresh synchronization for a buffer strategy. + * + * This BS capability is always page flipping because v-sync is only relevant + * to flipping buffer strategies. + * + * Note that asking for a v-synced BS doesn't necessarily guarantee that it will + * be v-synced since the vsync capability may be disabled in the driver, or + * there may be other restriction (like a number of v-synced buffer strategies + * allowed per vm). Because of this {@code createBufferStrategy} doesn't + * throw {@code AWTException} when a v-synced BS could not be created when + * requested. + * + * @see java.awt.Canvas#createBufferStrategy(int, BufferCapabilities) + * @see java.awt.Window#createBufferStrategy(int, BufferCapabilities) + */ +public class ExtendedBufferCapabilities extends BufferCapabilities { + + /** + * Type of synchronization on vertical retrace. + */ + public static enum VSyncType { + /** + * Use the default v-sync mode appropriate for given BufferStrategy + * and situation. + */ + VSYNC_DEFAULT(0), + + /** + * Synchronize flip on vertical retrace. + */ + VSYNC_ON(1), + + /** + * Do not synchronize flip on vertical retrace. + */ + VSYNC_OFF(2); + + /** + * Used to identify the v-sync type (independent of the constants + * order as opposed to {@code ordinal()}). + */ + public int id() { + return id; + } + + private VSyncType(int id) { + this.id = id; + } + private int id; + } + + private VSyncType vsync; + + /** + * Creates an ExtendedBufferCapabilities object with front/back/flip caps + * from the passed cap, and VSYNC_DEFAULT v-sync mode. + */ + public ExtendedBufferCapabilities(BufferCapabilities caps) { + super(caps.getFrontBufferCapabilities(), + caps.getBackBufferCapabilities(), + caps.getFlipContents()); + + this.vsync = VSyncType.VSYNC_DEFAULT; + } + + /** + * Creates an ExtendedBufferCapabilities instance with front/back/flip caps + * from the passed caps, and VSYNC_DEFAULT v-sync mode. + */ + public ExtendedBufferCapabilities(ImageCapabilities front, + ImageCapabilities back, FlipContents flip) + { + super(front, back, flip); + + this.vsync = VSyncType.VSYNC_DEFAULT; + } + + /** + * Creates an ExtendedBufferCapabilities instance with front/back/flip caps + * from the passed image/flip caps, and the v-sync type. + */ + public ExtendedBufferCapabilities(ImageCapabilities front, + ImageCapabilities back, FlipContents flip, + VSyncType t) + { + super(front, back, flip); + + this.vsync = t; + } + + /** + * Creates an ExtendedBufferCapabilities instance with front/back/flip caps + * from the passed cap, and the passed v-sync mode. + */ + public ExtendedBufferCapabilities(BufferCapabilities caps, VSyncType t) { + super(caps.getFrontBufferCapabilities(), + caps.getBackBufferCapabilities(), + caps.getFlipContents()); + + this.vsync = t; + } + + /** + * Creates an ExtendedBufferCapabilities instance with front/back/flip caps + * from the object, and passed v-sync mode. + */ + public ExtendedBufferCapabilities derive(VSyncType t) { + return new ExtendedBufferCapabilities(this, t); + } + + /** + * Returns the type of v-sync requested by this capabilities instance. + */ + public VSyncType getVSync() { + return vsync; + } + + @Override + public final boolean isPageFlipping() { + return true; + } +} |