Path: blob/master/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java
41159 views
/*1* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.x11;2627import java.awt.Composite;28import java.awt.GraphicsConfiguration;29import java.awt.GraphicsDevice;30import java.awt.GraphicsEnvironment;31import java.awt.Image;32import java.awt.Rectangle;33import java.awt.Transparency;34import java.awt.color.ColorSpace;35import java.awt.image.ColorModel;36import java.awt.image.ComponentColorModel;37import java.awt.image.DirectColorModel;38import java.awt.image.IndexColorModel;39import java.awt.image.Raster;4041import sun.awt.SunHints;42import sun.awt.SunToolkit;43import sun.awt.X11ComponentPeer;44import sun.awt.X11GraphicsConfig;45import sun.awt.image.PixelConverter;46import sun.font.X11TextRenderer;47import sun.java2d.InvalidPipeException;48import sun.java2d.SunGraphics2D;49import sun.java2d.SunGraphicsEnvironment;50import sun.java2d.SurfaceData;51import sun.java2d.SurfaceDataProxy;52import sun.java2d.loops.CompositeType;53import sun.java2d.loops.GraphicsPrimitive;54import sun.java2d.loops.RenderLoops;55import sun.java2d.loops.SurfaceType;56import sun.java2d.loops.XORComposite;57import sun.java2d.pipe.PixelToShapeConverter;58import sun.java2d.pipe.Region;59import sun.java2d.pipe.TextPipe;60import sun.java2d.pipe.ValidatePipe;6162public abstract class X11SurfaceData extends XSurfaceData {63X11ComponentPeer peer;64X11GraphicsConfig graphicsConfig;65private RenderLoops solidloops;6667protected int depth;6869private static native void initIDs(Class<?> xorComp);70protected native void initSurface(int depth, int width, int height,71long drawable);7273public static final String74DESC_INT_BGR_X11 = "Integer BGR Pixmap";75public static final String76DESC_INT_RGB_X11 = "Integer RGB Pixmap";7778public static final String79DESC_4BYTE_ABGR_PRE_X11 = "4 byte ABGR Pixmap with pre-multplied alpha";80public static final String81DESC_INT_ARGB_PRE_X11 = "Integer ARGB Pixmap with pre-multiplied " +82"alpha";8384public static final String85DESC_BYTE_IND_OPQ_X11 = "Byte Indexed Opaque Pixmap";8687public static final String88DESC_INT_BGR_X11_BM = "Integer BGR Pixmap with 1-bit transp";89public static final String90DESC_INT_RGB_X11_BM = "Integer RGB Pixmap with 1-bit transp";91public static final String92DESC_BYTE_IND_X11_BM = "Byte Indexed Pixmap with 1-bit transp";9394public static final String95DESC_BYTE_GRAY_X11 = "Byte Gray Opaque Pixmap";96public static final String97DESC_INDEX8_GRAY_X11 = "Index8 Gray Opaque Pixmap";9899public static final String100DESC_BYTE_GRAY_X11_BM = "Byte Gray Opaque Pixmap with 1-bit transp";101public static final String102DESC_INDEX8_GRAY_X11_BM = "Index8 Gray Opaque Pixmap with 1-bit transp";103104public static final String105DESC_3BYTE_RGB_X11 = "3 Byte RGB Pixmap";106public static final String107DESC_3BYTE_BGR_X11 = "3 Byte BGR Pixmap";108109public static final String110DESC_3BYTE_RGB_X11_BM = "3 Byte RGB Pixmap with 1-bit transp";111public static final String112DESC_3BYTE_BGR_X11_BM = "3 Byte BGR Pixmap with 1-bit transp";113114public static final String115DESC_USHORT_555_RGB_X11 = "Ushort 555 RGB Pixmap";116public static final String117DESC_USHORT_565_RGB_X11 = "Ushort 565 RGB Pixmap";118119public static final String120DESC_USHORT_555_RGB_X11_BM121= "Ushort 555 RGB Pixmap with 1-bit transp";122public static final String123DESC_USHORT_565_RGB_X11_BM124= "Ushort 565 RGB Pixmap with 1-bit transp";125public static final String126DESC_USHORT_INDEXED_X11 = "Ushort Indexed Pixmap";127128public static final String129DESC_USHORT_INDEXED_X11_BM = "Ushort Indexed Pixmap with 1-bit transp";130131public static final SurfaceType IntBgrX11 =132SurfaceType.IntBgr.deriveSubType(DESC_INT_BGR_X11);133public static final SurfaceType IntRgbX11 =134SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11);135136public static final SurfaceType FourByteAbgrPreX11 =137SurfaceType.FourByteAbgrPre.deriveSubType(DESC_4BYTE_ABGR_PRE_X11);138public static final SurfaceType IntArgbPreX11 =139SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_PRE_X11);140141public static final SurfaceType ThreeByteRgbX11 =142SurfaceType.ThreeByteRgb.deriveSubType(DESC_3BYTE_RGB_X11);143public static final SurfaceType ThreeByteBgrX11 =144SurfaceType.ThreeByteBgr.deriveSubType(DESC_3BYTE_BGR_X11);145146public static final SurfaceType UShort555RgbX11 =147SurfaceType.Ushort555Rgb.deriveSubType(DESC_USHORT_555_RGB_X11);148public static final SurfaceType UShort565RgbX11 =149SurfaceType.Ushort565Rgb.deriveSubType(DESC_USHORT_565_RGB_X11);150151public static final SurfaceType UShortIndexedX11 =152SurfaceType.UshortIndexed.deriveSubType(DESC_USHORT_INDEXED_X11);153154public static final SurfaceType ByteIndexedOpaqueX11 =155SurfaceType.ByteIndexedOpaque.deriveSubType(DESC_BYTE_IND_OPQ_X11);156157public static final SurfaceType ByteGrayX11 =158SurfaceType.ByteGray.deriveSubType(DESC_BYTE_GRAY_X11);159public static final SurfaceType Index8GrayX11 =160SurfaceType.Index8Gray.deriveSubType(DESC_INDEX8_GRAY_X11);161162// Bitmap surface types163public static final SurfaceType IntBgrX11_BM =164SurfaceType.Custom.deriveSubType(DESC_INT_BGR_X11_BM,165PixelConverter.Xbgr.instance);166public static final SurfaceType IntRgbX11_BM =167SurfaceType.Custom.deriveSubType(DESC_INT_RGB_X11_BM,168PixelConverter.Xrgb.instance);169170public static final SurfaceType ThreeByteRgbX11_BM =171SurfaceType.Custom.deriveSubType(DESC_3BYTE_RGB_X11_BM,172PixelConverter.Xbgr.instance);173public static final SurfaceType ThreeByteBgrX11_BM =174SurfaceType.Custom.deriveSubType(DESC_3BYTE_BGR_X11_BM,175PixelConverter.Xrgb.instance);176177public static final SurfaceType UShort555RgbX11_BM =178SurfaceType.Custom.deriveSubType(DESC_USHORT_555_RGB_X11_BM,179PixelConverter.Ushort555Rgb.instance);180public static final SurfaceType UShort565RgbX11_BM =181SurfaceType.Custom.deriveSubType(DESC_USHORT_565_RGB_X11_BM,182PixelConverter.Ushort565Rgb.instance);183184public static final SurfaceType UShortIndexedX11_BM =185SurfaceType.Custom.deriveSubType(DESC_USHORT_INDEXED_X11_BM);186187public static final SurfaceType ByteIndexedX11_BM =188SurfaceType.Custom.deriveSubType(DESC_BYTE_IND_X11_BM);189190public static final SurfaceType ByteGrayX11_BM =191SurfaceType.Custom.deriveSubType(DESC_BYTE_GRAY_X11_BM);192public static final SurfaceType Index8GrayX11_BM =193SurfaceType.Custom.deriveSubType(DESC_INDEX8_GRAY_X11_BM);194195196private static Boolean accelerationEnabled = null;197198public Raster getRaster(int x, int y, int w, int h) {199throw new InternalError("not implemented yet");200}201202protected X11Renderer x11pipe;203protected PixelToShapeConverter x11txpipe;204protected static TextPipe x11textpipe;205206static {207if (!isX11SurfaceDataInitialized() &&208!GraphicsEnvironment.isHeadless()) {209210initIDs(XORComposite.class);211212@SuppressWarnings("removal")213String xtextpipe = java.security.AccessController.doPrivileged214(new sun.security.action.GetPropertyAction("sun.java2d.xtextpipe"));215if (xtextpipe == null || "true".startsWith(xtextpipe)) {216if ("true".equals(xtextpipe)) {217// Only verbose if they use the full string "true"218System.out.println("using X11 text renderer");219}220x11textpipe = new X11TextRenderer();221if (GraphicsPrimitive.tracingEnabled()) {222x11textpipe = ((X11TextRenderer) x11textpipe).traceWrap();223}224} else {225if ("false".equals(xtextpipe)) {226// Only verbose if they use the full string "false"227System.out.println("using DGA text renderer");228}229x11textpipe = solidTextRenderer;230}231232if (isAccelerationEnabled()) {233X11PMBlitLoops.register();234X11PMBlitBgLoops.register();235}236}237}238239/**240* Returns true if shared memory pixmaps are available241*/242private static native boolean isShmPMAvailable();243244public static boolean isAccelerationEnabled() {245if (accelerationEnabled == null) {246247if (GraphicsEnvironment.isHeadless()) {248accelerationEnabled = Boolean.FALSE;249} else {250@SuppressWarnings("removal")251String prop = java.security.AccessController.doPrivileged(252new sun.security.action.GetPropertyAction("sun.java2d.pmoffscreen"));253if (prop != null) {254// true iff prop==true, false otherwise255accelerationEnabled = Boolean.valueOf(prop);256} else {257boolean isDisplayLocal = false;258GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();259if (ge instanceof SunGraphicsEnvironment) {260isDisplayLocal = ((SunGraphicsEnvironment) ge).isDisplayLocal();261}262263// EXA based drivers tend to place pixmaps in VRAM, slowing down readbacks.264// Don't use pixmaps if we are local and shared memory Pixmaps265// are not available.266accelerationEnabled = !(isDisplayLocal && !isShmPMAvailable());267}268}269}270return accelerationEnabled.booleanValue();271}272273@Override274public SurfaceDataProxy makeProxyFor(SurfaceData srcData) {275return X11SurfaceDataProxy.createProxy(srcData, graphicsConfig);276}277278public void validatePipe(SunGraphics2D sg2d) {279if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON &&280sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&281(sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY ||282sg2d.compositeState == SunGraphics2D.COMP_XOR))283{284if (x11txpipe == null) {285/*286* Note: this is thread-safe since x11txpipe is the287* second of the two pipes constructed in makePipes().288* In the rare case we are racing against another289* thread making new pipes, setting lazypipe is a290* safe alternative to waiting for the other thread.291*/292sg2d.drawpipe = lazypipe;293sg2d.fillpipe = lazypipe;294sg2d.shapepipe = lazypipe;295sg2d.imagepipe = lazypipe;296sg2d.textpipe = lazypipe;297return;298}299300if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {301// Do this to init textpipe correctly; we will override the302// other non-text pipes below303// REMIND: we should clean this up eventually instead of304// having this work duplicated.305super.validatePipe(sg2d);306} else {307switch (sg2d.textAntialiasHint) {308309case SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT:310/* equating to OFF which it is for us */311case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:312// Use X11 pipe even if DGA is available since DGA313// text slows everything down when mixed with X11 calls314if (sg2d.compositeState == SunGraphics2D.COMP_ISCOPY) {315sg2d.textpipe = x11textpipe;316} else {317sg2d.textpipe = solidTextRenderer;318}319break;320321case SunHints.INTVAL_TEXT_ANTIALIAS_ON:322// Remind: may use Xrender for these when composite is323// copy as above, or if remote X11.324sg2d.textpipe = aaTextRenderer;325break;326327default:328switch (sg2d.getFontInfo().aaHint) {329330case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_HRGB:331case SunHints.INTVAL_TEXT_ANTIALIAS_LCD_VRGB:332sg2d.textpipe = lcdTextRenderer;333break;334335case SunHints.INTVAL_TEXT_ANTIALIAS_OFF:336// Use X11 pipe even if DGA is available since DGA337// text slows everything down when mixed with X11 calls338if (sg2d.compositeState == SunGraphics2D.COMP_ISCOPY) {339sg2d.textpipe = x11textpipe;340} else {341sg2d.textpipe = solidTextRenderer;342}343break;344345case SunHints.INTVAL_TEXT_ANTIALIAS_ON:346sg2d.textpipe = aaTextRenderer;347break;348349default:350sg2d.textpipe = solidTextRenderer;351}352}353}354355if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {356sg2d.drawpipe = x11txpipe;357sg2d.fillpipe = x11txpipe;358} else if (sg2d.strokeState != SunGraphics2D.STROKE_THIN){359sg2d.drawpipe = x11txpipe;360sg2d.fillpipe = x11pipe;361} else {362sg2d.drawpipe = x11pipe;363sg2d.fillpipe = x11pipe;364}365sg2d.shapepipe = x11pipe;366sg2d.imagepipe = imagepipe;367368// This is needed for AA text.369// Note that even an X11TextRenderer can dispatch AA text370// if a GlyphVector overrides the AA setting.371// We use getRenderLoops() rather than setting solidloops372// directly so that we get the appropriate loops in XOR mode.373if (sg2d.loops == null) {374// assert(some pipe will always be a LoopBasedPipe)375sg2d.loops = getRenderLoops(sg2d);376}377} else {378super.validatePipe(sg2d);379}380}381382public RenderLoops getRenderLoops(SunGraphics2D sg2d) {383if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR &&384sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY)385{386return solidloops;387}388return super.getRenderLoops(sg2d);389}390391public GraphicsConfiguration getDeviceConfiguration() {392return graphicsConfig;393}394395/**396* Method for instantiating a Window SurfaceData397*/398public static X11WindowSurfaceData createData(X11ComponentPeer peer) {399X11GraphicsConfig gc = getGC(peer);400return new X11WindowSurfaceData(peer, gc, gc.getSurfaceType());401}402403/**404* Method for instantiating a Pixmap SurfaceData (offscreen)405*/406public static X11PixmapSurfaceData createData(X11GraphicsConfig gc,407int width, int height,408ColorModel cm, Image image,409long drawable,410int transparency,411boolean isTexture)412{413return new X11PixmapSurfaceData(gc, width, height, image,414getSurfaceType(gc, transparency, true),415cm, drawable, transparency, isTexture);416}417418// /**419// * Initializes the native Ops pointer.420// */421// private native void initOps(X11ComponentPeer peer,422// X11GraphicsConfig gc, int depth);423424protected X11SurfaceData(X11ComponentPeer peer,425X11GraphicsConfig gc,426SurfaceType sType,427ColorModel cm) {428super(sType, cm);429this.peer = peer;430this.graphicsConfig = gc;431this.solidloops = graphicsConfig.getSolidLoops(sType);432this.depth = cm.getPixelSize();433initOps(peer, graphicsConfig, depth);434if (isAccelerationEnabled()) {435setBlitProxyKey(gc.getProxyKey());436}437}438439public static X11GraphicsConfig getGC(X11ComponentPeer peer) {440if (peer != null) {441return (X11GraphicsConfig) peer.getGraphicsConfiguration();442} else {443GraphicsEnvironment env =444GraphicsEnvironment.getLocalGraphicsEnvironment();445GraphicsDevice gd = env.getDefaultScreenDevice();446return (X11GraphicsConfig)gd.getDefaultConfiguration();447}448}449450/**451* Returns a boolean indicating whether or not a copyArea from452* the given rectangle source coordinates might be incomplete453* and result in X11 GraphicsExposure events being generated454* from XCopyArea.455* This method allows the SurfaceData copyArea method to determine456* if it needs to set the GraphicsExposures attribute of the X11 GC457* to True or False to receive or avoid the events.458* @return true if there is any chance that an XCopyArea from the459* given source coordinates could produce any X11460* Exposure events.461*/462public abstract boolean canSourceSendExposures(int x, int y, int w, int h);463464public boolean copyArea(SunGraphics2D sg2d,465int x, int y, int w, int h, int dx, int dy)466{467if (x11pipe == null) {468if (!isDrawableValid()) {469return true;470}471makePipes();472}473CompositeType comptype = sg2d.imageComp;474if ((CompositeType.SrcOverNoEa.equals(comptype) ||475CompositeType.SrcNoEa.equals(comptype)))476{477SunToolkit.awtLock();478try {479boolean needExposures = canSourceSendExposures(x, y, w, h);480long xgc = getBlitGC(sg2d.getCompClip(), needExposures);481x11pipe.devCopyArea(getNativeOps(), xgc,482x, y,483x + dx, y + dy,484w, h);485} finally {486SunToolkit.awtUnlock();487}488return true;489}490return false;491}492493public static SurfaceType getSurfaceType(X11GraphicsConfig gc,494int transparency)495{496return getSurfaceType(gc, transparency, false);497}498499@SuppressWarnings("fallthrough")500public static SurfaceType getSurfaceType(X11GraphicsConfig gc,501int transparency,502boolean pixmapSurface)503{504boolean transparent = (transparency == Transparency.BITMASK);505SurfaceType sType;506ColorModel cm = gc.getColorModel();507switch (cm.getPixelSize()) {508case 24:509if (gc.getBitsPerPixel() == 24) {510if (cm instanceof DirectColorModel) {511// 4517321: We will always use ThreeByteBgr for 24 bpp512// surfaces, regardless of the pixel masks reported by513// X11. Despite ambiguity in the X11 spec in how 24 bpp514// surfaces are treated, it appears that the best515// SurfaceType for these configurations (including516// some Matrox Millenium and ATI Radeon boards) is517// ThreeByteBgr.518sType = transparent ? X11SurfaceData.ThreeByteBgrX11_BM : X11SurfaceData.ThreeByteBgrX11;519} else {520throw new sun.java2d.InvalidPipeException("Unsupported bit " +521"depth/cm combo: " +522cm.getPixelSize() +523", " + cm);524}525break;526}527// Fall through for 32 bit case528case 32:529if (cm instanceof DirectColorModel) {530if (((SunToolkit)java.awt.Toolkit.getDefaultToolkit()531).isTranslucencyCapable(gc) && !pixmapSurface)532{533sType = X11SurfaceData.IntArgbPreX11;534} else {535if (((DirectColorModel)cm).getRedMask() == 0xff0000) {536sType = transparent ? X11SurfaceData.IntRgbX11_BM :537X11SurfaceData.IntRgbX11;538} else {539sType = transparent ? X11SurfaceData.IntBgrX11_BM :540X11SurfaceData.IntBgrX11;541}542}543} else if (cm instanceof ComponentColorModel) {544sType = X11SurfaceData.FourByteAbgrPreX11;545} else {546547throw new sun.java2d.InvalidPipeException("Unsupported bit " +548"depth/cm combo: " +549cm.getPixelSize() +550", " + cm);551}552break;553case 15:554sType = transparent ? X11SurfaceData.UShort555RgbX11_BM : X11SurfaceData.UShort555RgbX11;555break;556case 16:557if ((cm instanceof DirectColorModel) &&558(((DirectColorModel)cm).getGreenMask() == 0x3e0))559{560// fix for 4352984: Riva128 on Linux561sType = transparent ? X11SurfaceData.UShort555RgbX11_BM : X11SurfaceData.UShort555RgbX11;562} else {563sType = transparent ? X11SurfaceData.UShort565RgbX11_BM : X11SurfaceData.UShort565RgbX11;564}565break;566case 12:567if (cm instanceof IndexColorModel) {568sType = transparent ?569X11SurfaceData.UShortIndexedX11_BM :570X11SurfaceData.UShortIndexedX11;571} else {572throw new sun.java2d.InvalidPipeException("Unsupported bit " +573"depth: " +574cm.getPixelSize() +575" cm="+cm);576}577break;578case 8:579if (cm.getColorSpace().getType() == ColorSpace.TYPE_GRAY &&580cm instanceof ComponentColorModel) {581sType = transparent ? X11SurfaceData.ByteGrayX11_BM : X11SurfaceData.ByteGrayX11;582} else if (cm instanceof IndexColorModel &&583isOpaqueGray((IndexColorModel)cm)) {584sType = transparent ? X11SurfaceData.Index8GrayX11_BM : X11SurfaceData.Index8GrayX11;585} else {586sType = transparent ? X11SurfaceData.ByteIndexedX11_BM : X11SurfaceData.ByteIndexedOpaqueX11;587}588break;589default:590throw new sun.java2d.InvalidPipeException("Unsupported bit " +591"depth: " +592cm.getPixelSize());593}594return sType;595}596597public void invalidate() {598if (isValid()) {599setInvalid();600super.invalidate();601}602}603604/**605* The following methods and variables are used to keep the Java-level606* context state in sync with the native X11 GC associated with this607* X11SurfaceData object.608*/609610private static native void XSetCopyMode(long xgc);611private static native void XSetXorMode(long xgc);612private static native void XSetForeground(long xgc, int pixel);613614private long xgc;615private Region validatedClip;616private XORComposite validatedXorComp;617private int xorpixelmod;618private int validatedPixel;619private boolean validatedExposures = true;620621public final long getRenderGC(Region clip,622int compState, Composite comp,623int pixel)624{625return getGC(clip, compState, comp, pixel, validatedExposures);626}627628public final long getBlitGC(Region clip, boolean needExposures) {629return getGC(clip, SunGraphics2D.COMP_ISCOPY, null,630validatedPixel, needExposures);631}632633final long getGC(Region clip,634int compState, Composite comp,635int pixel, boolean needExposures)636{637// assert SunToolkit.isAWTLockHeldByCurrentThread();638639if (!isValid()) {640throw new InvalidPipeException("bounds changed");641}642643// validate clip644if (clip != validatedClip) {645validatedClip = clip;646if (clip != null) {647XSetClip(xgc,648clip.getLoX(), clip.getLoY(),649clip.getHiX(), clip.getHiY(),650(clip.isRectangular() ? null : clip));651} else {652XResetClip(xgc);653}654}655656// validate composite657if (compState == SunGraphics2D.COMP_ISCOPY) {658if (validatedXorComp != null) {659validatedXorComp = null;660xorpixelmod = 0;661XSetCopyMode(xgc);662}663} else {664if (validatedXorComp != comp) {665validatedXorComp = (XORComposite)comp;666xorpixelmod = validatedXorComp.getXorPixel();667XSetXorMode(xgc);668}669}670671// validate pixel672pixel ^= xorpixelmod;673if (pixel != validatedPixel) {674validatedPixel = pixel;675XSetForeground(xgc, pixel);676}677678if (validatedExposures != needExposures) {679validatedExposures = needExposures;680XSetGraphicsExposures(xgc, needExposures);681}682683return xgc;684}685686public synchronized void makePipes() {687if (x11pipe == null) {688SunToolkit.awtLock();689try {690xgc = XCreateGC(getNativeOps());691} finally {692SunToolkit.awtUnlock();693}694x11pipe = X11Renderer.getInstance();695x11txpipe = new PixelToShapeConverter(x11pipe);696}697}698699private static final class X11WindowSurfaceData extends X11SurfaceData {700701private final int scale;702703public X11WindowSurfaceData(X11ComponentPeer peer,704X11GraphicsConfig gc,705SurfaceType sType) {706super(peer, gc, sType, peer.getColorModel());707this.scale = gc.getDevice().getScaleFactor();708if (isDrawableValid()) {709makePipes();710}711}712713public SurfaceData getReplacement() {714return peer.getSurfaceData();715}716717public Rectangle getBounds() {718Rectangle r = peer.getBounds();719r.x = r.y = 0;720r.width *= scale;721r.height *= scale;722return r;723}724725@Override726public boolean canSourceSendExposures(int x, int y, int w, int h) {727return true;728}729730/**731* Returns destination Component associated with this SurfaceData.732*/733public Object getDestination() {734return peer.getTarget();735}736737@Override738public double getDefaultScaleX() {739return scale;740}741742@Override743public double getDefaultScaleY() {744return scale;745}746}747748private static final class X11PixmapSurfaceData extends X11SurfaceData {749750private final Image offscreenImage;751private final int width;752private final int height;753private final int transparency;754private final int scale;755756public X11PixmapSurfaceData(X11GraphicsConfig gc,757int width, int height,758Image image,759SurfaceType sType, ColorModel cm,760long drawable, int transparency,761boolean isTexture)762{763super(null, gc, sType, cm);764this.scale = isTexture ? 1 : gc.getDevice().getScaleFactor();765this.width = width * scale;766this.height = height * scale;767offscreenImage = image;768this.transparency = transparency;769initSurface(depth, this.width, this.height, drawable);770makePipes();771}772773public SurfaceData getReplacement() {774return restoreContents(offscreenImage);775}776777/**778* Need this since the surface data is created with779* the color model of the target GC, which is always780* opaque. But in SunGraphics2D.blitSD we choose loops781* based on the transparency on the source SD, so782* it could choose wrong loop (blit instead of blitbg,783* for example).784*/785public int getTransparency() {786return transparency;787}788789public Rectangle getBounds() {790return new Rectangle(width, height);791}792793@Override794public boolean canSourceSendExposures(int x, int y, int w, int h) {795return (x < 0 || y < 0 || (x+w) > width || (y+h) > height);796}797798public void flush() {799/*800* We need to invalidate the surface before disposing the801* native Drawable and GC. This way if an application tries802* to render to an already flushed X11SurfaceData, we will notice803* in the validate() method above that it has been invalidated,804* and we will avoid using those native resources that have805* already been disposed.806*/807invalidate();808flushNativeSurface();809}810811/**812* Returns destination Image associated with this SurfaceData.813*/814public Object getDestination() {815return offscreenImage;816}817818@Override819public double getDefaultScaleX() {820return scale;821}822823@Override824public double getDefaultScaleY() {825return scale;826}827}828829private static LazyPipe lazypipe = new LazyPipe();830831public static class LazyPipe extends ValidatePipe {832public boolean validate(SunGraphics2D sg2d) {833X11SurfaceData xsd = (X11SurfaceData) sg2d.surfaceData;834if (!xsd.isDrawableValid()) {835return false;836}837xsd.makePipes();838return super.validate(sg2d);839}840}841}842843844