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