--- a/jdk/src/windows/classes/sun/java2d/windows/Win32SurfaceDataProxy.java Fri Aug 08 08:52:18 2008 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,434 +0,0 @@
-/*
- * Copyright 2007 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.windows;
-
-import java.awt.Color;
-import java.awt.Transparency;
-import java.awt.Rectangle;
-import java.awt.image.ColorModel;
-import java.awt.image.IndexColorModel;
-import java.awt.image.DirectColorModel;
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferInt;
-
-import sun.awt.Win32GraphicsConfig;
-import sun.awt.Win32GraphicsDevice;
-import sun.awt.image.BufImgSurfaceData;
-import sun.awt.image.SunWritableRaster;
-import sun.java2d.SurfaceData;
-import sun.java2d.SurfaceDataProxy;
-import sun.java2d.SunGraphics2D;
-import sun.java2d.StateTracker;
-import sun.java2d.InvalidPipeException;
-import sun.java2d.loops.CompositeType;
-
-/**
- * The proxy class contains the logic for when to replace a
- * SurfaceData with a cached X11 Pixmap and the code to create
- * the accelerated surfaces.
- */
-public abstract class Win32SurfaceDataProxy extends SurfaceDataProxy {
- /**
- * Represents the maximum size (width * height) of an image that we should
- * scan for an unused color. Any image larger than this would probably
- * require too much computation time.
- */
- private static final int MAX_SIZE = 65536;
-
- public static SurfaceDataProxy createProxy(SurfaceData srcData,
- Win32GraphicsConfig dstConfig)
- {
- Win32GraphicsDevice wgd =
- (Win32GraphicsDevice) dstConfig.getDevice();
- if (!wgd.isDDEnabledOnDevice() ||
- srcData instanceof Win32SurfaceData ||
- srcData instanceof Win32OffScreenSurfaceData)
- {
- // If they are not on the same screen then we could cache the
- // blit by returning an instance of Opaque below, but this
- // only happens for VolatileImage blits to the wrong screen
- // which we make no promises on so we just punt to UNCACHED...
- return UNCACHED;
- }
-
- ColorModel srcCM = srcData.getColorModel();
- int srcTransparency = srcCM.getTransparency();
-
- if (srcTransparency == Transparency.OPAQUE) {
- return new Opaque(dstConfig);
- } else if (srcTransparency == Transparency.BITMASK) {
- if (Bitmask.isCompatible(srcCM, srcData)) {
- return new Bitmask(dstConfig);
- }
- }
-
- return UNCACHED;
- }
-
- int srcTransparency;
- Win32GraphicsConfig wgc;
-
- public Win32SurfaceDataProxy(Win32GraphicsConfig wgc,
- int srcTransparency)
- {
- this.wgc = wgc;
- this.srcTransparency = srcTransparency;
- activateDisplayListener();
- }
-
- @Override
- public SurfaceData validateSurfaceData(SurfaceData srcData,
- SurfaceData cachedData,
- int w, int h)
- {
- if (cachedData == null ||
- !cachedData.isValid() ||
- cachedData.isSurfaceLost())
- {
- // use the device's color model for ddraw surfaces
- ColorModel dstScreenCM = wgc.getDeviceColorModel();
- try {
- cachedData =
- Win32OffScreenSurfaceData.createData(w, h,
- dstScreenCM,
- wgc, null,
- srcTransparency);
- } catch (InvalidPipeException e) {
- Win32GraphicsDevice wgd = (Win32GraphicsDevice) wgc.getDevice();
- if (!wgd.isDDEnabledOnDevice()) {
- invalidate();
- flush();
- return null;
- }
- }
- }
- return cachedData;
- }
-
- /**
- * Proxy for opaque source images.
- */
- public static class Opaque extends Win32SurfaceDataProxy {
- static int TXMAX =
- (WindowsFlags.isDDScaleEnabled()
- ? SunGraphics2D.TRANSFORM_TRANSLATESCALE
- : SunGraphics2D.TRANSFORM_ANY_TRANSLATE);
-
- public Opaque(Win32GraphicsConfig wgc) {
- super(wgc, Transparency.OPAQUE);
- }
-
- @Override
- public boolean isSupportedOperation(SurfaceData srcData,
- int txtype,
- CompositeType comp,
- Color bgColor)
- {
- // we save a read from video memory for compositing
- // operations by copying from the buffered image sd
- return (txtype <= TXMAX &&
- (CompositeType.SrcOverNoEa.equals(comp) ||
- CompositeType.SrcNoEa.equals(comp)));
- }
- }
-
- /**
- * Proxy for bitmask transparent source images.
- * This proxy can accelerate unscaled SrcOver copies with no bgColor.
- *
- * Note that this proxy plays some games with returning the srcData
- * from the validate method. It needs to do this since the conditions
- * for caching an accelerated copy depend on many factors that can
- * change over time, including:
- *
- * - the depth of the display
- * - the availability of a transparent pixel
- */
- public static class Bitmask extends Win32SurfaceDataProxy {
- /**
- * Tests a source image ColorModel and SurfaceData to
- * see if they are of an appropriate size and type to
- * perform our transparent pixel searches.
- *
- * Note that some dynamic factors may occur which prevent
- * us from finding or using a transparent pixel. These
- * are detailed above in the class comments. We do not
- * test those conditions here, but rely on the Bitmask
- * proxy to verify those conditions on the fly.
- */
- public static boolean isCompatible(ColorModel srcCM,
- SurfaceData srcData)
- {
- if (srcCM instanceof IndexColorModel) {
- return true;
- } else if (srcCM instanceof DirectColorModel) {
- return isCompatibleDCM((DirectColorModel) srcCM, srcData);
- }
-
- return false;
- }
-
- /**
- * Tests a given DirectColorModel to make sure it is
- * compatible with the assumptions we make when scanning
- * a DCM image for a transparent pixel.
- */
- public static boolean isCompatibleDCM(DirectColorModel dcm,
- SurfaceData srcData)
- {
- // The BISD restriction is because we need to
- // examine the pixels to find a tranparent color
- if (!(srcData instanceof BufImgSurfaceData)) {
- return false;
- }
-
- // The size restriction prevents us from wasting too
- // much time scanning large images for unused pixel values.
- Rectangle bounds = srcData.getBounds();
- // Using division instead of multiplication avoids overflow
- if (bounds.width <= 0 ||
- MAX_SIZE / bounds.width < bounds.height)
- {
- return false;
- }
-
- // Below we use the pixels from the data buffer to map
- // directly to pixel values using the dstData.pixelFor()
- // method so the pixel format must be compatible with
- // ARGB or we could end up with bad results. We assume
- // here that the destination is opaque and so only the
- // red, green, and blue masks matter.
- // These new checks for RGB masks are more correct,
- // but potentially reject the acceleration of some images
- // that we used to allow just because we cannot prove
- // that they will work OK. If we ever had an INT_BGR
- // image for instance, would that have really failed here?
- // 565 and 555 screens will both keep equal numbers of
- // bits of red and blue, but will differ in the amount of
- // green they keep so INT_BGR might be safe, but if anyone
- // ever created an INT_RBG image then 555 and 565 might
- // differ in whether they thought a transparent pixel
- // was available. Also, are there any other strange
- // screen formats where bizarre orderings of the RGB
- // would cause the tests below to make mistakes?
- return ((dcm.getPixelSize() == 25) &&
- (dcm.getTransferType() == DataBuffer.TYPE_INT) &&
- (dcm.getRedMask() == 0x00ff0000) &&
- (dcm.getGreenMask() == 0x0000ff00) &&
- (dcm.getBlueMask() == 0x000000ff));
- }
-
- int transPixel;
- Color transColor;
-
- // The real accelerated surface - only used when we can find
- // a transparent color.
- SurfaceData accelData;
-
- public Bitmask(Win32GraphicsConfig wgc) {
- super(wgc, Transparency.BITMASK);
- }
-
- @Override
- public boolean isSupportedOperation(SurfaceData srcData,
- int txtype,
- CompositeType comp,
- Color bgColor)
- {
- // We have accelerated loops only for blits with SrcOverNoEa
- // (no blit bg loops or blit loops with SrcNoEa)
- return (CompositeType.SrcOverNoEa.equals(comp) &&
- bgColor == null &&
- txtype < SunGraphics2D.TRANSFORM_TRANSLATESCALE);
- }
-
- /**
- * Note that every time we update the surface we may or may
- * not find a transparent pixel depending on what was modified
- * in the source image since the last time we looked.
- * Our validation method saves the accelerated surface aside
- * in a different field so we can switch back and forth between
- * the accelerated version and null depending on whether we
- * find a transparent pixel.
- * Note that we also override getRetryTracker() and return a
- * tracker that tracks the source pixels so that we do not
- * try to revalidate until there are new pixels to be scanned.
- */
- @Override
- public SurfaceData validateSurfaceData(SurfaceData srcData,
- SurfaceData cachedData,
- int w, int h)
- {
- // Evaluate the dest screen pixel size every time
- ColorModel dstScreenCM = wgc.getDeviceColorModel();
- if (dstScreenCM.getPixelSize() <= 8) {
- return null;
- }
- accelData = super.validateSurfaceData(srcData, accelData, w, h);
- return (accelData != null &&
- findTransparentPixel(srcData, accelData))
- ? accelData
- : null;
- }
-
- @Override
- public StateTracker getRetryTracker(SurfaceData srcData) {
- // If we failed to validate, it is permanent until the
- // next change to srcData...
- return srcData.getStateTracker();
- }
-
- @Override
- public void updateSurfaceData(SurfaceData srcData,
- SurfaceData dstData,
- int w, int h)
- {
- updateSurfaceDataBg(srcData, dstData, w, h, transColor);
- }
-
- /**
- * Invoked when the cached surface should be dropped.
- * Overrides the base class implementation so we can invalidate
- * the accelData field instead of the cachedSD field.
- */
- @Override
- public synchronized void flush() {
- SurfaceData accelData = this.accelData;
- if (accelData != null) {
- this.accelData = null;
- accelData.flush();
- }
- super.flush();
- }
-
- /**
- * The following constants determine the size of the histograms
- * used when searching for an unused color
- */
- private static final int ICM_HISTOGRAM_SIZE = 256;
- private static final int ICM_HISTOGRAM_MASK = ICM_HISTOGRAM_SIZE - 1;
- private static final int DCM_HISTOGRAM_SIZE = 1024;
- private static final int DCM_HISTOGRAM_MASK = DCM_HISTOGRAM_SIZE - 1;
-
- /**
- * Attempts to find an unused pixel value in the image and if
- * successful, sets up the DirectDraw surface so that it uses
- * this value as its color key.
- */
- public boolean findTransparentPixel(SurfaceData srcData,
- SurfaceData accelData)
- {
- ColorModel srcCM = srcData.getColorModel();
- boolean success = false;
-
- if (srcCM instanceof IndexColorModel) {
- success = findUnusedPixelICM((IndexColorModel) srcCM,
- accelData);
- } else if (srcCM instanceof DirectColorModel) {
- success = findUnusedPixelDCM((BufImgSurfaceData) srcData,
- accelData);
- }
-
- if (success) {
- int rgb = accelData.rgbFor(transPixel);
- transColor = new Color(rgb);
- Win32OffScreenSurfaceData wossd =
- (Win32OffScreenSurfaceData) accelData;
- wossd.setTransparentPixel(transPixel);
- } else {
- transColor = null;
- }
- return success;
- }
-
- /**
- * Attempts to find an unused pixel value in the color map of an
- * IndexColorModel. If successful, it returns that value (in the
- * ColorModel of the destination surface) or null otherwise.
- */
- private boolean findUnusedPixelICM(IndexColorModel icm,
- SurfaceData accelData) {
- int mapsize = icm.getMapSize();
- int[] histogram = new int[ICM_HISTOGRAM_SIZE];
- int[] cmap = new int[mapsize];
- icm.getRGBs(cmap);
-
- // load up the histogram
- for (int i = 0; i < mapsize; i++) {
- int pixel = accelData.pixelFor(cmap[i]);
- histogram[pixel & ICM_HISTOGRAM_MASK]++;
- }
-
- // find an empty histo-bucket
- for (int j = 0; j < histogram.length; j++) {
- if (histogram[j] == 0) {
- transPixel = j;
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Attempts to find an unused pixel value in an image with a
- * 25-bit DirectColorModel and a DataBuffer of TYPE_INT.
- * If successful, it returns that value (in the ColorModel
- * of the destination surface) or null otherwise.
- */
- private boolean findUnusedPixelDCM(BufImgSurfaceData bisd,
- SurfaceData accelData)
- {
- BufferedImage bimg = (BufferedImage) bisd.getDestination();
- DataBufferInt db =
- (DataBufferInt) bimg.getRaster().getDataBuffer();
- int[] pixels = SunWritableRaster.stealData(db, 0);
- int[] histogram = new int[DCM_HISTOGRAM_SIZE];
-
- // load up the histogram
- // REMIND: we could possibly make this faster by keeping track
- // of the unique colors found, and only doing a pixelFor()
- // when we come across a new unique color
- // REMIND: We are assuming pixels are in ARGB format. Is that
- // a safe assumption here?
- for (int i = 0; i < pixels.length; i++) {
- int pixel = accelData.pixelFor(pixels[i]);
- histogram[pixel & DCM_HISTOGRAM_MASK]++;
- }
-
- // find an empty histo-bucket
- for (int j = 0; j < histogram.length; j++) {
- if (histogram[j] == 0) {
- transPixel = j;
- return true;
- }
- }
-
- return false;
- }
- }
-}