| /* |
| * Copyright (c) 1999, 2014, Oracle and/or its affiliates. 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. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package sun.java2d.x11; |
| |
| import java.awt.GraphicsDevice; |
| import java.awt.GraphicsEnvironment; |
| import java.awt.Color; |
| import java.awt.Composite; |
| import java.awt.Rectangle; |
| import java.awt.GraphicsConfiguration; |
| import java.awt.Image; |
| import java.awt.color.ColorSpace; |
| import java.awt.Transparency; |
| import java.awt.image.BufferedImage; |
| import java.awt.image.ColorModel; |
| import java.awt.image.ComponentColorModel; |
| import java.awt.image.DirectColorModel; |
| import java.awt.image.IndexColorModel; |
| import java.awt.image.Raster; |
| import java.awt.peer.ComponentPeer; |
| |
| import sun.awt.SunHints; |
| import sun.awt.SunToolkit; |
| import sun.awt.X11ComponentPeer; |
| import sun.awt.X11GraphicsConfig; |
| import sun.awt.X11GraphicsEnvironment; |
| import sun.awt.image.PixelConverter; |
| import sun.font.X11TextRenderer; |
| import sun.java2d.InvalidPipeException; |
| import sun.java2d.SunGraphics2D; |
| import sun.java2d.SunGraphicsEnvironment; |
| import sun.java2d.SurfaceData; |
| import sun.java2d.SurfaceDataProxy; |
| import sun.java2d.loops.SurfaceType; |
| import sun.java2d.loops.CompositeType; |
| import sun.java2d.loops.RenderLoops; |
| import sun.java2d.loops.GraphicsPrimitive; |
| import sun.java2d.loops.XORComposite; |
| import sun.java2d.loops.Blit; |
| import sun.java2d.pipe.ValidatePipe; |
| import sun.java2d.pipe.PixelToShapeConverter; |
| import sun.java2d.pipe.TextPipe; |
| import sun.java2d.pipe.Region; |
| |
| public abstract class X11SurfaceData extends XSurfaceData { |
| X11ComponentPeer peer; |
| X11GraphicsConfig graphicsConfig; |
| private RenderLoops solidloops; |
| |
| protected int depth; |
| |
| private static native void initIDs(Class<?> xorComp); |
| protected native void initSurface(int depth, int width, int height, |
| long drawable); |
| |
| public static final String |
| DESC_INT_BGR_X11 = "Integer BGR Pixmap"; |
| public static final String |
| DESC_INT_RGB_X11 = "Integer RGB Pixmap"; |
| |
| public static final String |
| DESC_4BYTE_ABGR_PRE_X11 = "4 byte ABGR Pixmap with pre-multplied alpha"; |
| public static final String |
| DESC_INT_ARGB_PRE_X11 = "Integer ARGB Pixmap with pre-multiplied " + |
| "alpha"; |
| |
| public static final String |
| DESC_BYTE_IND_OPQ_X11 = "Byte Indexed Opaque Pixmap"; |
| |
| public static final String |
| DESC_INT_BGR_X11_BM = "Integer BGR Pixmap with 1-bit transp"; |
| public static final String |
| DESC_INT_RGB_X11_BM = "Integer RGB Pixmap with 1-bit transp"; |
| public static final String |
| DESC_BYTE_IND_X11_BM = "Byte Indexed Pixmap with 1-bit transp"; |
| |
| public static final String |
| DESC_BYTE_GRAY_X11 = "Byte Gray Opaque Pixmap"; |
| public static final String |
| DESC_INDEX8_GRAY_X11 = "Index8 Gray Opaque Pixmap"; |
| |
| public static final String |
| DESC_BYTE_GRAY_X11_BM = "Byte Gray Opaque Pixmap with 1-bit transp"; |
| public static final String |
| DESC_INDEX8_GRAY_X11_BM = "Index8 Gray Opaque Pixmap with 1-bit transp"; |
| |
| public static final String |
| DESC_3BYTE_RGB_X11 = "3 Byte RGB Pixmap"; |
| public static final String |
| DESC_3BYTE_BGR_X11 = "3 Byte BGR Pixmap"; |
| |
| public static final String |
| DESC_3BYTE_RGB_X11_BM = "3 Byte RGB Pixmap with 1-bit transp"; |
| public static final String |
| DESC_3BYTE_BGR_X11_BM = "3 Byte BGR Pixmap with 1-bit transp"; |
| |
| public static final String |
| DESC_USHORT_555_RGB_X11 = "Ushort 555 RGB Pixmap"; |
| public static final String |
| DESC_USHORT_565_RGB_X11 = "Ushort 565 RGB Pixmap"; |
| |
| public static final String |
| DESC_USHORT_555_RGB_X11_BM |
| = "Ushort 555 RGB Pixmap with 1-bit transp"; |
| public static final String |
| DESC_USHORT_565_RGB_X11_BM |
| = "Ushort 565 RGB Pixmap with 1-bit transp"; |
| public static final String |
| DESC_USHORT_INDEXED_X11 = "Ushort Indexed Pixmap"; |
| |
| public static final String |
| DESC_USHORT_INDEXED_X11_BM = "Ushort Indexed Pixmap with 1-bit transp"; |
| |
| public static final SurfaceType IntBgrX11 = |
| SurfaceType.IntBgr.deriveSubType(DESC_INT_BGR_X11); |
| public static final SurfaceType IntRgbX11 = |
| SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11); |
| |
| public static final SurfaceType FourByteAbgrPreX11 = |
| SurfaceType.FourByteAbgrPre.deriveSubType(DESC_4BYTE_ABGR_PRE_X11); |
| public static final SurfaceType IntArgbPreX11 = |
| SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_PRE_X11); |
| |
| public static final SurfaceType ThreeByteRgbX11 = |
| SurfaceType.ThreeByteRgb.deriveSubType(DESC_3BYTE_RGB_X11); |
| public static final SurfaceType ThreeByteBgrX11 = |
| SurfaceType.ThreeByteBgr.deriveSubType(DESC_3BYTE_BGR_X11); |
| |
| public static final SurfaceType UShort555RgbX11 = |
| SurfaceType.Ushort555Rgb.deriveSubType(DESC_USHORT_555_RGB_X11); |
| public static final SurfaceType UShort565RgbX11 = |
| SurfaceType.Ushort565Rgb.deriveSubType(DESC_USHORT_565_RGB_X11); |
| |
| public static final SurfaceType UShortIndexedX11 = |
| SurfaceType.UshortIndexed.deriveSubType(DESC_USHORT_INDEXED_X11); |
| |
| public static final SurfaceType ByteIndexedOpaqueX11 = |
| SurfaceType.ByteIndexedOpaque.deriveSubType(DESC_BYTE_IND_OPQ_X11); |
| |
| public static final SurfaceType ByteGrayX11 = |
| SurfaceType.ByteGray.deriveSubType(DESC_BYTE_GRAY_X11); |
| public static final SurfaceType Index8GrayX11 = |
| SurfaceType.Index8Gray.deriveSubType(DESC_INDEX8_GRAY_X11); |
| |
| // Bitmap surface types |
| public static final SurfaceType IntBgrX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_INT_BGR_X11_BM, |
| PixelConverter.Xbgr.instance); |
| public static final SurfaceType IntRgbX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_INT_RGB_X11_BM, |
| PixelConverter.Xrgb.instance); |
| |
| public static final SurfaceType ThreeByteRgbX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_3BYTE_RGB_X11_BM, |
| PixelConverter.Xbgr.instance); |
| public static final SurfaceType ThreeByteBgrX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_3BYTE_BGR_X11_BM, |
| PixelConverter.Xrgb.instance); |
| |
| public static final SurfaceType UShort555RgbX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_USHORT_555_RGB_X11_BM, |
| PixelConverter.Ushort555Rgb.instance); |
| public static final SurfaceType UShort565RgbX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_USHORT_565_RGB_X11_BM, |
| PixelConverter.Ushort565Rgb.instance); |
| |
| public static final SurfaceType UShortIndexedX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_USHORT_INDEXED_X11_BM); |
| |
| public static final SurfaceType ByteIndexedX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_BYTE_IND_X11_BM); |
| |
| public static final SurfaceType ByteGrayX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_BYTE_GRAY_X11_BM); |
| public static final SurfaceType Index8GrayX11_BM = |
| SurfaceType.Custom.deriveSubType(DESC_INDEX8_GRAY_X11_BM); |
| |
| |
| private static Boolean accelerationEnabled = null; |
| |
| public Raster getRaster(int x, int y, int w, int h) { |
| throw new InternalError("not implemented yet"); |
| } |
| |
| protected X11Renderer x11pipe; |
| protected PixelToShapeConverter x11txpipe; |
| protected static TextPipe x11textpipe; |
| |
| static { |
| if (!isX11SurfaceDataInitialized() && |
| !GraphicsEnvironment.isHeadless()) { |
| |
| initIDs(XORComposite.class); |
| |
| String xtextpipe = java.security.AccessController.doPrivileged |
| (new sun.security.action.GetPropertyAction("sun.java2d.xtextpipe")); |
| if (xtextpipe == null || "true".startsWith(xtextpipe)) { |
| if ("true".equals(xtextpipe)) { |
| // Only verbose if they use the full string "true" |
| System.out.println("using X11 text renderer"); |
| } |
| x11textpipe = new X11TextRenderer(); |
| if (GraphicsPrimitive.tracingEnabled()) { |
| x11textpipe = ((X11TextRenderer) x11textpipe).traceWrap(); |
| } |
| } else { |
| if ("false".equals(xtextpipe)) { |
| // Only verbose if they use the full string "false" |
| System.out.println("using DGA text renderer"); |
| } |
| x11textpipe = solidTextRenderer; |
| } |
| |
| if (isAccelerationEnabled()) { |
| X11PMBlitLoops.register(); |
| X11PMBlitBgLoops.register(); |
| } |
| } |
| } |
| |
| /** |
| * Returns true if shared memory pixmaps are available |
| */ |
| private static native boolean isShmPMAvailable(); |
| |
| public static boolean isAccelerationEnabled() { |
| if (accelerationEnabled == null) { |
| |
| if (GraphicsEnvironment.isHeadless()) { |
| accelerationEnabled = Boolean.FALSE; |
| } else { |
| String prop = java.security.AccessController.doPrivileged( |
| new sun.security.action.GetPropertyAction("sun.java2d.pmoffscreen")); |
| if (prop != null) { |
| // true iff prop==true, false otherwise |
| accelerationEnabled = Boolean.valueOf(prop); |
| } else { |
| boolean isDisplayLocal = false; |
| GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); |
| if (ge instanceof SunGraphicsEnvironment) { |
| isDisplayLocal = ((SunGraphicsEnvironment) ge).isDisplayLocal(); |
| } |
| |
| // EXA based drivers tend to place pixmaps in VRAM, slowing down readbacks. |
| // Don't use pixmaps if we are local and shared memory Pixmaps |
| // are not available. |
| accelerationEnabled = !(isDisplayLocal && !isShmPMAvailable()); |
| } |
| } |
| } |
| return accelerationEnabled.booleanValue(); |
| } |
| |
| @Override |
| public SurfaceDataProxy makeProxyFor(SurfaceData srcData) { |
| return X11SurfaceDataProxy.createProxy(srcData, graphicsConfig); |
| } |
| |
| public void validatePipe(SunGraphics2D sg2d) { |
| if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON && |
| sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && |
| (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY || |
| sg2d.compositeState == SunGraphics2D.COMP_XOR)) |
| { |
| if (x11txpipe == null) { |
| /* |
| * Note: this is thread-safe since x11txpipe is the |
| * second of the two pipes constructed in makePipes(). |
| * In the rare case we are racing against another |
| * thread making new pipes, setting lazypipe is a |
| * safe alternative to waiting for the other thread. |
| */ |
| sg2d.drawpipe = lazypipe; |
| sg2d.fillpipe = lazypipe; |
| sg2d.shapepipe = lazypipe; |
| sg2d.imagepipe = lazypipe; |
| sg2d.textpipe = lazypipe; |
| return; |
| } |
| |
| if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) { |
| // Do this to init textpipe correctly; we will override the |
| // other non-text pipes below |
| // REMIND: we should clean this up eventually instead of |
| // having this work duplicated. |
| super.validatePipe(sg2d); |
| } else { |
| switch (sg2d.textAntialiasHint) { |
| |
| case SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT: |
| /* equating to OFF which it is for us */ |
| case SunHints.INTVAL_TEXT_ANTIALIAS_OFF: |
| // Use X11 pipe even if DGA is available since DGA |
| // text slows everything down when mixed with X11 calls |
| if (sg2d.compositeState == SunGraphics2D.COMP_ISCOPY) { |
| sg2d.textpipe = x11textpipe; |
| } else { |
| sg2d.textpipe = solidTextRenderer; |
| } |
| break; |
| |
| case SunHints.INTVAL_TEXT_ANTIALIAS_ON: |
| // Remind: may use Xrender for these when composite is |
| // copy as above, or if remote X11. |
| sg2d.textpipe = aaTextRenderer; |
| break; |
| |
| default: |
| switch (sg2d.getFontInfo().aaHint) { |
| |
| case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB: |
| case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB: |
| sg2d.textpipe = lcdTextRenderer; |
| break; |
| |
| case SunHints.INTVAL_TEXT_ANTIALIAS_OFF: |
| // Use X11 pipe even if DGA is available since DGA |
| // text slows everything down when mixed with X11 calls |
| if (sg2d.compositeState == SunGraphics2D.COMP_ISCOPY) { |
| sg2d.textpipe = x11textpipe; |
| } else { |
| sg2d.textpipe = solidTextRenderer; |
| } |
| break; |
| |
| case SunHints.INTVAL_TEXT_ANTIALIAS_ON: |
| sg2d.textpipe = aaTextRenderer; |
| break; |
| |
| default: |
| sg2d.textpipe = solidTextRenderer; |
| } |
| } |
| } |
| |
| if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) { |
| sg2d.drawpipe = x11txpipe; |
| sg2d.fillpipe = x11txpipe; |
| } else if (sg2d.strokeState != SunGraphics2D.STROKE_THIN){ |
| sg2d.drawpipe = x11txpipe; |
| sg2d.fillpipe = x11pipe; |
| } else { |
| sg2d.drawpipe = x11pipe; |
| sg2d.fillpipe = x11pipe; |
| } |
| sg2d.shapepipe = x11pipe; |
| sg2d.imagepipe = imagepipe; |
| |
| // This is needed for AA text. |
| // Note that even an X11TextRenderer can dispatch AA text |
| // if a GlyphVector overrides the AA setting. |
| // We use getRenderLoops() rather than setting solidloops |
| // directly so that we get the appropriate loops in XOR mode. |
| if (sg2d.loops == null) { |
| // assert(some pipe will always be a LoopBasedPipe) |
| sg2d.loops = getRenderLoops(sg2d); |
| } |
| } else { |
| super.validatePipe(sg2d); |
| } |
| } |
| |
| public RenderLoops getRenderLoops(SunGraphics2D sg2d) { |
| if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && |
| sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY) |
| { |
| return solidloops; |
| } |
| return super.getRenderLoops(sg2d); |
| } |
| |
| public GraphicsConfiguration getDeviceConfiguration() { |
| return graphicsConfig; |
| } |
| |
| /** |
| * Method for instantiating a Window SurfaceData |
| */ |
| public static X11WindowSurfaceData createData(X11ComponentPeer peer) { |
| X11GraphicsConfig gc = getGC(peer); |
| return new X11WindowSurfaceData(peer, gc, gc.getSurfaceType()); |
| } |
| |
| /** |
| * Method for instantiating a Pixmap SurfaceData (offscreen) |
| */ |
| public static X11PixmapSurfaceData createData(X11GraphicsConfig gc, |
| int width, int height, |
| ColorModel cm, Image image, |
| long drawable, |
| int transparency) |
| { |
| return new X11PixmapSurfaceData(gc, width, height, image, |
| getSurfaceType(gc, transparency, true), |
| cm, drawable, transparency); |
| } |
| |
| // /** |
| // * Initializes the native Ops pointer. |
| // */ |
| // private native void initOps(X11ComponentPeer peer, |
| // X11GraphicsConfig gc, int depth); |
| |
| protected X11SurfaceData(X11ComponentPeer peer, |
| X11GraphicsConfig gc, |
| SurfaceType sType, |
| ColorModel cm) { |
| super(sType, cm); |
| this.peer = peer; |
| this.graphicsConfig = gc; |
| this.solidloops = graphicsConfig.getSolidLoops(sType); |
| this.depth = cm.getPixelSize(); |
| initOps(peer, graphicsConfig, depth); |
| if (isAccelerationEnabled()) { |
| setBlitProxyKey(gc.getProxyKey()); |
| } |
| } |
| |
| public static X11GraphicsConfig getGC(X11ComponentPeer peer) { |
| if (peer != null) { |
| return (X11GraphicsConfig) peer.getGraphicsConfiguration(); |
| } else { |
| GraphicsEnvironment env = |
| GraphicsEnvironment.getLocalGraphicsEnvironment(); |
| GraphicsDevice gd = env.getDefaultScreenDevice(); |
| return (X11GraphicsConfig)gd.getDefaultConfiguration(); |
| } |
| } |
| |
| /** |
| * Returns a boolean indicating whether or not a copyArea from |
| * the given rectangle source coordinates might be incomplete |
| * and result in X11 GraphicsExposure events being generated |
| * from XCopyArea. |
| * This method allows the SurfaceData copyArea method to determine |
| * if it needs to set the GraphicsExposures attribute of the X11 GC |
| * to True or False to receive or avoid the events. |
| * @return true if there is any chance that an XCopyArea from the |
| * given source coordinates could produce any X11 |
| * Exposure events. |
| */ |
| public abstract boolean canSourceSendExposures(int x, int y, int w, int h); |
| |
| public boolean copyArea(SunGraphics2D sg2d, |
| int x, int y, int w, int h, int dx, int dy) |
| { |
| if (x11pipe == null) { |
| if (!isDrawableValid()) { |
| return true; |
| } |
| makePipes(); |
| } |
| CompositeType comptype = sg2d.imageComp; |
| if ((CompositeType.SrcOverNoEa.equals(comptype) || |
| CompositeType.SrcNoEa.equals(comptype))) |
| { |
| SunToolkit.awtLock(); |
| try { |
| boolean needExposures = canSourceSendExposures(x, y, w, h); |
| long xgc = getBlitGC(sg2d.getCompClip(), needExposures); |
| x11pipe.devCopyArea(getNativeOps(), xgc, |
| x, y, |
| x + dx, y + dy, |
| w, h); |
| } finally { |
| SunToolkit.awtUnlock(); |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| public static SurfaceType getSurfaceType(X11GraphicsConfig gc, |
| int transparency) |
| { |
| return getSurfaceType(gc, transparency, false); |
| } |
| |
| @SuppressWarnings("fallthrough") |
| public static SurfaceType getSurfaceType(X11GraphicsConfig gc, |
| int transparency, |
| boolean pixmapSurface) |
| { |
| boolean transparent = (transparency == Transparency.BITMASK); |
| SurfaceType sType; |
| ColorModel cm = gc.getColorModel(); |
| switch (cm.getPixelSize()) { |
| case 24: |
| if (gc.getBitsPerPixel() == 24) { |
| if (cm instanceof DirectColorModel) { |
| // 4517321: We will always use ThreeByteBgr for 24 bpp |
| // surfaces, regardless of the pixel masks reported by |
| // X11. Despite ambiguity in the X11 spec in how 24 bpp |
| // surfaces are treated, it appears that the best |
| // SurfaceType for these configurations (including |
| // some Matrox Millenium and ATI Radeon boards) is |
| // ThreeByteBgr. |
| sType = transparent ? X11SurfaceData.ThreeByteBgrX11_BM : X11SurfaceData.ThreeByteBgrX11; |
| } else { |
| throw new sun.java2d.InvalidPipeException("Unsupported bit " + |
| "depth/cm combo: " + |
| cm.getPixelSize() + |
| ", " + cm); |
| } |
| break; |
| } |
| // Fall through for 32 bit case |
| case 32: |
| if (cm instanceof DirectColorModel) { |
| if (((SunToolkit)java.awt.Toolkit.getDefaultToolkit() |
| ).isTranslucencyCapable(gc) && !pixmapSurface) |
| { |
| sType = X11SurfaceData.IntArgbPreX11; |
| } else { |
| if (((DirectColorModel)cm).getRedMask() == 0xff0000) { |
| sType = transparent ? X11SurfaceData.IntRgbX11_BM : |
| X11SurfaceData.IntRgbX11; |
| } else { |
| sType = transparent ? X11SurfaceData.IntBgrX11_BM : |
| X11SurfaceData.IntBgrX11; |
| } |
| } |
| } else if (cm instanceof ComponentColorModel) { |
| sType = X11SurfaceData.FourByteAbgrPreX11; |
| } else { |
| |
| throw new sun.java2d.InvalidPipeException("Unsupported bit " + |
| "depth/cm combo: " + |
| cm.getPixelSize() + |
| ", " + cm); |
| } |
| break; |
| case 15: |
| sType = transparent ? X11SurfaceData.UShort555RgbX11_BM : X11SurfaceData.UShort555RgbX11; |
| break; |
| case 16: |
| if ((cm instanceof DirectColorModel) && |
| (((DirectColorModel)cm).getGreenMask() == 0x3e0)) |
| { |
| // fix for 4352984: Riva128 on Linux |
| sType = transparent ? X11SurfaceData.UShort555RgbX11_BM : X11SurfaceData.UShort555RgbX11; |
| } else { |
| sType = transparent ? X11SurfaceData.UShort565RgbX11_BM : X11SurfaceData.UShort565RgbX11; |
| } |
| break; |
| case 12: |
| if (cm instanceof IndexColorModel) { |
| sType = transparent ? |
| X11SurfaceData.UShortIndexedX11_BM : |
| X11SurfaceData.UShortIndexedX11; |
| } else { |
| throw new sun.java2d.InvalidPipeException("Unsupported bit " + |
| "depth: " + |
| cm.getPixelSize() + |
| " cm="+cm); |
| } |
| break; |
| case 8: |
| if (cm.getColorSpace().getType() == ColorSpace.TYPE_GRAY && |
| cm instanceof ComponentColorModel) { |
| sType = transparent ? X11SurfaceData.ByteGrayX11_BM : X11SurfaceData.ByteGrayX11; |
| } else if (cm instanceof IndexColorModel && |
| isOpaqueGray((IndexColorModel)cm)) { |
| sType = transparent ? X11SurfaceData.Index8GrayX11_BM : X11SurfaceData.Index8GrayX11; |
| } else { |
| sType = transparent ? X11SurfaceData.ByteIndexedX11_BM : X11SurfaceData.ByteIndexedOpaqueX11; |
| } |
| break; |
| default: |
| throw new sun.java2d.InvalidPipeException("Unsupported bit " + |
| "depth: " + |
| cm.getPixelSize()); |
| } |
| return sType; |
| } |
| |
| public void invalidate() { |
| if (isValid()) { |
| setInvalid(); |
| super.invalidate(); |
| } |
| } |
| |
| /** |
| * The following methods and variables are used to keep the Java-level |
| * context state in sync with the native X11 GC associated with this |
| * X11SurfaceData object. |
| */ |
| |
| private static native void XSetCopyMode(long xgc); |
| private static native void XSetXorMode(long xgc); |
| private static native void XSetForeground(long xgc, int pixel); |
| |
| private long xgc; |
| private Region validatedClip; |
| private XORComposite validatedXorComp; |
| private int xorpixelmod; |
| private int validatedPixel; |
| private boolean validatedExposures = true; |
| |
| public final long getRenderGC(Region clip, |
| int compState, Composite comp, |
| int pixel) |
| { |
| return getGC(clip, compState, comp, pixel, validatedExposures); |
| } |
| |
| public final long getBlitGC(Region clip, boolean needExposures) { |
| return getGC(clip, SunGraphics2D.COMP_ISCOPY, null, |
| validatedPixel, needExposures); |
| } |
| |
| final long getGC(Region clip, |
| int compState, Composite comp, |
| int pixel, boolean needExposures) |
| { |
| // assert SunToolkit.isAWTLockHeldByCurrentThread(); |
| |
| if (!isValid()) { |
| throw new InvalidPipeException("bounds changed"); |
| } |
| |
| // validate clip |
| if (clip != validatedClip) { |
| validatedClip = clip; |
| if (clip != null) { |
| XSetClip(xgc, |
| clip.getLoX(), clip.getLoY(), |
| clip.getHiX(), clip.getHiY(), |
| (clip.isRectangular() ? null : clip)); |
| } else { |
| XResetClip(xgc); |
| } |
| } |
| |
| // validate composite |
| if (compState == SunGraphics2D.COMP_ISCOPY) { |
| if (validatedXorComp != null) { |
| validatedXorComp = null; |
| xorpixelmod = 0; |
| XSetCopyMode(xgc); |
| } |
| } else { |
| if (validatedXorComp != comp) { |
| validatedXorComp = (XORComposite)comp; |
| xorpixelmod = validatedXorComp.getXorPixel(); |
| XSetXorMode(xgc); |
| } |
| } |
| |
| // validate pixel |
| pixel ^= xorpixelmod; |
| if (pixel != validatedPixel) { |
| validatedPixel = pixel; |
| XSetForeground(xgc, pixel); |
| } |
| |
| if (validatedExposures != needExposures) { |
| validatedExposures = needExposures; |
| XSetGraphicsExposures(xgc, needExposures); |
| } |
| |
| return xgc; |
| } |
| |
| public synchronized void makePipes() { |
| if (x11pipe == null) { |
| SunToolkit.awtLock(); |
| try { |
| xgc = XCreateGC(getNativeOps()); |
| } finally { |
| SunToolkit.awtUnlock(); |
| } |
| x11pipe = X11Renderer.getInstance(); |
| x11txpipe = new PixelToShapeConverter(x11pipe); |
| } |
| } |
| |
| public static class X11WindowSurfaceData extends X11SurfaceData { |
| public X11WindowSurfaceData(X11ComponentPeer peer, |
| X11GraphicsConfig gc, |
| SurfaceType sType) { |
| super(peer, gc, sType, peer.getColorModel()); |
| if (isDrawableValid()) { |
| makePipes(); |
| } |
| } |
| |
| public SurfaceData getReplacement() { |
| return peer.getSurfaceData(); |
| } |
| |
| public Rectangle getBounds() { |
| Rectangle r = peer.getBounds(); |
| r.x = r.y = 0; |
| return r; |
| } |
| |
| @Override |
| public boolean canSourceSendExposures(int x, int y, int w, int h) { |
| return true; |
| } |
| |
| /** |
| * Returns destination Component associated with this SurfaceData. |
| */ |
| public Object getDestination() { |
| return peer.getTarget(); |
| } |
| } |
| |
| public static class X11PixmapSurfaceData extends X11SurfaceData { |
| |
| Image offscreenImage; |
| int width; |
| int height; |
| int transparency; |
| |
| public X11PixmapSurfaceData(X11GraphicsConfig gc, |
| int width, int height, |
| Image image, |
| SurfaceType sType, ColorModel cm, |
| long drawable, int transparency) |
| { |
| super(null, gc, sType, cm); |
| this.width = width; |
| this.height = height; |
| offscreenImage = image; |
| this.transparency = transparency; |
| initSurface(depth, width, height, drawable); |
| makePipes(); |
| } |
| |
| public SurfaceData getReplacement() { |
| return restoreContents(offscreenImage); |
| } |
| |
| /** |
| * Need this since the surface data is created with |
| * the color model of the target GC, which is always |
| * opaque. But in SunGraphics2D.blitSD we choose loops |
| * based on the transparency on the source SD, so |
| * it could choose wrong loop (blit instead of blitbg, |
| * for example). |
| */ |
| public int getTransparency() { |
| return transparency; |
| } |
| |
| public Rectangle getBounds() { |
| return new Rectangle(width, height); |
| } |
| |
| @Override |
| public boolean canSourceSendExposures(int x, int y, int w, int h) { |
| return (x < 0 || y < 0 || (x+w) > width || (y+h) > height); |
| } |
| |
| public void flush() { |
| /* |
| * We need to invalidate the surface before disposing the |
| * native Drawable and GC. This way if an application tries |
| * to render to an already flushed X11SurfaceData, we will notice |
| * in the validate() method above that it has been invalidated, |
| * and we will avoid using those native resources that have |
| * already been disposed. |
| */ |
| invalidate(); |
| flushNativeSurface(); |
| } |
| |
| /** |
| * Returns destination Image associated with this SurfaceData. |
| */ |
| public Object getDestination() { |
| return offscreenImage; |
| } |
| } |
| |
| private static LazyPipe lazypipe = new LazyPipe(); |
| |
| public static class LazyPipe extends ValidatePipe { |
| public boolean validate(SunGraphics2D sg2d) { |
| X11SurfaceData xsd = (X11SurfaceData) sg2d.surfaceData; |
| if (!xsd.isDrawableValid()) { |
| return false; |
| } |
| xsd.makePipes(); |
| return super.validate(sg2d); |
| } |
| } |
| } |