1 /* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.xr; 27 28 import java.awt.*; 29 import java.awt.geom.*; 30 import java.awt.image.*; 31 import sun.awt.*; 32 import sun.java2d.InvalidPipeException; 33 import sun.java2d.SunGraphics2D; 34 import sun.java2d.SurfaceData; 35 import sun.java2d.SurfaceDataProxy; 36 import sun.java2d.jules.*; 37 import sun.java2d.loops.*; 38 import sun.java2d.pipe.*; 39 import sun.java2d.x11.*; 40 import sun.font.FontManagerNativeLibrary; 41 42 public abstract class XRSurfaceData extends XSurfaceData { 43 X11ComponentPeer peer; 44 XRGraphicsConfig graphicsConfig; 45 XRBackend renderQueue; 46 47 private RenderLoops solidloops; 48 49 protected int depth; 50 51 private static native void initIDs(); 52 53 protected native void XRInitSurface(int depth, int width, int height, 54 long drawable, int pictFormat); 55 56 native void initXRPicture(long xsdo, int pictForm); 57 58 native void freeXSDOPicture(long xsdo); 59 60 public static final String DESC_BYTE_A8_X11 = "Byte A8 Pixmap"; 61 public static final String DESC_INT_RGB_X11 = "Integer RGB Pixmap"; 62 public static final String DESC_INT_ARGB_X11 = "Integer ARGB-Pre Pixmap"; 63 64 public static final SurfaceType 65 ByteA8X11 = SurfaceType.ByteGray.deriveSubType(DESC_BYTE_A8_X11); 66 public static final SurfaceType 67 IntRgbX11 = SurfaceType.IntRgb.deriveSubType(DESC_INT_RGB_X11); 68 public static final SurfaceType 69 IntArgbPreX11 = SurfaceType.IntArgbPre.deriveSubType(DESC_INT_ARGB_X11); 70 71 public Raster getRaster(int x, int y, int w, int h) { 72 throw new InternalError("not implemented yet"); 73 } 74 75 protected XRRenderer xrpipe; 76 protected PixelToShapeConverter xrtxpipe; 77 protected TextPipe xrtextpipe; 78 protected XRDrawImage xrDrawImage; 79 80 protected ShapeDrawPipe aaShapePipe; 81 protected PixelToShapeConverter aaPixelToShapeConv; 82 83 public static void initXRSurfaceData() { 84 if (!isX11SurfaceDataInitialized()) { 85 FontManagerNativeLibrary.load(); 86 initIDs(); 87 XRPMBlitLoops.register(); 88 XRMaskFill.register(); 89 XRMaskBlit.register(); 90 91 setX11SurfaceDataInitialized(); 92 } 93 } 94 95 /** 96 * Synchronized accessor method for isDrawableValid. 97 */ 98 protected boolean isXRDrawableValid() { 99 try { 100 SunToolkit.awtLock(); 101 return isDrawableValid(); 102 } finally { 103 SunToolkit.awtUnlock(); 104 } 105 } 106 107 @Override 108 public SurfaceDataProxy makeProxyFor(SurfaceData srcData) { 109 return XRSurfaceDataProxy.createProxy(srcData, graphicsConfig); 110 } 111 112 @Override 113 public void validatePipe(SunGraphics2D sg2d) { 114 TextPipe textpipe; 115 boolean validated = false; 116 117 /* 118 * The textpipe for now can't handle TexturePaint when extra-alpha is 119 * specified nore XOR mode 120 */ 121 if ((textpipe = getTextPipe(sg2d)) == null) 122 { 123 super.validatePipe(sg2d); 124 textpipe = sg2d.textpipe; 125 validated = true; 126 } 127 128 PixelToShapeConverter txPipe = null; 129 XRRenderer nonTxPipe = null; 130 131 /* 132 * TODO: Can we rely on the GC for ARGB32 surfaces? 133 */ 134 if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) { 135 if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) { 136 if (sg2d.compositeState <= SunGraphics2D.COMP_XOR) { 137 txPipe = xrtxpipe; 138 nonTxPipe = xrpipe; 139 } 140 } else if (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) { 141 if (XRPaints.isValid(sg2d)) { 142 txPipe = xrtxpipe; 143 nonTxPipe = xrpipe; 144 } 145 // custom paints handled by super.validatePipe() below 146 } 147 } 148 149 if (sg2d.antialiasHint == SunHints.INTVAL_ANTIALIAS_ON && 150 JulesPathBuf.isCairoAvailable()) 151 { 152 sg2d.shapepipe = aaShapePipe; 153 sg2d.drawpipe = aaPixelToShapeConv; 154 sg2d.fillpipe = aaPixelToShapeConv; 155 } else { 156 if (txPipe != null) { 157 if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) { 158 sg2d.drawpipe = txPipe; 159 sg2d.fillpipe = txPipe; 160 } else if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) { 161 sg2d.drawpipe = txPipe; 162 sg2d.fillpipe = nonTxPipe; 163 } else { 164 sg2d.drawpipe = nonTxPipe; 165 sg2d.fillpipe = nonTxPipe; 166 } 167 sg2d.shapepipe = nonTxPipe; 168 } else { 169 if (!validated) { 170 super.validatePipe(sg2d); 171 } 172 } 173 } 174 175 // install the text pipe based on our earlier decision 176 sg2d.textpipe = textpipe; 177 178 // always override the image pipe with the specialized XRender pipe 179 sg2d.imagepipe = xrDrawImage; 180 } 181 182 protected TextPipe getTextPipe(SunGraphics2D sg2d) { 183 boolean supportedPaint = sg2d.compositeState <= SunGraphics2D.COMP_ALPHA 184 && (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR || sg2d.composite == null); 185 186 boolean supportedCompOp = false; 187 if (sg2d.composite instanceof AlphaComposite) { 188 int compRule = ((AlphaComposite) sg2d.composite).getRule(); 189 supportedCompOp = XRUtils.isMaskEvaluated(XRUtils.j2dAlphaCompToXR(compRule)) 190 || (compRule == AlphaComposite.SRC 191 && sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR); 192 } 193 194 return (supportedPaint && supportedCompOp) ? xrtextpipe : null; 195 } 196 197 protected MaskFill getMaskFill(SunGraphics2D sg2d) { 198 AlphaComposite aComp = null; 199 if(sg2d.composite != null 200 && sg2d.composite instanceof AlphaComposite) { 201 aComp = (AlphaComposite) sg2d.composite; 202 } 203 204 boolean supportedPaint = sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR 205 || XRPaints.isValid(sg2d); 206 207 boolean supportedCompOp = false; 208 if(aComp != null) { 209 int rule = aComp.getRule(); 210 supportedCompOp = XRUtils.isMaskEvaluated(XRUtils.j2dAlphaCompToXR(rule)); 211 } 212 213 return (supportedPaint && supportedCompOp) ? super.getMaskFill(sg2d) : null; 214 } 215 216 public RenderLoops getRenderLoops(SunGraphics2D sg2d) { 217 if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && 218 sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) 219 { 220 return solidloops; 221 } 222 223 return super.getRenderLoops(sg2d); 224 } 225 226 public GraphicsConfiguration getDeviceConfiguration() { 227 return graphicsConfig; 228 } 229 230 /** 231 * Method for instantiating a Window SurfaceData 232 */ 233 public static XRWindowSurfaceData createData(X11ComponentPeer peer) { 234 XRGraphicsConfig gc = getGC(peer); 235 return new XRWindowSurfaceData(peer, gc, gc.getSurfaceType()); 236 } 237 238 /** 239 * Method for instantiating a Pixmap SurfaceData (offscreen). 240 * If the surface * is opaque a 24-bit/RGB surface is chosen, 241 * otherwise a 32-bit ARGB surface. 242 */ 243 public static XRPixmapSurfaceData createData(XRGraphicsConfig gc, 244 int width, int height, 245 ColorModel cm, Image image, 246 long drawable, 247 int transparency) { 248 int depth; 249 // If we have a 32 bit color model for the window it needs 250 // alpha to support translucency of the window so we need 251 // to upgrade what was requested for the surface. 252 if (gc.getColorModel().getPixelSize() == 32) { 253 depth = 32; 254 transparency = Transparency.TRANSLUCENT; 255 } else { 256 depth = transparency > Transparency.OPAQUE ? 32 : 24; 257 } 258 259 if (depth == 24) { 260 cm = new DirectColorModel(depth, 261 0x00FF0000, 0x0000FF00, 0x000000FF); 262 } else { 263 cm = new DirectColorModel(depth, 0x00FF0000, 0x0000FF00, 264 0x000000FF, 0xFF000000); 265 } 266 267 return new XRPixmapSurfaceData 268 (gc, width, height, image, getSurfaceType(gc, transparency), 269 cm, drawable, transparency, 270 XRUtils.getPictureFormatForTransparency(transparency), depth); 271 } 272 273 protected XRSurfaceData(X11ComponentPeer peer, XRGraphicsConfig gc, 274 SurfaceType sType, ColorModel cm, int depth, int transparency) 275 { 276 super(sType, cm); 277 this.peer = peer; 278 this.graphicsConfig = gc; 279 this.solidloops = graphicsConfig.getSolidLoops(sType); 280 this.depth = depth; 281 initOps(peer, graphicsConfig, depth); 282 283 setBlitProxyKey(gc.getProxyKey()); 284 } 285 286 protected XRSurfaceData(XRBackend renderQueue) { 287 super(XRSurfaceData.IntRgbX11, 288 new DirectColorModel(24, 0x00FF0000, 0x0000FF00, 0x000000FF)); 289 this.renderQueue = renderQueue; 290 } 291 292 /** 293 * Inits the XRender-data-structures which belong to the XRSurfaceData. 294 * 295 * @param pictureFormat 296 */ 297 public void initXRender(int pictureFormat) { 298 try { 299 SunToolkit.awtLock(); 300 initXRPicture(getNativeOps(), pictureFormat); 301 renderQueue = XRCompositeManager.getInstance(this).getBackend(); 302 maskBuffer = XRCompositeManager.getInstance(this); 303 } catch (Throwable ex) { 304 ex.printStackTrace(); 305 } finally { 306 SunToolkit.awtUnlock(); 307 } 308 } 309 310 public static XRGraphicsConfig getGC(X11ComponentPeer peer) { 311 if (peer != null) { 312 return (XRGraphicsConfig) peer.getGraphicsConfiguration(); 313 } else { 314 GraphicsEnvironment env = 315 GraphicsEnvironment.getLocalGraphicsEnvironment(); 316 GraphicsDevice gd = env.getDefaultScreenDevice(); 317 return (XRGraphicsConfig) gd.getDefaultConfiguration(); 318 } 319 } 320 321 /** 322 * Returns a boolean indicating whether or not a copyArea from the given 323 * rectangle source coordinates might be incomplete and result in X11 324 * GraphicsExposure events being generated from XCopyArea. This method 325 * allows the SurfaceData copyArea method to determine if it needs to set 326 * the GraphicsExposures attribute of the X11 GC to True or False to receive 327 * or avoid the events. 328 * 329 * @return true if there is any chance that an XCopyArea from the given 330 * source coordinates could produce any X11 Exposure events. 331 */ 332 public abstract boolean canSourceSendExposures(int x, int y, int w, int h); 333 334 /** 335 * CopyArea is implemented using the "old" X11 GC, therefor clip and 336 * needExposures have to be validated against that GC. Pictures and GCs 337 * don't share state. 338 */ 339 public void validateCopyAreaGC(Region gcClip, boolean needExposures) { 340 if (validatedGCClip != gcClip) { 341 if (gcClip != null) 342 renderQueue.setGCClipRectangles(xgc, gcClip); 343 validatedGCClip = gcClip; 344 } 345 346 if (validatedExposures != needExposures) { 347 validatedExposures = needExposures; 348 renderQueue.setGCExposures(xgc, needExposures); 349 } 350 351 if (validatedXorComp != null) { 352 renderQueue.setGCMode(xgc, true); 353 renderQueue.setGCForeground(xgc, validatedGCForegroundPixel); 354 validatedXorComp = null; 355 } 356 } 357 358 public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, 359 int dx, int dy) { 360 if (xrpipe == null) { 361 if (!isXRDrawableValid()) { 362 return true; 363 } 364 makePipes(); 365 } 366 CompositeType comptype = sg2d.imageComp; 367 if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE && 368 (CompositeType.SrcOverNoEa.equals(comptype) || 369 CompositeType.SrcNoEa.equals(comptype))) 370 { 371 x += sg2d.transX; 372 y += sg2d.transY; 373 try { 374 SunToolkit.awtLock(); 375 boolean needExposures = canSourceSendExposures(x, y, w, h); 376 validateCopyAreaGC(sg2d.getCompClip(), needExposures); 377 renderQueue.copyArea(xid, xid, xgc, x, y, w, h, x + dx, y + dy); 378 } finally { 379 SunToolkit.awtUnlock(); 380 } 381 return true; 382 } 383 return false; 384 } 385 386 /** 387 * Returns the XRender SurfaceType which is able to fullfill the specified 388 * transparency requirement. 389 */ 390 public static SurfaceType getSurfaceType(XRGraphicsConfig gc, 391 int transparency) { 392 SurfaceType sType = null; 393 394 switch (transparency) { 395 case Transparency.OPAQUE: 396 sType = XRSurfaceData.IntRgbX11; 397 break; 398 399 case Transparency.BITMASK: 400 case Transparency.TRANSLUCENT: 401 sType = XRSurfaceData.IntArgbPreX11; 402 break; 403 } 404 405 return sType; 406 } 407 408 public void invalidate() { 409 if (isValid()) { 410 setInvalid(); 411 super.invalidate(); 412 } 413 } 414 415 private long xgc; // GC is still used for copyArea 416 private int validatedGCForegroundPixel = 0; 417 private XORComposite validatedXorComp; 418 private int xid; 419 public int picture; 420 public XRCompositeManager maskBuffer; 421 422 private Region validatedClip; 423 private Region validatedGCClip; 424 private boolean validatedExposures = true; 425 426 boolean transformInUse = false; 427 AffineTransform validatedSourceTransform = new AffineTransform(); 428 AffineTransform staticSrcTx = null; 429 int validatedRepeat = XRUtils.RepeatNone; 430 int validatedFilter = XRUtils.FAST; 431 432 /** 433 * Validates an XRSurfaceData when used as source. Note that the clip is 434 * applied when used as source as well as destination. 435 */ 436 void validateAsSource(AffineTransform sxForm, int repeat, int filter) { 437 438 if (validatedClip != null) { 439 validatedClip = null; 440 renderQueue.setClipRectangles(picture, null); 441 } 442 443 if (validatedRepeat != repeat && repeat != -1) { 444 validatedRepeat = repeat; 445 renderQueue.setPictureRepeat(picture, repeat); 446 } 447 448 if (sxForm == null) { 449 if (transformInUse) { 450 validatedSourceTransform.setToIdentity(); 451 renderQueue.setPictureTransform(picture, 452 validatedSourceTransform); 453 transformInUse = false; 454 } 455 } else if (!transformInUse || 456 (transformInUse && !sxForm.equals(validatedSourceTransform))) { 457 458 validatedSourceTransform.setTransform(sxForm.getScaleX(), 459 sxForm.getShearY(), 460 sxForm.getShearX(), 461 sxForm.getScaleY(), 462 sxForm.getTranslateX(), 463 sxForm.getTranslateY()); 464 465 AffineTransform srcTransform = validatedSourceTransform; 466 if(staticSrcTx != null) { 467 // Apply static transform set when used as texture or gradient. 468 // Create a copy to not modify validatedSourceTransform as 469 // this would confuse the validation logic. 470 srcTransform = new AffineTransform(validatedSourceTransform); 471 srcTransform.preConcatenate(staticSrcTx); 472 } 473 474 renderQueue.setPictureTransform(picture, srcTransform); 475 transformInUse = true; 476 } 477 478 if (filter != validatedFilter && filter != -1) { 479 renderQueue.setFilter(picture, filter); 480 validatedFilter = filter; 481 } 482 } 483 484 /** 485 * Validates the Surface when used as destination. 486 */ 487 public void validateAsDestination(SunGraphics2D sg2d, Region clip) { 488 if (!isValid()) { 489 throw new InvalidPipeException("bounds changed"); 490 } 491 492 boolean updateGCClip = false; 493 if (clip != validatedClip) { 494 renderQueue.setClipRectangles(picture, clip); 495 validatedClip = clip; 496 updateGCClip = true; 497 } 498 499 if (sg2d != null && sg2d.compositeState == SunGraphics2D.COMP_XOR) { 500 if (validatedXorComp != sg2d.getComposite()) { 501 validatedXorComp = (XORComposite) sg2d.getComposite(); 502 renderQueue.setGCMode(xgc, false); 503 } 504 505 // validate pixel 506 int pixel = sg2d.pixel; 507 if (validatedGCForegroundPixel != pixel) { 508 int xorpixelmod = validatedXorComp.getXorPixel(); 509 renderQueue.setGCForeground(xgc, pixel ^ xorpixelmod); 510 validatedGCForegroundPixel = pixel; 511 } 512 513 if (updateGCClip) { 514 renderQueue.setGCClipRectangles(xgc, clip); 515 } 516 } 517 } 518 519 public synchronized void makePipes() { /* 520 * TODO: Why is this synchronized, 521 * but access not? 522 */ 523 if (xrpipe == null) { 524 try { 525 SunToolkit.awtLock(); 526 xgc = XCreateGC(getNativeOps()); 527 528 xrpipe = new XRRenderer(maskBuffer.getMaskBuffer()); 529 xrtxpipe = new PixelToShapeConverter(xrpipe); 530 xrtextpipe = maskBuffer.getTextRenderer(); 531 xrDrawImage = new XRDrawImage(); 532 533 if (JulesPathBuf.isCairoAvailable()) { 534 aaShapePipe = 535 new JulesShapePipe(XRCompositeManager.getInstance(this)); 536 aaPixelToShapeConv = new PixelToShapeConverter(aaShapePipe); 537 } 538 } finally { 539 SunToolkit.awtUnlock(); 540 } 541 } 542 } 543 544 public static class XRWindowSurfaceData extends XRSurfaceData { 545 public XRWindowSurfaceData(X11ComponentPeer peer, 546 XRGraphicsConfig gc, SurfaceType sType) { 547 super(peer, gc, sType, peer.getColorModel(), 548 peer.getColorModel().getPixelSize(), Transparency.OPAQUE); 549 550 if (isXRDrawableValid()) { 551 // If we have a 32 bit color model for the window it needs 552 // alpha to support translucency of the window so we need 553 // to get the ARGB32 XRender picture format else for 554 // 24 bit colormodel we need RGB24 or OPAQUE pictureformat. 555 if (peer.getColorModel().getPixelSize() == 32) { 556 initXRender(XRUtils. 557 getPictureFormatForTransparency(Transparency.TRANSLUCENT)); 558 } 559 else { 560 initXRender(XRUtils. 561 getPictureFormatForTransparency(Transparency.OPAQUE)); 562 } 563 makePipes(); 564 } 565 } 566 567 public SurfaceData getReplacement() { 568 return peer.getSurfaceData(); 569 } 570 571 public Rectangle getBounds() { 572 Rectangle r = peer.getBounds(); 573 r.x = r.y = 0; 574 return r; 575 } 576 577 @Override 578 public boolean canSourceSendExposures(int x, int y, int w, int h) { 579 return true; 580 } 581 582 /** 583 * Returns destination Component associated with this SurfaceData. 584 */ 585 public Object getDestination() { 586 return peer.getTarget(); 587 } 588 589 public void invalidate() { 590 try { 591 SunToolkit.awtLock(); 592 freeXSDOPicture(getNativeOps()); 593 }finally { 594 SunToolkit.awtUnlock(); 595 } 596 597 super.invalidate(); 598 } 599 } 600 601 public static class XRInternalSurfaceData extends XRSurfaceData { 602 public XRInternalSurfaceData(XRBackend renderQueue, int pictXid) { 603 super(renderQueue); 604 this.picture = pictXid; 605 this.transformInUse = false; 606 } 607 608 public boolean canSourceSendExposures(int x, int y, int w, int h) { 609 return false; 610 } 611 612 public Rectangle getBounds() { 613 return null; 614 } 615 616 public Object getDestination() { 617 return null; 618 } 619 620 public SurfaceData getReplacement() { 621 return null; 622 } 623 } 624 625 public static class XRPixmapSurfaceData extends XRSurfaceData { 626 Image offscreenImage; 627 int width; 628 int height; 629 int transparency; 630 631 public XRPixmapSurfaceData(XRGraphicsConfig gc, int width, int height, 632 Image image, SurfaceType sType, 633 ColorModel cm, long drawable, 634 int transparency, int pictFormat, 635 int depth) { 636 super(null, gc, sType, cm, depth, transparency); 637 this.width = width; 638 this.height = height; 639 offscreenImage = image; 640 this.transparency = transparency; 641 initSurface(depth, width, height, drawable, pictFormat); 642 643 initXRender(pictFormat); 644 makePipes(); 645 } 646 647 public void initSurface(int depth, int width, int height, 648 long drawable, int pictFormat) { 649 try { 650 SunToolkit.awtLock(); 651 XRInitSurface(depth, width, height, drawable, pictFormat); 652 } finally { 653 SunToolkit.awtUnlock(); 654 } 655 } 656 657 public SurfaceData getReplacement() { 658 return restoreContents(offscreenImage); 659 } 660 661 /** 662 * Need this since the surface data is created with the color model of 663 * the target GC, which is always opaque. But in SunGraphics2D.blitSD we 664 * choose loops based on the transparency on the source SD, so it could 665 * choose wrong loop (blit instead of blitbg, for example). 666 */ 667 public int getTransparency() { 668 return transparency; 669 } 670 671 public Rectangle getBounds() { 672 return new Rectangle(width, height); 673 } 674 675 @Override 676 public boolean canSourceSendExposures(int x, int y, int w, int h) { 677 return (x < 0 || y < 0 || (x + w) > width || (y + h) > height); 678 } 679 680 public void flush() { 681 /* 682 * We need to invalidate the surface before disposing the native 683 * Drawable and Picture. This way if an application tries to render 684 * to an already flushed XRSurfaceData, we will notice in the 685 * validate() method above that it has been invalidated, and we will 686 * avoid using those native resources that have already been 687 * disposed. 688 */ 689 invalidate(); 690 flushNativeSurface(); 691 } 692 693 /** 694 * Returns destination Image associated with this SurfaceData. 695 */ 696 public Object getDestination() { 697 return offscreenImage; 698 } 699 } 700 701 public long getGC() { 702 return xgc; 703 } 704 705 public static class LazyPipe extends ValidatePipe { 706 public boolean validate(SunGraphics2D sg2d) { 707 XRSurfaceData xsd = (XRSurfaceData) sg2d.surfaceData; 708 if (!xsd.isXRDrawableValid()) { 709 return false; 710 } 711 xsd.makePipes(); 712 return super.validate(sg2d); 713 } 714 } 715 716 public int getPicture() { 717 return picture; 718 } 719 720 public int getXid() { 721 return xid; 722 } 723 724 public XRGraphicsConfig getGraphicsConfig() { 725 return graphicsConfig; 726 } 727 728 public void setStaticSrcTx(AffineTransform staticSrcTx) { 729 this.staticSrcTx = staticSrcTx; 730 } 731 }