1 /* 2 * Copyright (c) 2003, 2015, 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.opengl; 27 28 import java.awt.AlphaComposite; 29 import java.awt.Composite; 30 import java.awt.GraphicsConfiguration; 31 import java.awt.GraphicsEnvironment; 32 import java.awt.Rectangle; 33 import java.awt.Transparency; 34 import java.awt.image.ColorModel; 35 import java.awt.image.Raster; 36 import sun.awt.SunHints; 37 import sun.awt.image.PixelConverter; 38 import sun.java2d.pipe.hw.AccelSurface; 39 import sun.java2d.SunGraphics2D; 40 import sun.java2d.SurfaceData; 41 import sun.java2d.SurfaceDataProxy; 42 import sun.java2d.loops.CompositeType; 43 import sun.java2d.loops.GraphicsPrimitive; 44 import sun.java2d.loops.MaskFill; 45 import sun.java2d.loops.SurfaceType; 46 import sun.java2d.pipe.ParallelogramPipe; 47 import sun.java2d.pipe.PixelToParallelogramConverter; 48 import sun.java2d.pipe.RenderBuffer; 49 import sun.java2d.pipe.TextPipe; 50 import static sun.java2d.pipe.BufferedOpCodes.*; 51 import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; 52 53 /** 54 * This class describes an OpenGL "surface", that is, a region of pixels 55 * managed via OpenGL. An OGLSurfaceData can be tagged with one of three 56 * different SurfaceType objects for the purpose of registering loops, etc. 57 * This diagram shows the hierarchy of OGL SurfaceTypes: 58 * 59 * Any 60 * / \ 61 * OpenGLSurface OpenGLTexture 62 * | 63 * OpenGLSurfaceRTT 64 * 65 * OpenGLSurface 66 * This kind of surface can be rendered to using OpenGL APIs. It is also 67 * possible to copy an OpenGLSurface to another OpenGLSurface (or to itself). 68 * This is typically accomplished by calling MakeContextCurrent(dstSD, srcSD) 69 * and then calling glCopyPixels() (although there are other techniques to 70 * achieve the same goal). 71 * 72 * OpenGLTexture 73 * This kind of surface cannot be rendered to using OpenGL (in the same sense 74 * as in OpenGLSurface). However, it is possible to upload a region of pixels 75 * to an OpenGLTexture object via glTexSubImage2D(). One can also copy a 76 * surface of type OpenGLTexture to an OpenGLSurface by binding the texture 77 * to a quad and then rendering it to the destination surface (this process 78 * is known as "texture mapping"). 79 * 80 * OpenGLSurfaceRTT 81 * This kind of surface can be thought of as a sort of hybrid between 82 * OpenGLSurface and OpenGLTexture, in that one can render to this kind of 83 * surface as if it were of type OpenGLSurface, but the process of copying 84 * this kind of surface to another is more like an OpenGLTexture. (Note that 85 * "RTT" stands for "render-to-texture".) 86 * 87 * In addition to these SurfaceType variants, we have also defined some 88 * constants that describe in more detail the type of underlying OpenGL 89 * surface. This table helps explain the relationships between those 90 * "type" constants and their corresponding SurfaceType: 91 * 92 * OGL Type Corresponding SurfaceType 93 * -------- ------------------------- 94 * WINDOW OpenGLSurface 95 * TEXTURE OpenGLTexture 96 * FLIP_BACKBUFFER OpenGLSurface 97 * FBOBJECT OpenGLSurfaceRTT 98 */ 99 public abstract class OGLSurfaceData extends SurfaceData 100 implements AccelSurface { 101 102 /** 103 * OGL-specific surface types 104 * 105 * @see sun.java2d.pipe.hw.AccelSurface 106 */ 107 public static final int FBOBJECT = RT_TEXTURE; 108 109 /** 110 * Pixel formats 111 */ 112 public static final int PF_INT_ARGB = 0; 113 public static final int PF_INT_ARGB_PRE = 1; 114 public static final int PF_INT_RGB = 2; 115 public static final int PF_INT_RGBX = 3; 116 public static final int PF_INT_BGR = 4; 117 public static final int PF_INT_BGRX = 5; 118 public static final int PF_USHORT_565_RGB = 6; 119 public static final int PF_USHORT_555_RGB = 7; 120 public static final int PF_USHORT_555_RGBX = 8; 121 public static final int PF_BYTE_GRAY = 9; 122 public static final int PF_USHORT_GRAY = 10; 123 public static final int PF_3BYTE_BGR = 11; 124 125 /** 126 * SurfaceTypes 127 */ 128 private static final String DESC_OPENGL_SURFACE = "OpenGL Surface"; 129 private static final String DESC_OPENGL_SURFACE_RTT = 130 "OpenGL Surface (render-to-texture)"; 131 private static final String DESC_OPENGL_TEXTURE = "OpenGL Texture"; 132 133 static final SurfaceType OpenGLSurface = 134 SurfaceType.Any.deriveSubType(DESC_OPENGL_SURFACE, 135 PixelConverter.ArgbPre.instance); 136 static final SurfaceType OpenGLSurfaceRTT = 137 OpenGLSurface.deriveSubType(DESC_OPENGL_SURFACE_RTT); 138 static final SurfaceType OpenGLTexture = 139 SurfaceType.Any.deriveSubType(DESC_OPENGL_TEXTURE); 140 141 /** This will be true if the fbobject system property has been enabled. */ 142 private static boolean isFBObjectEnabled; 143 144 /** This will be true if the lcdshader system property has been enabled.*/ 145 private static boolean isLCDShaderEnabled; 146 147 /** This will be true if the biopshader system property has been enabled.*/ 148 private static boolean isBIOpShaderEnabled; 149 150 /** This will be true if the gradshader system property has been enabled.*/ 151 private static boolean isGradShaderEnabled; 152 153 private OGLGraphicsConfig graphicsConfig; 154 protected int type; 155 // these fields are set from the native code when the surface is 156 // initialized 157 private int nativeWidth, nativeHeight; 158 159 protected static OGLRenderer oglRenderPipe; 160 protected static PixelToParallelogramConverter oglTxRenderPipe; 161 protected static ParallelogramPipe oglAAPgramPipe; 162 protected static OGLTextRenderer oglTextPipe; 163 protected static OGLDrawImage oglImagePipe; 164 initTexture(long pData, boolean isOpaque, boolean texNonPow2, boolean texRect, int width, int height)165 protected native boolean initTexture(long pData, 166 boolean isOpaque, boolean texNonPow2, 167 boolean texRect, 168 int width, int height); initFBObject(long pData, boolean isOpaque, boolean texNonPow2, boolean texRect, int width, int height)169 protected native boolean initFBObject(long pData, 170 boolean isOpaque, boolean texNonPow2, 171 boolean texRect, 172 int width, int height); initFlipBackbuffer(long pData)173 protected native boolean initFlipBackbuffer(long pData); 174 getTextureTarget(long pData)175 private native int getTextureTarget(long pData); getTextureID(long pData)176 private native int getTextureID(long pData); 177 178 static { 179 if (!GraphicsEnvironment.isHeadless()) { 180 // fbobject currently enabled by default; use "false" to disable 181 String fbo = java.security.AccessController.doPrivileged( 182 new sun.security.action.GetPropertyAction( 183 "sun.java2d.opengl.fbobject")); 184 isFBObjectEnabled = !"false".equals(fbo); 185 186 // lcdshader currently enabled by default; use "false" to disable 187 String lcd = java.security.AccessController.doPrivileged( 188 new sun.security.action.GetPropertyAction( 189 "sun.java2d.opengl.lcdshader")); 190 isLCDShaderEnabled = !"false".equals(lcd); 191 192 // biopshader currently enabled by default; use "false" to disable 193 String biop = java.security.AccessController.doPrivileged( 194 new sun.security.action.GetPropertyAction( 195 "sun.java2d.opengl.biopshader")); 196 isBIOpShaderEnabled = !"false".equals(biop); 197 198 // gradshader currently enabled by default; use "false" to disable 199 String grad = java.security.AccessController.doPrivileged( 200 new sun.security.action.GetPropertyAction( 201 "sun.java2d.opengl.gradshader")); 202 isGradShaderEnabled = !"false".equals(grad); 203 204 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 205 oglImagePipe = new OGLDrawImage(); 206 oglTextPipe = new OGLTextRenderer(rq); 207 oglRenderPipe = new OGLRenderer(rq); 208 if (GraphicsPrimitive.tracingEnabled()) { 209 oglTextPipe = oglTextPipe.traceWrap(); 210 //The wrapped oglRenderPipe will wrap the AA pipe as well... 211 //oglAAPgramPipe = oglRenderPipe.traceWrap(); 212 } 213 oglAAPgramPipe = oglRenderPipe.getAAParallelogramPipe(); 214 oglTxRenderPipe = 215 new PixelToParallelogramConverter(oglRenderPipe, 216 oglRenderPipe, 217 1.0, 0.25, true); 218 OGLBlitLoops.register()219 OGLBlitLoops.register(); OGLMaskFill.register()220 OGLMaskFill.register(); OGLMaskBlit.register()221 OGLMaskBlit.register(); 222 } 223 } 224 OGLSurfaceData(OGLGraphicsConfig gc, ColorModel cm, int type)225 protected OGLSurfaceData(OGLGraphicsConfig gc, 226 ColorModel cm, int type) 227 { 228 super(getCustomSurfaceType(type), cm); 229 this.graphicsConfig = gc; 230 this.type = type; 231 setBlitProxyKey(gc.getProxyKey()); 232 } 233 234 @Override makeProxyFor(SurfaceData srcData)235 public SurfaceDataProxy makeProxyFor(SurfaceData srcData) { 236 return OGLSurfaceDataProxy.createProxy(srcData, graphicsConfig); 237 } 238 239 /** 240 * Returns the appropriate SurfaceType corresponding to the given OpenGL 241 * surface type constant (e.g. TEXTURE -> OpenGLTexture). 242 */ getCustomSurfaceType(int oglType)243 private static SurfaceType getCustomSurfaceType(int oglType) { 244 switch (oglType) { 245 case TEXTURE: 246 return OpenGLTexture; 247 case FBOBJECT: 248 return OpenGLSurfaceRTT; 249 default: 250 return OpenGLSurface; 251 } 252 } 253 254 /** 255 * Note: This should only be called from the QFT under the AWT lock. 256 * This method is kept separate from the initSurface() method below just 257 * to keep the code a bit cleaner. 258 */ initSurfaceNow(int width, int height)259 private void initSurfaceNow(int width, int height) { 260 boolean isOpaque = (getTransparency() == Transparency.OPAQUE); 261 boolean success = false; 262 263 switch (type) { 264 case TEXTURE: 265 success = initTexture(getNativeOps(), 266 isOpaque, isTexNonPow2Available(), 267 isTexRectAvailable(), 268 width, height); 269 break; 270 271 case FBOBJECT: 272 success = initFBObject(getNativeOps(), 273 isOpaque, isTexNonPow2Available(), 274 isTexRectAvailable(), 275 width, height); 276 break; 277 278 case FLIP_BACKBUFFER: 279 success = initFlipBackbuffer(getNativeOps()); 280 break; 281 282 default: 283 break; 284 } 285 286 if (!success) { 287 throw new OutOfMemoryError("can't create offscreen surface"); 288 } 289 } 290 291 /** 292 * Initializes the appropriate OpenGL offscreen surface based on the value 293 * of the type parameter. If the surface creation fails for any reason, 294 * an OutOfMemoryError will be thrown. 295 */ initSurface(final int width, final int height)296 protected void initSurface(final int width, final int height) { 297 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 298 rq.lock(); 299 try { 300 switch (type) { 301 case TEXTURE: 302 case FBOBJECT: 303 // need to make sure the context is current before 304 // creating the texture or fbobject 305 OGLContext.setScratchSurface(graphicsConfig); 306 break; 307 default: 308 break; 309 } 310 rq.flushAndInvokeNow(new Runnable() { 311 public void run() { 312 initSurfaceNow(width, height); 313 } 314 }); 315 } finally { 316 rq.unlock(); 317 } 318 } 319 320 /** 321 * Returns the OGLContext for the GraphicsConfig associated with this 322 * surface. 323 */ getContext()324 public final OGLContext getContext() { 325 return graphicsConfig.getContext(); 326 } 327 328 /** 329 * Returns the OGLGraphicsConfig associated with this surface. 330 */ getOGLGraphicsConfig()331 final OGLGraphicsConfig getOGLGraphicsConfig() { 332 return graphicsConfig; 333 } 334 335 /** 336 * Returns one of the surface type constants defined above. 337 */ getType()338 public final int getType() { 339 return type; 340 } 341 342 /** 343 * If this surface is backed by a texture object, returns the target 344 * for that texture (either GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB). 345 * Otherwise, this method will return zero. 346 */ getTextureTarget()347 public final int getTextureTarget() { 348 return getTextureTarget(getNativeOps()); 349 } 350 351 /** 352 * If this surface is backed by a texture object, returns the texture ID 353 * for that texture. 354 * Otherwise, this method will return zero. 355 */ getTextureID()356 public final int getTextureID() { 357 return getTextureID(getNativeOps()); 358 } 359 360 /** 361 * Returns native resource of specified {@code resType} associated with 362 * this surface. 363 * 364 * Specifically, for {@code OGLSurfaceData} this method returns the 365 * the following: 366 * <pre> 367 * TEXTURE - texture id 368 * </pre> 369 * 370 * Note: the resource returned by this method is only valid on the rendering 371 * thread. 372 * 373 * @return native resource of specified type or 0L if 374 * such resource doesn't exist or can not be retrieved. 375 * @see sun.java2d.pipe.hw.AccelSurface#getNativeResource 376 */ getNativeResource(int resType)377 public long getNativeResource(int resType) { 378 if (resType == TEXTURE) { 379 return getTextureID(); 380 } 381 return 0L; 382 } 383 getRaster(int x, int y, int w, int h)384 public Raster getRaster(int x, int y, int w, int h) { 385 throw new InternalError("not implemented yet"); 386 } 387 388 /** 389 * For now, we can only render LCD text if: 390 * - the fragment shader extension is available, and 391 * - the source color is opaque, and 392 * - blending is SrcOverNoEa or disabled 393 * - and the destination is opaque 394 * 395 * Eventually, we could enhance the native OGL text rendering code 396 * and remove the above restrictions, but that would require significantly 397 * more code just to support a few uncommon cases. 398 */ canRenderLCDText(SunGraphics2D sg2d)399 public boolean canRenderLCDText(SunGraphics2D sg2d) { 400 return 401 graphicsConfig.isCapPresent(CAPS_EXT_LCD_SHADER) && 402 sg2d.surfaceData.getTransparency() == Transparency.OPAQUE && 403 sg2d.paintState <= SunGraphics2D.PAINT_OPAQUECOLOR && 404 (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY || 405 (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA && canHandleComposite(sg2d.composite))); 406 } 407 canHandleComposite(Composite c)408 private boolean canHandleComposite(Composite c) { 409 if (c instanceof AlphaComposite) { 410 AlphaComposite ac = (AlphaComposite)c; 411 412 return ac.getRule() == AlphaComposite.SRC_OVER && ac.getAlpha() >= 1f; 413 } 414 return false; 415 } 416 validatePipe(SunGraphics2D sg2d)417 public void validatePipe(SunGraphics2D sg2d) { 418 TextPipe textpipe; 419 boolean validated = false; 420 421 // OGLTextRenderer handles both AA and non-AA text, but 422 // only works with the following modes: 423 // (Note: For LCD text we only enter this code path if 424 // canRenderLCDText() has already validated that the mode is 425 // CompositeType.SrcNoEa (opaque color), which will be subsumed 426 // by the CompositeType.SrcNoEa (any color) test below.) 427 428 if (/* CompositeType.SrcNoEa (any color) */ 429 (sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY && 430 sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) || 431 432 /* CompositeType.SrcOver (any color) */ 433 (sg2d.compositeState == SunGraphics2D.COMP_ALPHA && 434 sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && 435 (((AlphaComposite)sg2d.composite).getRule() == 436 AlphaComposite.SRC_OVER)) || 437 438 /* CompositeType.Xor (any color) */ 439 (sg2d.compositeState == SunGraphics2D.COMP_XOR && 440 sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR)) 441 { 442 textpipe = oglTextPipe; 443 } else { 444 // do this to initialize textpipe correctly; we will attempt 445 // to override the non-text pipes below 446 super.validatePipe(sg2d); 447 textpipe = sg2d.textpipe; 448 validated = true; 449 } 450 451 PixelToParallelogramConverter txPipe = null; 452 OGLRenderer nonTxPipe = null; 453 454 if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) { 455 if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) { 456 if (sg2d.compositeState <= SunGraphics2D.COMP_XOR) { 457 txPipe = oglTxRenderPipe; 458 nonTxPipe = oglRenderPipe; 459 } 460 } else if (sg2d.compositeState <= SunGraphics2D.COMP_ALPHA) { 461 if (OGLPaints.isValid(sg2d)) { 462 txPipe = oglTxRenderPipe; 463 nonTxPipe = oglRenderPipe; 464 } 465 // custom paints handled by super.validatePipe() below 466 } 467 } else { 468 if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR) { 469 if (graphicsConfig.isCapPresent(CAPS_PS30) && 470 (sg2d.imageComp == CompositeType.SrcOverNoEa || 471 sg2d.imageComp == CompositeType.SrcOver)) 472 { 473 if (!validated) { 474 super.validatePipe(sg2d); 475 validated = true; 476 } 477 PixelToParallelogramConverter aaConverter = 478 new PixelToParallelogramConverter(sg2d.shapepipe, 479 oglAAPgramPipe, 480 1.0/8.0, 0.499, 481 false); 482 sg2d.drawpipe = aaConverter; 483 sg2d.fillpipe = aaConverter; 484 sg2d.shapepipe = aaConverter; 485 } else if (sg2d.compositeState == SunGraphics2D.COMP_XOR) { 486 // install the solid pipes when AA and XOR are both enabled 487 txPipe = oglTxRenderPipe; 488 nonTxPipe = oglRenderPipe; 489 } 490 } 491 // other cases handled by super.validatePipe() below 492 } 493 494 if (txPipe != null) { 495 if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) { 496 sg2d.drawpipe = txPipe; 497 sg2d.fillpipe = txPipe; 498 } else if (sg2d.strokeState != SunGraphics2D.STROKE_THIN) { 499 sg2d.drawpipe = txPipe; 500 sg2d.fillpipe = nonTxPipe; 501 } else { 502 sg2d.drawpipe = nonTxPipe; 503 sg2d.fillpipe = nonTxPipe; 504 } 505 // Note that we use the transforming pipe here because it 506 // will examine the shape and possibly perform an optimized 507 // operation if it can be simplified. The simplifications 508 // will be valid for all STROKE and TRANSFORM types. 509 sg2d.shapepipe = txPipe; 510 } else { 511 if (!validated) { 512 super.validatePipe(sg2d); 513 } 514 } 515 516 // install the text pipe based on our earlier decision 517 sg2d.textpipe = textpipe; 518 519 // always override the image pipe with the specialized OGL pipe 520 sg2d.imagepipe = oglImagePipe; 521 } 522 523 @Override getMaskFill(SunGraphics2D sg2d)524 protected MaskFill getMaskFill(SunGraphics2D sg2d) { 525 if (sg2d.paintState > SunGraphics2D.PAINT_ALPHACOLOR) { 526 /* 527 * We can only accelerate non-Color MaskFill operations if 528 * all of the following conditions hold true: 529 * - there is an implementation for the given paintState 530 * - the current Paint can be accelerated for this destination 531 * - multitexturing is available (since we need to modulate 532 * the alpha mask texture with the paint texture) 533 * 534 * In all other cases, we return null, in which case the 535 * validation code will choose a more general software-based loop. 536 */ 537 if (!OGLPaints.isValid(sg2d) || 538 !graphicsConfig.isCapPresent(CAPS_MULTITEXTURE)) 539 { 540 return null; 541 } 542 } 543 return super.getMaskFill(sg2d); 544 } 545 546 @Override copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy)547 public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, 548 int dx, int dy) { 549 if (sg2d.compositeState >= SunGraphics2D.COMP_XOR) { 550 return false; 551 } 552 oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy); 553 return true; 554 } 555 flush()556 public void flush() { 557 invalidate(); 558 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 559 rq.lock(); 560 try { 561 // make sure we have a current context before 562 // disposing the native resources (e.g. texture object) 563 OGLContext.setScratchSurface(graphicsConfig); 564 565 RenderBuffer buf = rq.getBuffer(); 566 rq.ensureCapacityAndAlignment(12, 4); 567 buf.putInt(FLUSH_SURFACE); 568 buf.putLong(getNativeOps()); 569 570 // this call is expected to complete synchronously, so flush now 571 rq.flushNow(); 572 } finally { 573 rq.unlock(); 574 } 575 } 576 577 /** 578 * Disposes the native resources associated with the given OGLSurfaceData 579 * (referenced by the pData parameter). This method is invoked from 580 * the native Dispose() method from the Disposer thread when the 581 * Java-level OGLSurfaceData object is about to go away. Note that we 582 * also pass a reference to the OGLGraphicsConfig 583 * for the purposes of making a context current. 584 */ dispose(long pData, OGLGraphicsConfig gc)585 static void dispose(long pData, OGLGraphicsConfig gc) { 586 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 587 rq.lock(); 588 try { 589 // make sure we have a current context before 590 // disposing the native resources (e.g. texture object) 591 OGLContext.setScratchSurface(gc); 592 593 RenderBuffer buf = rq.getBuffer(); 594 rq.ensureCapacityAndAlignment(12, 4); 595 buf.putInt(DISPOSE_SURFACE); 596 buf.putLong(pData); 597 598 // this call is expected to complete synchronously, so flush now 599 rq.flushNow(); 600 } finally { 601 rq.unlock(); 602 } 603 } 604 swapBuffers(long window)605 static void swapBuffers(long window) { 606 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 607 rq.lock(); 608 try { 609 RenderBuffer buf = rq.getBuffer(); 610 rq.ensureCapacityAndAlignment(12, 4); 611 buf.putInt(SWAP_BUFFERS); 612 buf.putLong(window); 613 rq.flushNow(); 614 } finally { 615 rq.unlock(); 616 } 617 } 618 619 /** 620 * Returns true if OpenGL textures can have non-power-of-two dimensions 621 * when using the basic GL_TEXTURE_2D target. 622 */ isTexNonPow2Available()623 boolean isTexNonPow2Available() { 624 return graphicsConfig.isCapPresent(CAPS_TEXNONPOW2); 625 } 626 627 /** 628 * Returns true if OpenGL textures can have non-power-of-two dimensions 629 * when using the GL_TEXTURE_RECTANGLE_ARB target (only available when the 630 * GL_ARB_texture_rectangle extension is present). 631 */ isTexRectAvailable()632 boolean isTexRectAvailable() { 633 return graphicsConfig.isCapPresent(CAPS_EXT_TEXRECT); 634 } 635 getNativeBounds()636 public Rectangle getNativeBounds() { 637 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 638 rq.lock(); 639 try { 640 return new Rectangle(nativeWidth, nativeHeight); 641 } finally { 642 rq.unlock(); 643 } 644 } 645 646 /** 647 * Returns true if the surface is an on-screen window surface or 648 * a FBO texture attached to an on-screen CALayer. 649 * 650 * Needed by Mac OS X port. 651 */ isOnScreen()652 boolean isOnScreen() { 653 return getType() == WINDOW; 654 } 655 } 656