Showing the changes to java/pkg/sun/java2d/opengl (15 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,762 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2007, 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.Composite; | |
| 29 | +import java.awt.Transparency; | |
| 30 | +import java.awt.geom.AffineTransform; | |
| 31 | +import java.awt.image.AffineTransformOp; | |
| 32 | +import java.awt.image.BufferedImage; | |
| 33 | +import java.awt.image.BufferedImageOp; | |
| 34 | +import java.lang.ref.WeakReference; | |
| 35 | +import sun.java2d.SurfaceData; | |
| 36 | +import sun.java2d.loops.Blit; | |
| 37 | +import sun.java2d.loops.CompositeType; | |
| 38 | +import sun.java2d.loops.GraphicsPrimitive; | |
| 39 | +import sun.java2d.loops.GraphicsPrimitiveMgr; | |
| 40 | +import sun.java2d.loops.ScaledBlit; | |
| 41 | +import sun.java2d.loops.SurfaceType; | |
| 42 | +import sun.java2d.loops.TransformBlit; | |
| 43 | +import sun.java2d.pipe.Region; | |
| 44 | +import sun.java2d.pipe.RenderBuffer; | |
| 45 | +import sun.java2d.pipe.RenderQueue; | |
| 46 | +import static sun.java2d.pipe.BufferedOpCodes.*; | |
| 47 | + | |
| 48 | +class OGLBlitLoops { | |
| 49 | + | |
| 50 | + static void register() { | |
| 51 | + Blit blitIntArgbPreToSurface = | |
| 52 | + new OGLSwToSurfaceBlit(SurfaceType.IntArgbPre, | |
| 53 | + OGLSurfaceData.PF_INT_ARGB_PRE); | |
| 54 | + Blit blitIntArgbPreToTexture = | |
| 55 | + new OGLSwToTextureBlit(SurfaceType.IntArgbPre, | |
| 56 | + OGLSurfaceData.PF_INT_ARGB_PRE); | |
| 57 | + | |
| 58 | + GraphicsPrimitive[] primitives = { | |
| 59 | + // surface->surface ops | |
| 60 | + new OGLSurfaceToSurfaceBlit(), | |
| 61 | + new OGLSurfaceToSurfaceScale(), | |
| 62 | + new OGLSurfaceToSurfaceTransform(), | |
| 63 | + | |
| 64 | + // render-to-texture surface->surface ops | |
| 65 | + new OGLRTTSurfaceToSurfaceBlit(), | |
| 66 | + new OGLRTTSurfaceToSurfaceScale(), | |
| 67 | + new OGLRTTSurfaceToSurfaceTransform(), | |
| 68 | + | |
| 69 | + // surface->sw ops | |
| 70 | + new OGLSurfaceToSwBlit(SurfaceType.IntArgb, | |
| 71 | + OGLSurfaceData.PF_INT_ARGB), | |
| 72 | + | |
| 73 | + // sw->surface ops | |
| 74 | + blitIntArgbPreToSurface, | |
| 75 | + new OGLSwToSurfaceBlit(SurfaceType.IntRgb, | |
| 76 | + OGLSurfaceData.PF_INT_RGB), | |
| 77 | + new OGLSwToSurfaceBlit(SurfaceType.IntRgbx, | |
| 78 | + OGLSurfaceData.PF_INT_RGBX), | |
| 79 | + new OGLSwToSurfaceBlit(SurfaceType.IntBgr, | |
| 80 | + OGLSurfaceData.PF_INT_BGR), | |
| 81 | + new OGLSwToSurfaceBlit(SurfaceType.IntBgrx, | |
| 82 | + OGLSurfaceData.PF_INT_BGRX), | |
| 83 | + new OGLSwToSurfaceBlit(SurfaceType.ThreeByteBgr, | |
| 84 | + OGLSurfaceData.PF_3BYTE_BGR), | |
| 85 | + new OGLSwToSurfaceBlit(SurfaceType.Ushort565Rgb, | |
| 86 | + OGLSurfaceData.PF_USHORT_565_RGB), | |
| 87 | + new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgb, | |
| 88 | + OGLSurfaceData.PF_USHORT_555_RGB), | |
| 89 | + new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx, | |
| 90 | + OGLSurfaceData.PF_USHORT_555_RGBX), | |
| 91 | + new OGLSwToSurfaceBlit(SurfaceType.ByteGray, | |
| 92 | + OGLSurfaceData.PF_BYTE_GRAY), | |
| 93 | + new OGLSwToSurfaceBlit(SurfaceType.UshortGray, | |
| 94 | + OGLSurfaceData.PF_USHORT_GRAY), | |
| 95 | + new OGLGeneralBlit(OGLSurfaceData.OpenGLSurface, | |
| 96 | + CompositeType.AnyAlpha, | |
| 97 | + blitIntArgbPreToSurface), | |
| 98 | + | |
| 99 | + new OGLSwToSurfaceScale(SurfaceType.IntRgb, | |
| 100 | + OGLSurfaceData.PF_INT_RGB), | |
| 101 | + new OGLSwToSurfaceScale(SurfaceType.IntRgbx, | |
| 102 | + OGLSurfaceData.PF_INT_RGBX), | |
| 103 | + new OGLSwToSurfaceScale(SurfaceType.IntBgr, | |
| 104 | + OGLSurfaceData.PF_INT_BGR), | |
| 105 | + new OGLSwToSurfaceScale(SurfaceType.IntBgrx, | |
| 106 | + OGLSurfaceData.PF_INT_BGRX), | |
| 107 | + new OGLSwToSurfaceScale(SurfaceType.ThreeByteBgr, | |
| 108 | + OGLSurfaceData.PF_3BYTE_BGR), | |
| 109 | + new OGLSwToSurfaceScale(SurfaceType.Ushort565Rgb, | |
| 110 | + OGLSurfaceData.PF_USHORT_565_RGB), | |
| 111 | + new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgb, | |
| 112 | + OGLSurfaceData.PF_USHORT_555_RGB), | |
| 113 | + new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgbx, | |
| 114 | + OGLSurfaceData.PF_USHORT_555_RGBX), | |
| 115 | + new OGLSwToSurfaceScale(SurfaceType.ByteGray, | |
| 116 | + OGLSurfaceData.PF_BYTE_GRAY), | |
| 117 | + new OGLSwToSurfaceScale(SurfaceType.UshortGray, | |
| 118 | + OGLSurfaceData.PF_USHORT_GRAY), | |
| 119 | + new OGLSwToSurfaceScale(SurfaceType.IntArgbPre, | |
| 120 | + OGLSurfaceData.PF_INT_ARGB_PRE), | |
| 121 | + | |
| 122 | + new OGLSwToSurfaceTransform(SurfaceType.IntRgb, | |
| 123 | + OGLSurfaceData.PF_INT_RGB), | |
| 124 | + new OGLSwToSurfaceTransform(SurfaceType.IntRgbx, | |
| 125 | + OGLSurfaceData.PF_INT_RGBX), | |
| 126 | + new OGLSwToSurfaceTransform(SurfaceType.IntBgr, | |
| 127 | + OGLSurfaceData.PF_INT_BGR), | |
| 128 | + new OGLSwToSurfaceTransform(SurfaceType.IntBgrx, | |
| 129 | + OGLSurfaceData.PF_INT_BGRX), | |
| 130 | + new OGLSwToSurfaceTransform(SurfaceType.ThreeByteBgr, | |
| 131 | + OGLSurfaceData.PF_3BYTE_BGR), | |
| 132 | + new OGLSwToSurfaceTransform(SurfaceType.Ushort565Rgb, | |
| 133 | + OGLSurfaceData.PF_USHORT_565_RGB), | |
| 134 | + new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgb, | |
| 135 | + OGLSurfaceData.PF_USHORT_555_RGB), | |
| 136 | + new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx, | |
| 137 | + OGLSurfaceData.PF_USHORT_555_RGBX), | |
| 138 | + new OGLSwToSurfaceTransform(SurfaceType.ByteGray, | |
| 139 | + OGLSurfaceData.PF_BYTE_GRAY), | |
| 140 | + new OGLSwToSurfaceTransform(SurfaceType.UshortGray, | |
| 141 | + OGLSurfaceData.PF_USHORT_GRAY), | |
| 142 | + new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, | |
| 143 | + OGLSurfaceData.PF_INT_ARGB_PRE), | |
| 144 | + | |
| 145 | + // texture->surface ops | |
| 146 | + new OGLTextureToSurfaceBlit(), | |
| 147 | + new OGLTextureToSurfaceScale(), | |
| 148 | + new OGLTextureToSurfaceTransform(), | |
| 149 | + | |
| 150 | + // sw->texture ops | |
| 151 | + blitIntArgbPreToTexture, | |
| 152 | + new OGLSwToTextureBlit(SurfaceType.IntRgb, | |
| 153 | + OGLSurfaceData.PF_INT_RGB), | |
| 154 | + new OGLSwToTextureBlit(SurfaceType.IntRgbx, | |
| 155 | + OGLSurfaceData.PF_INT_RGBX), | |
| 156 | + new OGLSwToTextureBlit(SurfaceType.IntBgr, | |
| 157 | + OGLSurfaceData.PF_INT_BGR), | |
| 158 | + new OGLSwToTextureBlit(SurfaceType.IntBgrx, | |
| 159 | + OGLSurfaceData.PF_INT_BGRX), | |
| 160 | + new OGLSwToTextureBlit(SurfaceType.ThreeByteBgr, | |
| 161 | + OGLSurfaceData.PF_3BYTE_BGR), | |
| 162 | + new OGLSwToTextureBlit(SurfaceType.Ushort565Rgb, | |
| 163 | + OGLSurfaceData.PF_USHORT_565_RGB), | |
| 164 | + new OGLSwToTextureBlit(SurfaceType.Ushort555Rgb, | |
| 165 | + OGLSurfaceData.PF_USHORT_555_RGB), | |
| 166 | + new OGLSwToTextureBlit(SurfaceType.Ushort555Rgbx, | |
| 167 | + OGLSurfaceData.PF_USHORT_555_RGBX), | |
| 168 | + new OGLSwToTextureBlit(SurfaceType.ByteGray, | |
| 169 | + OGLSurfaceData.PF_BYTE_GRAY), | |
| 170 | + new OGLSwToTextureBlit(SurfaceType.UshortGray, | |
| 171 | + OGLSurfaceData.PF_USHORT_GRAY), | |
| 172 | + new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture, | |
| 173 | + CompositeType.SrcNoEa, | |
| 174 | + blitIntArgbPreToTexture), | |
| 175 | + }; | |
| 176 | + GraphicsPrimitiveMgr.register(primitives); | |
| 177 | + } | |
| 178 | + | |
| 179 | + /** | |
| 180 | + * The following offsets are used to pack the parameters in | |
| 181 | + * createPackedParams(). (They are also used at the native level when | |
| 182 | + * unpacking the params.) | |
| 183 | + */ | |
| 184 | + private static final int OFFSET_SRCTYPE = 16; | |
| 185 | + private static final int OFFSET_HINT = 8; | |
| 186 | + private static final int OFFSET_TEXTURE = 3; | |
| 187 | + private static final int OFFSET_RTT = 2; | |
| 188 | + private static final int OFFSET_XFORM = 1; | |
| 189 | + private static final int OFFSET_ISOBLIT = 0; | |
| 190 | + | |
| 191 | + /** | |
| 192 | + * Packs the given parameters into a single int value in order to save | |
| 193 | + * space on the rendering queue. | |
| 194 | + */ | |
| 195 | + private static int createPackedParams(boolean isoblit, boolean texture, | |
| 196 | + boolean rtt, boolean xform, | |
| 197 | + int hint, int srctype) | |
| 198 | + { | |
| 199 | + return | |
| 200 | + ((srctype << OFFSET_SRCTYPE) | | |
| 201 | + (hint << OFFSET_HINT ) | | |
| 202 | + ((texture ? 1 : 0) << OFFSET_TEXTURE) | | |
| 203 | + ((rtt ? 1 : 0) << OFFSET_RTT ) | | |
| 204 | + ((xform ? 1 : 0) << OFFSET_XFORM ) | | |
| 205 | + ((isoblit ? 1 : 0) << OFFSET_ISOBLIT)); | |
| 206 | + } | |
| 207 | + | |
| 208 | + /** | |
| 209 | + * Enqueues a BLIT operation with the given parameters. Note that the | |
| 210 | + * RenderQueue lock must be held before calling this method. | |
| 211 | + */ | |
| 212 | + private static void enqueueBlit(RenderQueue rq, | |
| 213 | + SurfaceData src, SurfaceData dst, | |
| 214 | + int packedParams, | |
| 215 | + int sx1, int sy1, | |
| 216 | + int sx2, int sy2, | |
| 217 | + double dx1, double dy1, | |
| 218 | + double dx2, double dy2) | |
| 219 | + { | |
| 220 | + // assert rq.lock.isHeldByCurrentThread(); | |
| 221 | + RenderBuffer buf = rq.getBuffer(); | |
| 222 | + rq.ensureCapacityAndAlignment(72, 24); | |
| 223 | + buf.putInt(BLIT); | |
| 224 | + buf.putInt(packedParams); | |
| 225 | + buf.putInt(sx1).putInt(sy1); | |
| 226 | + buf.putInt(sx2).putInt(sy2); | |
| 227 | + buf.putDouble(dx1).putDouble(dy1); | |
| 228 | + buf.putDouble(dx2).putDouble(dy2); | |
| 229 | + buf.putLong(src.getNativeOps()); | |
| 230 | + buf.putLong(dst.getNativeOps()); | |
| 231 | + } | |
| 232 | + | |
| 233 | + static void Blit(SurfaceData srcData, SurfaceData dstData, | |
| 234 | + Composite comp, Region clip, | |
| 235 | + AffineTransform xform, int hint, | |
| 236 | + int sx1, int sy1, | |
| 237 | + int sx2, int sy2, | |
| 238 | + double dx1, double dy1, | |
| 239 | + double dx2, double dy2, | |
| 240 | + int srctype, boolean texture) | |
| 241 | + { | |
| 242 | + int ctxflags = 0; | |
| 243 | + if (srcData.getTransparency() == Transparency.OPAQUE) { | |
| 244 | + ctxflags |= OGLContext.SRC_IS_OPAQUE; | |
| 245 | + } | |
| 246 | + | |
| 247 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 248 | + rq.lock(); | |
| 249 | + try { | |
| 250 | + // make sure the RenderQueue keeps a hard reference to the | |
| 251 | + // source (sysmem) SurfaceData to prevent it from being | |
| 252 | + // disposed while the operation is processed on the QFT | |
| 253 | + rq.addReference(srcData); | |
| 254 | + | |
| 255 | + OGLSurfaceData oglDst = (OGLSurfaceData)dstData; | |
| 256 | + if (texture) { | |
| 257 | + // make sure we have a current context before uploading | |
| 258 | + // the sysmem data to the texture object | |
| 259 | + OGLGraphicsConfig gc = oglDst.getOGLGraphicsConfig(); | |
| 260 | + OGLContext.setScratchSurface(gc); | |
| 261 | + } else { | |
| 262 | + OGLContext.validateContext(oglDst, oglDst, | |
| 263 | + clip, comp, xform, null, null, | |
| 264 | + ctxflags); | |
| 265 | + } | |
| 266 | + | |
| 267 | + int packedParams = createPackedParams(false, texture, | |
| 268 | + false, xform != null, | |
| 269 | + hint, srctype); | |
| 270 | + enqueueBlit(rq, srcData, dstData, | |
| 271 | + packedParams, | |
| 272 | + sx1, sy1, sx2, sy2, | |
| 273 | + dx1, dy1, dx2, dy2); | |
| 274 | + | |
| 275 | + // always flush immediately, since we (currently) have no means | |
| 276 | + // of tracking changes to the system memory surface | |
| 277 | + rq.flushNow(); | |
| 278 | + } finally { | |
| 279 | + rq.unlock(); | |
| 280 | + } | |
| 281 | + } | |
| 282 | + | |
| 283 | + /** | |
| 284 | + * Note: The srcImg and biop parameters are only used when invoked | |
| 285 | + * from the OGLBufImgOps.renderImageWithOp() method; in all other cases, | |
| 286 | + * this method can be called with null values for those two parameters, | |
| 287 | + * and they will be effectively ignored. | |
| 288 | + */ | |
| 289 | + static void IsoBlit(SurfaceData srcData, SurfaceData dstData, | |
| 290 | + BufferedImage srcImg, BufferedImageOp biop, | |
| 291 | + Composite comp, Region clip, | |
| 292 | + AffineTransform xform, int hint, | |
| 293 | + int sx1, int sy1, | |
| 294 | + int sx2, int sy2, | |
| 295 | + double dx1, double dy1, | |
| 296 | + double dx2, double dy2, | |
| 297 | + boolean texture) | |
| 298 | + { | |
| 299 | + int ctxflags = 0; | |
| 300 | + if (srcData.getTransparency() == Transparency.OPAQUE) { | |
| 301 | + ctxflags |= OGLContext.SRC_IS_OPAQUE; | |
| 302 | + } | |
| 303 | + | |
| 304 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 305 | + rq.lock(); | |
| 306 | + try { | |
| 307 | + OGLSurfaceData oglSrc = (OGLSurfaceData)srcData; | |
| 308 | + OGLSurfaceData oglDst = (OGLSurfaceData)dstData; | |
| 309 | + int srctype = oglSrc.getType(); | |
| 310 | + boolean rtt; | |
| 311 | + OGLSurfaceData srcCtxData; | |
| 312 | + if (srctype == OGLSurfaceData.TEXTURE) { | |
| 313 | + // the source is a regular texture object; we substitute | |
| 314 | + // the destination surface for the purposes of making a | |
| 315 | + // context current | |
| 316 | + rtt = false; | |
| 317 | + srcCtxData = oglDst; | |
| 318 | + } else { | |
| 319 | + // the source is a pbuffer, backbuffer, or render-to-texture | |
| 320 | + // surface; we set rtt to true to differentiate this kind | |
| 321 | + // of surface from a regular texture object | |
| 322 | + rtt = true; | |
| 323 | + if (srctype == OGLSurfaceData.FBOBJECT) { | |
| 324 | + srcCtxData = oglDst; | |
| 325 | + } else { | |
| 326 | + srcCtxData = oglSrc; | |
| 327 | + } | |
| 328 | + } | |
| 329 | + | |
| 330 | + OGLContext.validateContext(srcCtxData, oglDst, | |
| 331 | + clip, comp, xform, null, null, | |
| 332 | + ctxflags); | |
| 333 | + | |
| 334 | + if (biop != null) { | |
| 335 | + OGLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop); | |
| 336 | + } | |
| 337 | + | |
| 338 | + int packedParams = createPackedParams(true, texture, | |
| 339 | + rtt, xform != null, | |
| 340 | + hint, 0 /*unused*/); | |
| 341 | + enqueueBlit(rq, srcData, dstData, | |
| 342 | + packedParams, | |
| 343 | + sx1, sy1, sx2, sy2, | |
| 344 | + dx1, dy1, dx2, dy2); | |
| 345 | + | |
| 346 | + if (biop != null) { | |
| 347 | + OGLBufImgOps.disableBufImgOp(rq, biop); | |
| 348 | + } | |
| 349 | + | |
| 350 | + if (rtt && (oglDst.getType() == OGLSurfaceData.WINDOW)) { | |
| 351 | + // we only have to flush immediately when copying from a | |
| 352 | + // (non-texture) surface to the screen; otherwise Swing apps | |
| 353 | + // might appear unresponsive until the auto-flush completes | |
| 354 | + rq.flushNow(); | |
| 355 | + } | |
| 356 | + } finally { | |
| 357 | + rq.unlock(); | |
| 358 | + } | |
| 359 | + } | |
| 360 | +} | |
| 361 | + | |
| 362 | +class OGLSurfaceToSurfaceBlit extends Blit { | |
| 363 | + | |
| 364 | + OGLSurfaceToSurfaceBlit() { | |
| 365 | + super(OGLSurfaceData.OpenGLSurface, | |
| 366 | + CompositeType.AnyAlpha, | |
| 367 | + OGLSurfaceData.OpenGLSurface); | |
| 368 | + } | |
| 369 | + | |
| 370 | + public void Blit(SurfaceData src, SurfaceData dst, | |
| 371 | + Composite comp, Region clip, | |
| 372 | + int sx, int sy, int dx, int dy, int w, int h) | |
| 373 | + { | |
| 374 | + OGLBlitLoops.IsoBlit(src, dst, | |
| 375 | + null, null, | |
| 376 | + comp, clip, null, | |
| 377 | + AffineTransformOp.TYPE_NEAREST_NEIGHBOR, | |
| 378 | + sx, sy, sx+w, sy+h, | |
| 379 | + dx, dy, dx+w, dy+h, | |
| 380 | + false); | |
| 381 | + } | |
| 382 | +} | |
| 383 | + | |
| 384 | +class OGLSurfaceToSurfaceScale extends ScaledBlit { | |
| 385 | + | |
| 386 | + OGLSurfaceToSurfaceScale() { | |
| 387 | + super(OGLSurfaceData.OpenGLSurface, | |
| 388 | + CompositeType.AnyAlpha, | |
| 389 | + OGLSurfaceData.OpenGLSurface); | |
| 390 | + } | |
| 391 | + | |
| 392 | + public void Scale(SurfaceData src, SurfaceData dst, | |
| 393 | + Composite comp, Region clip, | |
| 394 | + int sx1, int sy1, | |
| 395 | + int sx2, int sy2, | |
| 396 | + double dx1, double dy1, | |
| 397 | + double dx2, double dy2) | |
| 398 | + { | |
| 399 | + OGLBlitLoops.IsoBlit(src, dst, | |
| 400 | + null, null, | |
| 401 | + comp, clip, null, | |
| 402 | + AffineTransformOp.TYPE_NEAREST_NEIGHBOR, | |
| 403 | + sx1, sy1, sx2, sy2, | |
| 404 | + dx1, dy1, dx2, dy2, | |
| 405 | + false); | |
| 406 | + } | |
| 407 | +} | |
| 408 | + | |
| 409 | +class OGLSurfaceToSurfaceTransform extends TransformBlit { | |
| 410 | + | |
| 411 | + OGLSurfaceToSurfaceTransform() { | |
| 412 | + super(OGLSurfaceData.OpenGLSurface, | |
| 413 | + CompositeType.AnyAlpha, | |
| 414 | + OGLSurfaceData.OpenGLSurface); | |
| 415 | + } | |
| 416 | + | |
| 417 | + public void Transform(SurfaceData src, SurfaceData dst, | |
| 418 | + Composite comp, Region clip, | |
| 419 | + AffineTransform at, int hint, | |
| 420 | + int sx, int sy, int dx, int dy, | |
| 421 | + int w, int h) | |
| 422 | + { | |
| 423 | + OGLBlitLoops.IsoBlit(src, dst, | |
| 424 | + null, null, | |
| 425 | + comp, clip, at, hint, | |
| 426 | + sx, sy, sx+w, sy+h, | |
| 427 | + dx, dy, dx+w, dy+h, | |
| 428 | + false); | |
| 429 | + } | |
| 430 | +} | |
| 431 | + | |
| 432 | +class OGLRTTSurfaceToSurfaceBlit extends Blit { | |
| 433 | + | |
| 434 | + OGLRTTSurfaceToSurfaceBlit() { | |
| 435 | + super(OGLSurfaceData.OpenGLSurfaceRTT, | |
| 436 | + CompositeType.AnyAlpha, | |
| 437 | + OGLSurfaceData.OpenGLSurface); | |
| 438 | + } | |
| 439 | + | |
| 440 | + public void Blit(SurfaceData src, SurfaceData dst, | |
| 441 | + Composite comp, Region clip, | |
| 442 | + int sx, int sy, int dx, int dy, int w, int h) | |
| 443 | + { | |
| 444 | + OGLBlitLoops.IsoBlit(src, dst, | |
| 445 | + null, null, | |
| 446 | + comp, clip, null, | |
| 447 | + AffineTransformOp.TYPE_NEAREST_NEIGHBOR, | |
| 448 | + sx, sy, sx+w, sy+h, | |
| 449 | + dx, dy, dx+w, dy+h, | |
| 450 | + true); | |
| 451 | + } | |
| 452 | +} | |
| 453 | + | |
| 454 | +class OGLRTTSurfaceToSurfaceScale extends ScaledBlit { | |
| 455 | + | |
| 456 | + OGLRTTSurfaceToSurfaceScale() { | |
| 457 | + super(OGLSurfaceData.OpenGLSurfaceRTT, | |
| 458 | + CompositeType.AnyAlpha, | |
| 459 | + OGLSurfaceData.OpenGLSurface); | |
| 460 | + } | |
| 461 | + | |
| 462 | + public void Scale(SurfaceData src, SurfaceData dst, | |
| 463 | + Composite comp, Region clip, | |
| 464 | + int sx1, int sy1, | |
| 465 | + int sx2, int sy2, | |
| 466 | + double dx1, double dy1, | |
| 467 | + double dx2, double dy2) | |
| 468 | + { | |
| 469 | + OGLBlitLoops.IsoBlit(src, dst, | |
| 470 | + null, null, | |
| 471 | + comp, clip, null, | |
| 472 | + AffineTransformOp.TYPE_NEAREST_NEIGHBOR, | |
| 473 | + sx1, sy1, sx2, sy2, | |
| 474 | + dx1, dy1, dx2, dy2, | |
| 475 | + true); | |
| 476 | + } | |
| 477 | +} | |
| 478 | + | |
| 479 | +class OGLRTTSurfaceToSurfaceTransform extends TransformBlit { | |
| 480 | + | |
| 481 | + OGLRTTSurfaceToSurfaceTransform() { | |
| 482 | + super(OGLSurfaceData.OpenGLSurfaceRTT, | |
| 483 | + CompositeType.AnyAlpha, | |
| 484 | + OGLSurfaceData.OpenGLSurface); | |
| 485 | + } | |
| 486 | + | |
| 487 | + public void Transform(SurfaceData src, SurfaceData dst, | |
| 488 | + Composite comp, Region clip, | |
| 489 | + AffineTransform at, int hint, | |
| 490 | + int sx, int sy, int dx, int dy, int w, int h) | |
| 491 | + { | |
| 492 | + OGLBlitLoops.IsoBlit(src, dst, | |
| 493 | + null, null, | |
| 494 | + comp, clip, at, hint, | |
| 495 | + sx, sy, sx+w, sy+h, | |
| 496 | + dx, dy, dx+w, dy+h, | |
| 497 | + true); | |
| 498 | + } | |
| 499 | +} | |
| 500 | + | |
| 501 | +class OGLSurfaceToSwBlit extends Blit { | |
| 502 | + | |
| 503 | + private int typeval; | |
| 504 | + | |
| 505 | + // REMIND: destination will actually be opaque/premultiplied... | |
| 506 | + OGLSurfaceToSwBlit(SurfaceType dstType, int typeval) { | |
| 507 | + super(OGLSurfaceData.OpenGLSurface, | |
| 508 | + CompositeType.SrcNoEa, | |
| 509 | + dstType); | |
| 510 | + this.typeval = typeval; | |
| 511 | + } | |
| 512 | + | |
| 513 | + public void Blit(SurfaceData src, SurfaceData dst, | |
| 514 | + Composite comp, Region clip, | |
| 515 | + int sx, int sy, int dx, int dy, | |
| 516 | + int w, int h) | |
| 517 | + { | |
| 518 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 519 | + rq.lock(); | |
| 520 | + try { | |
| 521 | + // make sure the RenderQueue keeps a hard reference to the | |
| 522 | + // destination (sysmem) SurfaceData to prevent it from being | |
| 523 | + // disposed while the operation is processed on the QFT | |
| 524 | + rq.addReference(dst); | |
| 525 | + | |
| 526 | + RenderBuffer buf = rq.getBuffer(); | |
| 527 | + OGLContext.validateContext((OGLSurfaceData)src); | |
| 528 | + | |
| 529 | + rq.ensureCapacityAndAlignment(48, 32); | |
| 530 | + buf.putInt(SURFACE_TO_SW_BLIT); | |
| 531 | + buf.putInt(sx).putInt(sy); | |
| 532 | + buf.putInt(dx).putInt(dy); | |
| 533 | + buf.putInt(w).putInt(h); | |
| 534 | + buf.putInt(typeval); | |
| 535 | + buf.putLong(src.getNativeOps()); | |
| 536 | + buf.putLong(dst.getNativeOps()); | |
| 537 | + | |
| 538 | + // always flush immediately | |
| 539 | + rq.flushNow(); | |
| 540 | + } finally { | |
| 541 | + rq.unlock(); | |
| 542 | + } | |
| 543 | + } | |
| 544 | +} | |
| 545 | + | |
| 546 | +class OGLSwToSurfaceBlit extends Blit { | |
| 547 | + | |
| 548 | + private int typeval; | |
| 549 | + | |
| 550 | + OGLSwToSurfaceBlit(SurfaceType srcType, int typeval) { | |
| 551 | + super(srcType, | |
| 552 | + CompositeType.AnyAlpha, | |
| 553 | + OGLSurfaceData.OpenGLSurface); | |
| 554 | + this.typeval = typeval; | |
| 555 | + } | |
| 556 | + | |
| 557 | + public void Blit(SurfaceData src, SurfaceData dst, | |
| 558 | + Composite comp, Region clip, | |
| 559 | + int sx, int sy, int dx, int dy, int w, int h) | |
| 560 | + { | |
| 561 | + OGLBlitLoops.Blit(src, dst, | |
| 562 | + comp, clip, null, | |
| 563 | + AffineTransformOp.TYPE_NEAREST_NEIGHBOR, | |
| 564 | + sx, sy, sx+w, sy+h, | |
| 565 | + dx, dy, dx+w, dy+h, | |
| 566 | + typeval, false); | |
| 567 | + } | |
| 568 | +} | |
| 569 | + | |
| 570 | +class OGLSwToSurfaceScale extends ScaledBlit { | |
| 571 | + | |
| 572 | + private int typeval; | |
| 573 | + | |
| 574 | + OGLSwToSurfaceScale(SurfaceType srcType, int typeval) { | |
| 575 | + super(srcType, | |
| 576 | + CompositeType.AnyAlpha, | |
| 577 | + OGLSurfaceData.OpenGLSurface); | |
| 578 | + this.typeval = typeval; | |
| 579 | + } | |
| 580 | + | |
| 581 | + public void Scale(SurfaceData src, SurfaceData dst, | |
| 582 | + Composite comp, Region clip, | |
| 583 | + int sx1, int sy1, | |
| 584 | + int sx2, int sy2, | |
| 585 | + double dx1, double dy1, | |
| 586 | + double dx2, double dy2) | |
| 587 | + { | |
| 588 | + OGLBlitLoops.Blit(src, dst, | |
| 589 | + comp, clip, null, | |
| 590 | + AffineTransformOp.TYPE_NEAREST_NEIGHBOR, | |
| 591 | + sx1, sy1, sx2, sy2, | |
| 592 | + dx1, dy1, dx2, dy2, | |
| 593 | + typeval, false); | |
| 594 | + } | |
| 595 | +} | |
| 596 | + | |
| 597 | +class OGLSwToSurfaceTransform extends TransformBlit { | |
| 598 | + | |
| 599 | + private int typeval; | |
| 600 | + | |
| 601 | + OGLSwToSurfaceTransform(SurfaceType srcType, int typeval) { | |
| 602 | + super(srcType, | |
| 603 | + CompositeType.AnyAlpha, | |
| 604 | + OGLSurfaceData.OpenGLSurface); | |
| 605 | + this.typeval = typeval; | |
| 606 | + } | |
| 607 | + | |
| 608 | + public void Transform(SurfaceData src, SurfaceData dst, | |
| 609 | + Composite comp, Region clip, | |
| 610 | + AffineTransform at, int hint, | |
| 611 | + int sx, int sy, int dx, int dy, int w, int h) | |
| 612 | + { | |
| 613 | + OGLBlitLoops.Blit(src, dst, | |
| 614 | + comp, clip, at, hint, | |
| 615 | + sx, sy, sx+w, sy+h, | |
| 616 | + dx, dy, dx+w, dy+h, | |
| 617 | + typeval, false); | |
| 618 | + } | |
| 619 | +} | |
| 620 | + | |
| 621 | +class OGLSwToTextureBlit extends Blit { | |
| 622 | + | |
| 623 | + private int typeval; | |
| 624 | + | |
| 625 | + OGLSwToTextureBlit(SurfaceType srcType, int typeval) { | |
| 626 | + super(srcType, | |
| 627 | + CompositeType.SrcNoEa, | |
| 628 | + OGLSurfaceData.OpenGLTexture); | |
| 629 | + this.typeval = typeval; | |
| 630 | + } | |
| 631 | + | |
| 632 | + public void Blit(SurfaceData src, SurfaceData dst, | |
| 633 | + Composite comp, Region clip, | |
| 634 | + int sx, int sy, int dx, int dy, int w, int h) | |
| 635 | + { | |
| 636 | + OGLBlitLoops.Blit(src, dst, | |
| 637 | + comp, clip, null, | |
| 638 | + AffineTransformOp.TYPE_NEAREST_NEIGHBOR, | |
| 639 | + sx, sy, sx+w, sy+h, | |
| 640 | + dx, dy, dx+w, dy+h, | |
| 641 | + typeval, true); | |
| 642 | + } | |
| 643 | +} | |
| 644 | + | |
| 645 | +class OGLTextureToSurfaceBlit extends Blit { | |
| 646 | + | |
| 647 | + OGLTextureToSurfaceBlit() { | |
| 648 | + super(OGLSurfaceData.OpenGLTexture, | |
| 649 | + CompositeType.AnyAlpha, | |
| 650 | + OGLSurfaceData.OpenGLSurface); | |
| 651 | + } | |
| 652 | + | |
| 653 | + public void Blit(SurfaceData src, SurfaceData dst, | |
| 654 | + Composite comp, Region clip, | |
| 655 | + int sx, int sy, int dx, int dy, int w, int h) | |
| 656 | + { | |
| 657 | + OGLBlitLoops.IsoBlit(src, dst, | |
| 658 | + null, null, | |
| 659 | + comp, clip, null, | |
| 660 | + AffineTransformOp.TYPE_NEAREST_NEIGHBOR, | |
| 661 | + sx, sy, sx+w, sy+h, | |
| 662 | + dx, dy, dx+w, dy+h, | |
| 663 | + true); | |
| 664 | + } | |
| 665 | +} | |
| 666 | + | |
| 667 | +class OGLTextureToSurfaceScale extends ScaledBlit { | |
| 668 | + | |
| 669 | + OGLTextureToSurfaceScale() { | |
| 670 | + super(OGLSurfaceData.OpenGLTexture, | |
| 671 | + CompositeType.AnyAlpha, | |
| 672 | + OGLSurfaceData.OpenGLSurface); | |
| 673 | + } | |
| 674 | + | |
| 675 | + public void Scale(SurfaceData src, SurfaceData dst, | |
| 676 | + Composite comp, Region clip, | |
| 677 | + int sx1, int sy1, | |
| 678 | + int sx2, int sy2, | |
| 679 | + double dx1, double dy1, | |
| 680 | + double dx2, double dy2) | |
| 681 | + { | |
| 682 | + OGLBlitLoops.IsoBlit(src, dst, | |
| 683 | + null, null, | |
| 684 | + comp, clip, null, | |
| 685 | + AffineTransformOp.TYPE_NEAREST_NEIGHBOR, | |
| 686 | + sx1, sy1, sx2, sy2, | |
| 687 | + dx1, dy1, dx2, dy2, | |
| 688 | + true); | |
| 689 | + } | |
| 690 | +} | |
| 691 | + | |
| 692 | +class OGLTextureToSurfaceTransform extends TransformBlit { | |
| 693 | + | |
| 694 | + OGLTextureToSurfaceTransform() { | |
| 695 | + super(OGLSurfaceData.OpenGLTexture, | |
| 696 | + CompositeType.AnyAlpha, | |
| 697 | + OGLSurfaceData.OpenGLSurface); | |
| 698 | + } | |
| 699 | + | |
| 700 | + public void Transform(SurfaceData src, SurfaceData dst, | |
| 701 | + Composite comp, Region clip, | |
| 702 | + AffineTransform at, int hint, | |
| 703 | + int sx, int sy, int dx, int dy, | |
| 704 | + int w, int h) | |
| 705 | + { | |
| 706 | + OGLBlitLoops.IsoBlit(src, dst, | |
| 707 | + null, null, | |
| 708 | + comp, clip, at, hint, | |
| 709 | + sx, sy, sx+w, sy+h, | |
| 710 | + dx, dy, dx+w, dy+h, | |
| 711 | + true); | |
| 712 | + } | |
| 713 | +} | |
| 714 | + | |
| 715 | +/** | |
| 716 | + * This general Blit implemenation converts any source surface to an | |
| 717 | + * intermediate IntArgbPre surface, and then uses the more specific | |
| 718 | + * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate | |
| 719 | + * (premultiplied) surface down to OpenGL. | |
| 720 | + */ | |
| 721 | +class OGLGeneralBlit extends Blit { | |
| 722 | + | |
| 723 | + private Blit performop; | |
| 724 | + private WeakReference srcTmp; | |
| 725 | + | |
| 726 | + OGLGeneralBlit(SurfaceType dstType, | |
| 727 | + CompositeType compType, | |
| 728 | + Blit performop) | |
| 729 | + { | |
| 730 | + super(SurfaceType.Any, compType, dstType); | |
| 731 | + this.performop = performop; | |
| 732 | + } | |
| 733 | + | |
| 734 | + public synchronized void Blit(SurfaceData src, SurfaceData dst, | |
| 735 | + Composite comp, Region clip, | |
| 736 | + int sx, int sy, int dx, int dy, | |
| 737 | + int w, int h) | |
| 738 | + { | |
| 739 | + Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), | |
| 740 | + CompositeType.SrcNoEa, | |
| 741 | + SurfaceType.IntArgbPre); | |
| 742 | + | |
| 743 | + SurfaceData cachedSrc = null; | |
| 744 | + if (srcTmp != null) { | |
| 745 | + // use cached intermediate surface, if available | |
| 746 | + cachedSrc = (SurfaceData)srcTmp.get(); | |
| 747 | + } | |
| 748 | + | |
| 749 | + // convert source to IntArgbPre | |
| 750 | + src = convertFrom(convertsrc, src, sx, sy, w, h, | |
| 751 | + cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE); | |
| 752 | + | |
| 753 | + // copy IntArgbPre intermediate surface to OpenGL surface | |
| 754 | + performop.Blit(src, dst, comp, clip, | |
| 755 | + 0, 0, dx, dy, w, h); | |
| 756 | + | |
| 757 | + if (src != cachedSrc) { | |
| 758 | + // cache the intermediate surface | |
| 759 | + srcTmp = new WeakReference(src); | |
| 760 | + } | |
| 761 | + } | |
| 762 | +} | |
| @@ -0,0 +1,115 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2008, 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.image.AffineTransformOp; | |
| 29 | +import java.awt.image.BufferedImage; | |
| 30 | +import java.awt.image.BufferedImageOp; | |
| 31 | +import java.awt.image.ConvolveOp; | |
| 32 | +import java.awt.image.LookupOp; | |
| 33 | +import java.awt.image.RescaleOp; | |
| 34 | +import sun.java2d.SunGraphics2D; | |
| 35 | +import sun.java2d.SurfaceData; | |
| 36 | +import sun.java2d.loops.CompositeType; | |
| 37 | +import sun.java2d.pipe.BufferedBufImgOps; | |
| 38 | +import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; | |
| 39 | + | |
| 40 | +class OGLBufImgOps extends BufferedBufImgOps { | |
| 41 | + | |
| 42 | + /** | |
| 43 | + * This method is called from OGLDrawImage.transformImage() only. It | |
| 44 | + * validates the provided BufferedImageOp to determine whether the op | |
| 45 | + * is one that can be accelerated by the OGL pipeline. If the operation | |
| 46 | + * cannot be completed for any reason, this method returns false; | |
| 47 | + * otherwise, the given BufferedImage is rendered to the destination | |
| 48 | + * using the provided BufferedImageOp and this method returns true. | |
| 49 | + */ | |
| 50 | + static boolean renderImageWithOp(SunGraphics2D sg, BufferedImage img, | |
| 51 | + BufferedImageOp biop, int x, int y) | |
| 52 | + { | |
| 53 | + // Validate the provided BufferedImage (make sure it is one that | |
| 54 | + // is supported, and that its properties are acceleratable) | |
| 55 | + if (biop instanceof ConvolveOp) { | |
| 56 | + if (!isConvolveOpValid((ConvolveOp)biop)) { | |
| 57 | + return false; | |
| 58 | + } | |
| 59 | + } else if (biop instanceof RescaleOp) { | |
| 60 | + if (!isRescaleOpValid((RescaleOp)biop, img)) { | |
| 61 | + return false; | |
| 62 | + } | |
| 63 | + } else if (biop instanceof LookupOp) { | |
| 64 | + if (!isLookupOpValid((LookupOp)biop, img)) { | |
| 65 | + return false; | |
| 66 | + } | |
| 67 | + } else { | |
| 68 | + // No acceleration for other BufferedImageOps (yet) | |
| 69 | + return false; | |
| 70 | + } | |
| 71 | + | |
| 72 | + SurfaceData dstData = sg.surfaceData; | |
| 73 | + if (!(dstData instanceof OGLSurfaceData) || | |
| 74 | + (sg.interpolationType == AffineTransformOp.TYPE_BICUBIC) || | |
| 75 | + (sg.compositeState > SunGraphics2D.COMP_ALPHA)) | |
| 76 | + { | |
| 77 | + return false; | |
| 78 | + } | |
| 79 | + | |
| 80 | + SurfaceData srcData = | |
| 81 | + dstData.getSourceSurfaceData(img, sg.TRANSFORM_ISIDENT, | |
| 82 | + CompositeType.SrcOver, null); | |
| 83 | + if (!(srcData instanceof OGLSurfaceData)) { | |
| 84 | + // REMIND: this hack tries to ensure that we have a cached texture | |
| 85 | + srcData = | |
| 86 | + dstData.getSourceSurfaceData(img, sg.TRANSFORM_ISIDENT, | |
| 87 | + CompositeType.SrcOver, null); | |
| 88 | + if (!(srcData instanceof OGLSurfaceData)) { | |
| 89 | + return false; | |
| 90 | + } | |
| 91 | + } | |
| 92 | + | |
| 93 | + // Verify that the source surface is actually a texture and | |
| 94 | + // that the operation is supported | |
| 95 | + OGLSurfaceData oglSrc = (OGLSurfaceData)srcData; | |
| 96 | + OGLGraphicsConfig gc = oglSrc.getOGLGraphicsConfig(); | |
| 97 | + if (oglSrc.getType() != OGLSurfaceData.TEXTURE || | |
| 98 | + !gc.isCapPresent(CAPS_EXT_BIOP_SHADER)) | |
| 99 | + { | |
| 100 | + return false; | |
| 101 | + } | |
| 102 | + | |
| 103 | + int sw = img.getWidth(); | |
| 104 | + int sh = img.getHeight(); | |
| 105 | + OGLBlitLoops.IsoBlit(srcData, dstData, | |
| 106 | + img, biop, | |
| 107 | + sg.composite, sg.getCompClip(), | |
| 108 | + sg.transform, sg.interpolationType, | |
| 109 | + 0, 0, sw, sh, | |
| 110 | + x, y, x+sw, y+sh, | |
| 111 | + true); | |
| 112 | + | |
| 113 | + return true; | |
| 114 | + } | |
| 115 | +} | |
| @@ -0,0 +1,220 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2004, 2008, 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 sun.java2d.pipe.BufferedContext; | |
| 29 | +import sun.java2d.pipe.RenderBuffer; | |
| 30 | +import sun.java2d.pipe.RenderQueue; | |
| 31 | +import sun.java2d.pipe.hw.ContextCapabilities; | |
| 32 | +import static sun.java2d.pipe.BufferedOpCodes.*; | |
| 33 | +import static sun.java2d.pipe.hw.ContextCapabilities.*; | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * Note that the RenderQueue lock must be acquired before calling any of | |
| 37 | + * the methods in this class. | |
| 38 | + */ | |
| 39 | +public class OGLContext extends BufferedContext { | |
| 40 | + | |
| 41 | + private final OGLGraphicsConfig config; | |
| 42 | + | |
| 43 | + OGLContext(RenderQueue rq, OGLGraphicsConfig config) { | |
| 44 | + super(rq); | |
| 45 | + this.config = config; | |
| 46 | + } | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * Convenience method that delegates to setScratchSurface() below. | |
| 50 | + */ | |
| 51 | + static void setScratchSurface(OGLGraphicsConfig gc) { | |
| 52 | + setScratchSurface(gc.getNativeConfigInfo()); | |
| 53 | + } | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * Makes the given GraphicsConfig's context current to its associated | |
| 57 | + * "scratch surface". Each GraphicsConfig maintains a native context | |
| 58 | + * (GLXContext on Unix, HGLRC on Windows) as well as a native pbuffer | |
| 59 | + * known as the "scratch surface". By making the context current to the | |
| 60 | + * scratch surface, we are assured that we have a current context for | |
| 61 | + * the relevant GraphicsConfig, and can therefore perform operations | |
| 62 | + * depending on the capabilities of that GraphicsConfig. For example, | |
| 63 | + * if the GraphicsConfig supports the GL_ARB_texture_non_power_of_two | |
| 64 | + * extension, then we should be able to make a non-pow2 texture for this | |
| 65 | + * GraphicsConfig once we make the context current to the scratch surface. | |
| 66 | + * | |
| 67 | + * This method should be used for operations with an OpenGL texture | |
| 68 | + * as the destination surface (e.g. a sw->texture blit loop), or in those | |
| 69 | + * situations where we may not otherwise have a current context (e.g. | |
| 70 | + * when disposing a texture-based surface). | |
| 71 | + */ | |
| 72 | + static void setScratchSurface(long pConfigInfo) { | |
| 73 | + // assert OGLRenderQueue.getInstance().lock.isHeldByCurrentThread(); | |
| 74 | + | |
| 75 | + // invalidate the current context | |
| 76 | + currentContext = null; | |
| 77 | + | |
| 78 | + // set the scratch context | |
| 79 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 80 | + RenderBuffer buf = rq.getBuffer(); | |
| 81 | + rq.ensureCapacityAndAlignment(12, 4); | |
| 82 | + buf.putInt(SET_SCRATCH_SURFACE); | |
| 83 | + buf.putLong(pConfigInfo); | |
| 84 | + } | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * Invalidates the currentContext field to ensure that we properly | |
| 88 | + * revalidate the OGLContext (make it current, etc.) next time through | |
| 89 | + * the validate() method. This is typically invoked from methods | |
| 90 | + * that affect the current context state (e.g. disposing a context or | |
| 91 | + * surface). | |
| 92 | + */ | |
| 93 | + static void invalidateCurrentContext() { | |
| 94 | + // assert OGLRenderQueue.getInstance().lock.isHeldByCurrentThread(); | |
| 95 | + | |
| 96 | + // invalidate the current Java-level context so that we | |
| 97 | + // revalidate everything the next time around | |
| 98 | + if (currentContext != null) { | |
| 99 | + currentContext.invalidateContext(); | |
| 100 | + currentContext = null; | |
| 101 | + } | |
| 102 | + | |
| 103 | + // invalidate the context reference at the native level, and | |
| 104 | + // then flush the queue so that we have no pending operations | |
| 105 | + // dependent on the current context | |
| 106 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 107 | + rq.ensureCapacity(4); | |
| 108 | + rq.getBuffer().putInt(INVALIDATE_CONTEXT); | |
| 109 | + rq.flushNow(); | |
| 110 | + } | |
| 111 | + | |
| 112 | + public RenderQueue getRenderQueue() { | |
| 113 | + return OGLRenderQueue.getInstance(); | |
| 114 | + } | |
| 115 | + | |
| 116 | + /** | |
| 117 | + * Returns a string representing adapter id (vendor, renderer, version). | |
| 118 | + * Must be called on the rendering thread. | |
| 119 | + * | |
| 120 | + * @return an id string for the adapter | |
| 121 | + */ | |
| 122 | + static final native String getOGLIdString(); | |
| 123 | + | |
| 124 | + @Override | |
| 125 | + public void saveState() { | |
| 126 | + // assert rq.lock.isHeldByCurrentThread(); | |
| 127 | + | |
| 128 | + // reset all attributes of this and current contexts | |
| 129 | + invalidateContext(); | |
| 130 | + invalidateCurrentContext(); | |
| 131 | + | |
| 132 | + setScratchSurface(config); | |
| 133 | + | |
| 134 | + // save the state on the native level | |
| 135 | + rq.ensureCapacity(4); | |
| 136 | + buf.putInt(SAVE_STATE); | |
| 137 | + rq.flushNow(); | |
| 138 | + } | |
| 139 | + | |
| 140 | + @Override | |
| 141 | + public void restoreState() { | |
| 142 | + // assert rq.lock.isHeldByCurrentThread(); | |
| 143 | + | |
| 144 | + // reset all attributes of this and current contexts | |
| 145 | + invalidateContext(); | |
| 146 | + invalidateCurrentContext(); | |
| 147 | + | |
| 148 | + setScratchSurface(config); | |
| 149 | + | |
| 150 | + // restore the state on the native level | |
| 151 | + rq.ensureCapacity(4); | |
| 152 | + buf.putInt(RESTORE_STATE); | |
| 153 | + rq.flushNow(); | |
| 154 | + } | |
| 155 | + | |
| 156 | + static class OGLContextCaps extends ContextCapabilities { | |
| 157 | + /** | |
| 158 | + * Indicates the presence of the GL_EXT_framebuffer_object extension. | |
| 159 | + * This cap will only be set if the fbobject system property has been | |
| 160 | + * enabled and we are able to create an FBO with depth buffer. | |
| 161 | + */ | |
| 162 | + static final int CAPS_EXT_FBOBJECT = | |
| 163 | + (CAPS_RT_TEXTURE_ALPHA | CAPS_RT_TEXTURE_OPAQUE); | |
| 164 | + /** Indicates that the context supports a stored alpha channel. */ | |
| 165 | + static final int CAPS_STORED_ALPHA = CAPS_RT_PLAIN_ALPHA; | |
| 166 | + /** Indicates that the context is doublebuffered. */ | |
| 167 | + static final int CAPS_DOUBLEBUFFERED = (FIRST_PRIVATE_CAP << 0); | |
| 168 | + /** | |
| 169 | + * Indicates the presence of the GL_ARB_fragment_shader extension. | |
| 170 | + * This cap will only be set if the lcdshader system property has been | |
| 171 | + * enabled and the hardware supports the minimum number of texture units | |
| 172 | + */ | |
| 173 | + static final int CAPS_EXT_LCD_SHADER = (FIRST_PRIVATE_CAP << 1); | |
| 174 | + /** | |
| 175 | + * Indicates the presence of the GL_ARB_fragment_shader extension. | |
| 176 | + * This cap will only be set if the biopshader system property has been | |
| 177 | + * enabled and the hardware meets our minimum requirements. | |
| 178 | + */ | |
| 179 | + static final int CAPS_EXT_BIOP_SHADER = (FIRST_PRIVATE_CAP << 2); | |
| 180 | + /** | |
| 181 | + * Indicates the presence of the GL_ARB_fragment_shader extension. | |
| 182 | + * This cap will only be set if the gradshader system property has been | |
| 183 | + * enabled and the hardware meets our minimum requirements. | |
| 184 | + */ | |
| 185 | + static final int CAPS_EXT_GRAD_SHADER = (FIRST_PRIVATE_CAP << 3); | |
| 186 | + /** Indicates the presence of the GL_ARB_texture_rectangle extension. */ | |
| 187 | + static final int CAPS_EXT_TEXRECT = (FIRST_PRIVATE_CAP << 4); | |
| 188 | + | |
| 189 | + OGLContextCaps(int caps, String adapterId) { | |
| 190 | + super(caps, adapterId); | |
| 191 | + } | |
| 192 | + | |
| 193 | + @Override | |
| 194 | + public String toString() { | |
| 195 | + StringBuffer buf = new StringBuffer(super.toString()); | |
| 196 | + if ((caps & CAPS_EXT_FBOBJECT) != 0) { | |
| 197 | + buf.append("CAPS_EXT_FBOBJECT|"); | |
| 198 | + } | |
| 199 | + if ((caps & CAPS_STORED_ALPHA) != 0) { | |
| 200 | + buf.append("CAPS_STORED_ALPHA|"); | |
| 201 | + } | |
| 202 | + if ((caps & CAPS_DOUBLEBUFFERED) != 0) { | |
| 203 | + buf.append("CAPS_DOUBLEBUFFERED|"); | |
| 204 | + } | |
| 205 | + if ((caps & CAPS_EXT_LCD_SHADER) != 0) { | |
| 206 | + buf.append("CAPS_EXT_LCD_SHADER|"); | |
| 207 | + } | |
| 208 | + if ((caps & CAPS_EXT_BIOP_SHADER) != 0) { | |
| 209 | + buf.append("CAPS_BIOP_SHADER|"); | |
| 210 | + } | |
| 211 | + if ((caps & CAPS_EXT_GRAD_SHADER) != 0) { | |
| 212 | + buf.append("CAPS_EXT_GRAD_SHADER|"); | |
| 213 | + } | |
| 214 | + if ((caps & CAPS_EXT_TEXRECT) != 0) { | |
| 215 | + buf.append("CAPS_EXT_TEXRECT|"); | |
| 216 | + } | |
| 217 | + return buf.toString(); | |
| 218 | + } | |
| 219 | + } | |
| 220 | +} | |
| @@ -0,0 +1,113 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2007, 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.Color; | |
| 29 | +import java.awt.Image; | |
| 30 | +import java.awt.geom.AffineTransform; | |
| 31 | +import java.awt.image.AffineTransformOp; | |
| 32 | +import java.awt.image.BufferedImage; | |
| 33 | +import java.awt.image.BufferedImageOp; | |
| 34 | +import sun.java2d.SunGraphics2D; | |
| 35 | +import sun.java2d.SurfaceData; | |
| 36 | +import sun.java2d.loops.SurfaceType; | |
| 37 | +import sun.java2d.loops.TransformBlit; | |
| 38 | +import sun.java2d.pipe.DrawImage; | |
| 39 | + | |
| 40 | +public class OGLDrawImage extends DrawImage { | |
| 41 | + | |
| 42 | + @Override | |
| 43 | + protected void renderImageXform(SunGraphics2D sg, Image img, | |
| 44 | + AffineTransform tx, int interpType, | |
| 45 | + int sx1, int sy1, int sx2, int sy2, | |
| 46 | + Color bgColor) | |
| 47 | + { | |
| 48 | + // punt to the MediaLib-based transformImage() in the superclass if: | |
| 49 | + // - bicubic interpolation is specified | |
| 50 | + // - a background color is specified and will be used | |
| 51 | + // - the source surface is neither a texture nor render-to-texture | |
| 52 | + // surface, and a non-default interpolation hint is specified | |
| 53 | + // (we can only control the filtering for texture->surface | |
| 54 | + // copies) | |
| 55 | + // REMIND: we should tweak the sw->texture->surface | |
| 56 | + // transform case to handle filtering appropriately | |
| 57 | + // (see 4841762)... | |
| 58 | + // - an appropriate TransformBlit primitive could not be found | |
| 59 | + if (interpType != AffineTransformOp.TYPE_BICUBIC) { | |
| 60 | + SurfaceData dstData = sg.surfaceData; | |
| 61 | + SurfaceData srcData = | |
| 62 | + dstData.getSourceSurfaceData(img, | |
| 63 | + sg.TRANSFORM_GENERIC, | |
| 64 | + sg.imageComp, | |
| 65 | + bgColor); | |
| 66 | + | |
| 67 | + if (srcData != null && | |
| 68 | + !isBgOperation(srcData, bgColor) && | |
| 69 | + (srcData.getSurfaceType() == OGLSurfaceData.OpenGLTexture || | |
| 70 | + srcData.getSurfaceType() == OGLSurfaceData.OpenGLSurfaceRTT || | |
| 71 | + interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR)) | |
| 72 | + { | |
| 73 | + SurfaceType srcType = srcData.getSurfaceType(); | |
| 74 | + SurfaceType dstType = dstData.getSurfaceType(); | |
| 75 | + TransformBlit blit = TransformBlit.getFromCache(srcType, | |
| 76 | + sg.imageComp, | |
| 77 | + dstType); | |
| 78 | + | |
| 79 | + if (blit != null) { | |
| 80 | + blit.Transform(srcData, dstData, | |
| 81 | + sg.composite, sg.getCompClip(), | |
| 82 | + tx, interpType, | |
| 83 | + sx1, sy1, 0, 0, sx2-sx1, sy2-sy1); | |
| 84 | + return; | |
| 85 | + } | |
| 86 | + } | |
| 87 | + } | |
| 88 | + | |
| 89 | + super.renderImageXform(sg, img, tx, interpType, | |
| 90 | + sx1, sy1, sx2, sy2, bgColor); | |
| 91 | + } | |
| 92 | + | |
| 93 | + @Override | |
| 94 | + public void transformImage(SunGraphics2D sg, BufferedImage img, | |
| 95 | + BufferedImageOp op, int x, int y) | |
| 96 | + { | |
| 97 | + if (op != null) { | |
| 98 | + if (op instanceof AffineTransformOp) { | |
| 99 | + AffineTransformOp atop = (AffineTransformOp) op; | |
| 100 | + transformImage(sg, img, x, y, | |
| 101 | + atop.getTransform(), | |
| 102 | + atop.getInterpolationType()); | |
| 103 | + return; | |
| 104 | + } else { | |
| 105 | + if (OGLBufImgOps.renderImageWithOp(sg, img, op, x, y)) { | |
| 106 | + return; | |
| 107 | + } | |
| 108 | + } | |
| 109 | + img = op.filter(img, null); | |
| 110 | + } | |
| 111 | + copyImage(sg, img, x, y, null); | |
| 112 | + } | |
| 113 | +} | |
| @@ -0,0 +1,44 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2008, 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 sun.java2d.SurfaceData; | |
| 29 | +import sun.awt.image.SurfaceManager; | |
| 30 | +import sun.java2d.pipe.hw.AccelGraphicsConfig; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * This interface collects the methods that are provided by both | |
| 34 | + * GLXGraphicsConfig and WGLGraphicsConfig, making it easier to invoke these | |
| 35 | + * methods directly from OGLSurfaceData. | |
| 36 | + */ | |
| 37 | +interface OGLGraphicsConfig extends | |
| 38 | + AccelGraphicsConfig, SurfaceManager.ProxiedGraphicsConfig | |
| 39 | +{ | |
| 40 | + OGLContext getContext(); | |
| 41 | + long getNativeConfigInfo(); | |
| 42 | + boolean isCapPresent(int cap); | |
| 43 | + SurfaceData createManagedSurface(int w, int h, int transparency); | |
| 44 | +} | |
| @@ -0,0 +1,69 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2007, 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.Composite; | |
| 29 | +import sun.java2d.SurfaceData; | |
| 30 | +import sun.java2d.loops.CompositeType; | |
| 31 | +import sun.java2d.loops.GraphicsPrimitive; | |
| 32 | +import sun.java2d.loops.GraphicsPrimitiveMgr; | |
| 33 | +import sun.java2d.loops.SurfaceType; | |
| 34 | +import sun.java2d.pipe.Region; | |
| 35 | +import sun.java2d.pipe.BufferedMaskBlit; | |
| 36 | +import static sun.java2d.loops.CompositeType.*; | |
| 37 | +import static sun.java2d.loops.SurfaceType.*; | |
| 38 | + | |
| 39 | +class OGLMaskBlit extends BufferedMaskBlit { | |
| 40 | + | |
| 41 | + static void register() { | |
| 42 | + GraphicsPrimitive[] primitives = { | |
| 43 | + new OGLMaskBlit(IntArgb, SrcOver), | |
| 44 | + new OGLMaskBlit(IntArgbPre, SrcOver), | |
| 45 | + new OGLMaskBlit(IntRgb, SrcOver), | |
| 46 | + new OGLMaskBlit(IntRgb, SrcNoEa), | |
| 47 | + new OGLMaskBlit(IntBgr, SrcOver), | |
| 48 | + new OGLMaskBlit(IntBgr, SrcNoEa), | |
| 49 | + }; | |
| 50 | + GraphicsPrimitiveMgr.register(primitives); | |
| 51 | + } | |
| 52 | + | |
| 53 | + private OGLMaskBlit(SurfaceType srcType, | |
| 54 | + CompositeType compType) | |
| 55 | + { | |
| 56 | + super(OGLRenderQueue.getInstance(), | |
| 57 | + srcType, compType, OGLSurfaceData.OpenGLSurface); | |
| 58 | + } | |
| 59 | + | |
| 60 | + @Override | |
| 61 | + protected void validateContext(SurfaceData dstData, | |
| 62 | + Composite comp, Region clip) | |
| 63 | + { | |
| 64 | + OGLSurfaceData oglDst = (OGLSurfaceData)dstData; | |
| 65 | + OGLContext.validateContext(oglDst, oglDst, | |
| 66 | + clip, comp, null, null, null, | |
| 67 | + OGLContext.NO_CONTEXT_FLAGS); | |
| 68 | + } | |
| 69 | +} | |
| @@ -0,0 +1,75 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2007, 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.Composite; | |
| 29 | +import sun.java2d.SunGraphics2D; | |
| 30 | +import sun.java2d.loops.GraphicsPrimitive; | |
| 31 | +import sun.java2d.loops.GraphicsPrimitiveMgr; | |
| 32 | +import sun.java2d.loops.CompositeType; | |
| 33 | +import sun.java2d.loops.SurfaceType; | |
| 34 | +import sun.java2d.pipe.BufferedMaskFill; | |
| 35 | +import static sun.java2d.loops.CompositeType.*; | |
| 36 | +import static sun.java2d.loops.SurfaceType.*; | |
| 37 | + | |
| 38 | +class OGLMaskFill extends BufferedMaskFill { | |
| 39 | + | |
| 40 | + static void register() { | |
| 41 | + GraphicsPrimitive[] primitives = { | |
| 42 | + new OGLMaskFill(AnyColor, SrcOver), | |
| 43 | + new OGLMaskFill(OpaqueColor, SrcNoEa), | |
| 44 | + new OGLMaskFill(GradientPaint, SrcOver), | |
| 45 | + new OGLMaskFill(OpaqueGradientPaint, SrcNoEa), | |
| 46 | + new OGLMaskFill(LinearGradientPaint, SrcOver), | |
| 47 | + new OGLMaskFill(OpaqueLinearGradientPaint, SrcNoEa), | |
| 48 | + new OGLMaskFill(RadialGradientPaint, SrcOver), | |
| 49 | + new OGLMaskFill(OpaqueRadialGradientPaint, SrcNoEa), | |
| 50 | + new OGLMaskFill(TexturePaint, SrcOver), | |
| 51 | + new OGLMaskFill(OpaqueTexturePaint, SrcNoEa), | |
| 52 | + }; | |
| 53 | + GraphicsPrimitiveMgr.register(primitives); | |
| 54 | + } | |
| 55 | + | |
| 56 | + protected OGLMaskFill(SurfaceType srcType, CompositeType compType) { | |
| 57 | + super(OGLRenderQueue.getInstance(), | |
| 58 | + srcType, compType, OGLSurfaceData.OpenGLSurface); | |
| 59 | + } | |
| 60 | + | |
| 61 | + @Override | |
| 62 | + protected native void maskFill(int x, int y, int w, int h, | |
| 63 | + int maskoff, int maskscan, int masklen, | |
| 64 | + byte[] mask); | |
| 65 | + | |
| 66 | + @Override | |
| 67 | + protected void validateContext(SunGraphics2D sg2d, | |
| 68 | + Composite comp, int ctxflags) | |
| 69 | + { | |
| 70 | + OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; | |
| 71 | + OGLContext.validateContext(dstData, dstData, | |
| 72 | + sg2d.getCompClip(), comp, | |
| 73 | + null, sg2d.paint, sg2d, ctxflags); | |
| 74 | + } | |
| 75 | +} | |
| @@ -0,0 +1,209 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2008, 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.GradientPaint; | |
| 29 | +import java.awt.LinearGradientPaint; | |
| 30 | +import java.awt.MultipleGradientPaint; | |
| 31 | +import java.awt.MultipleGradientPaint.ColorSpaceType; | |
| 32 | +import java.awt.MultipleGradientPaint.CycleMethod; | |
| 33 | +import java.awt.RadialGradientPaint; | |
| 34 | +import java.awt.TexturePaint; | |
| 35 | +import java.awt.image.BufferedImage; | |
| 36 | +import java.util.HashMap; | |
| 37 | +import java.util.Map; | |
| 38 | +import sun.java2d.SunGraphics2D; | |
| 39 | +import sun.java2d.SurfaceData; | |
| 40 | +import sun.java2d.loops.CompositeType; | |
| 41 | +import static sun.java2d.pipe.BufferedPaints.*; | |
| 42 | +import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; | |
| 43 | + | |
| 44 | +abstract class OGLPaints { | |
| 45 | + | |
| 46 | + /** | |
| 47 | + * Holds all registered implementations, using the corresponding | |
| 48 | + * SunGraphics2D.PAINT_* constant as the hash key. | |
| 49 | + */ | |
| 50 | + private static Map<Integer, OGLPaints> impls = | |
| 51 | + new HashMap<Integer, OGLPaints>(4, 1.0f); | |
| 52 | + | |
| 53 | + static { | |
| 54 | + impls.put(SunGraphics2D.PAINT_GRADIENT, new Gradient()); | |
| 55 | + impls.put(SunGraphics2D.PAINT_LIN_GRADIENT, new LinearGradient()); | |
| 56 | + impls.put(SunGraphics2D.PAINT_RAD_GRADIENT, new RadialGradient()); | |
| 57 | + impls.put(SunGraphics2D.PAINT_TEXTURE, new Texture()); | |
| 58 | + } | |
| 59 | + | |
| 60 | + /** | |
| 61 | + * Attempts to locate an implementation corresponding to the paint state | |
| 62 | + * of the provided SunGraphics2D object. If no implementation can be | |
| 63 | + * found, or if the paint cannot be accelerated under the conditions | |
| 64 | + * of the SunGraphics2D, this method returns false; otherwise, returns | |
| 65 | + * true. | |
| 66 | + */ | |
| 67 | + static boolean isValid(SunGraphics2D sg2d) { | |
| 68 | + OGLPaints impl = impls.get(sg2d.paintState); | |
| 69 | + return (impl != null && impl.isPaintValid(sg2d)); | |
| 70 | + } | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * Returns true if this implementation is able to accelerate the | |
| 74 | + * Paint object associated with, and under the conditions of, the | |
| 75 | + * provided SunGraphics2D instance; otherwise returns false. | |
| 76 | + */ | |
| 77 | + abstract boolean isPaintValid(SunGraphics2D sg2d); | |
| 78 | + | |
| 79 | +/************************* GradientPaint support ****************************/ | |
| 80 | + | |
| 81 | + private static class Gradient extends OGLPaints { | |
| 82 | + private Gradient() {} | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * There are no restrictions for accelerating GradientPaint, so | |
| 86 | + * this method always returns true. | |
| 87 | + */ | |
| 88 | + @Override | |
| 89 | + boolean isPaintValid(SunGraphics2D sg2d) { | |
| 90 | + return true; | |
| 91 | + } | |
| 92 | + } | |
| 93 | + | |
| 94 | +/************************** TexturePaint support ****************************/ | |
| 95 | + | |
| 96 | + private static class Texture extends OGLPaints { | |
| 97 | + private Texture() {} | |
| 98 | + | |
| 99 | + /** | |
| 100 | + * Returns true if the given TexturePaint instance can be used by the | |
| 101 | + * accelerated OGLPaints.Texture implementation. A TexturePaint is | |
| 102 | + * considered valid if the following conditions are met: | |
| 103 | + * - the texture image dimensions are power-of-two (or the | |
| 104 | + * GL_ARB_texture_non_power_of_two extension is present) | |
| 105 | + * - the texture image can be (or is already) cached in an OpenGL | |
| 106 | + * texture object | |
| 107 | + */ | |
| 108 | + @Override | |
| 109 | + boolean isPaintValid(SunGraphics2D sg2d) { | |
| 110 | + TexturePaint paint = (TexturePaint)sg2d.paint; | |
| 111 | + OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; | |
| 112 | + BufferedImage bi = paint.getImage(); | |
| 113 | + | |
| 114 | + // see if texture-non-pow2 extension is available | |
| 115 | + if (!dstData.isTexNonPow2Available()) { | |
| 116 | + int imgw = bi.getWidth(); | |
| 117 | + int imgh = bi.getHeight(); | |
| 118 | + | |
| 119 | + // verify that the texture image dimensions are pow2 | |
| 120 | + if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) { | |
| 121 | + return false; | |
| 122 | + } | |
| 123 | + } | |
| 124 | + | |
| 125 | + SurfaceData srcData = | |
| 126 | + dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT, | |
| 127 | + CompositeType.SrcOver, null); | |
| 128 | + if (!(srcData instanceof OGLSurfaceData)) { | |
| 129 | + // REMIND: this is a hack that attempts to cache the system | |
| 130 | + // memory image from the TexturePaint instance into an | |
| 131 | + // OpenGL texture... | |
| 132 | + srcData = | |
| 133 | + dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT, | |
| 134 | + CompositeType.SrcOver, null); | |
| 135 | + if (!(srcData instanceof OGLSurfaceData)) { | |
| 136 | + return false; | |
| 137 | + } | |
| 138 | + } | |
| 139 | + | |
| 140 | + // verify that the source surface is actually a texture | |
| 141 | + OGLSurfaceData oglData = (OGLSurfaceData)srcData; | |
| 142 | + if (oglData.getType() != OGLSurfaceData.TEXTURE) { | |
| 143 | + return false; | |
| 144 | + } | |
| 145 | + | |
| 146 | + return true; | |
| 147 | + } | |
| 148 | + } | |
| 149 | + | |
| 150 | +/****************** Shared MultipleGradientPaint support ********************/ | |
| 151 | + | |
| 152 | + private static abstract class MultiGradient extends OGLPaints { | |
| 153 | + protected MultiGradient() {} | |
| 154 | + | |
| 155 | + /** | |
| 156 | + * Returns true if the given MultipleGradientPaint instance can be | |
| 157 | + * used by the accelerated OGLPaints.MultiGradient implementation. | |
| 158 | + * A MultipleGradientPaint is considered valid if the following | |
| 159 | + * conditions are met: | |
| 160 | + * - the number of gradient "stops" is <= MAX_FRACTIONS | |
| 161 | + * - the destination has support for fragment shaders | |
| 162 | + */ | |
| 163 | + @Override | |
| 164 | + boolean isPaintValid(SunGraphics2D sg2d) { | |
| 165 | + MultipleGradientPaint paint = (MultipleGradientPaint)sg2d.paint; | |
| 166 | + // REMIND: ugh, this creates garbage; would be nicer if | |
| 167 | + // we had a MultipleGradientPaint.getNumStops() method... | |
| 168 | + if (paint.getFractions().length > MULTI_MAX_FRACTIONS) { | |
| 169 | + return false; | |
| 170 | + } | |
| 171 | + | |
| 172 | + OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; | |
| 173 | + OGLGraphicsConfig gc = dstData.getOGLGraphicsConfig(); | |
| 174 | + if (!gc.isCapPresent(CAPS_EXT_GRAD_SHADER)) { | |
| 175 | + return false; | |
| 176 | + } | |
| 177 | + | |
| 178 | + return true; | |
| 179 | + } | |
| 180 | + } | |
| 181 | + | |
| 182 | +/********************** LinearGradientPaint support *************************/ | |
| 183 | + | |
| 184 | + private static class LinearGradient extends MultiGradient { | |
| 185 | + private LinearGradient() {} | |
| 186 | + | |
| 187 | + @Override | |
| 188 | + boolean isPaintValid(SunGraphics2D sg2d) { | |
| 189 | + LinearGradientPaint paint = (LinearGradientPaint)sg2d.paint; | |
| 190 | + | |
| 191 | + if (paint.getFractions().length == 2 && | |
| 192 | + paint.getCycleMethod() != CycleMethod.REPEAT && | |
| 193 | + paint.getColorSpace() != ColorSpaceType.LINEAR_RGB) | |
| 194 | + { | |
| 195 | + // we can delegate to the optimized two-color gradient | |
| 196 | + // codepath, which does not require fragment shader support | |
| 197 | + return true; | |
| 198 | + } | |
| 199 | + | |
| 200 | + return super.isPaintValid(sg2d); | |
| 201 | + } | |
| 202 | + } | |
| 203 | + | |
| 204 | +/********************** RadialGradientPaint support *************************/ | |
| 205 | + | |
| 206 | + private static class RadialGradient extends MultiGradient { | |
| 207 | + private RadialGradient() {} | |
| 208 | + } | |
| 209 | +} | |
| @@ -0,0 +1,239 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2007, 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 sun.java2d.pipe.RenderBuffer; | |
| 29 | +import sun.java2d.pipe.RenderQueue; | |
| 30 | +import static sun.java2d.pipe.BufferedOpCodes.*; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * OGL-specific implementation of RenderQueue. This class provides a | |
| 34 | + * single (daemon) thread that is responsible for periodically flushing | |
| 35 | + * the queue, thus ensuring that only one thread communicates with the native | |
| 36 | + * OpenGL libraries for the entire process. | |
| 37 | + */ | |
| 38 | +public class OGLRenderQueue extends RenderQueue { | |
| 39 | + | |
| 40 | + private static OGLRenderQueue theInstance; | |
| 41 | + private final QueueFlusher flusher; | |
| 42 | + | |
| 43 | + private OGLRenderQueue() { | |
| 44 | + flusher = new QueueFlusher(); | |
| 45 | + } | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * Returns the single OGLRenderQueue instance. If it has not yet been | |
| 49 | + * initialized, this method will first construct the single instance | |
| 50 | + * before returning it. | |
| 51 | + */ | |
| 52 | + public static synchronized OGLRenderQueue getInstance() { | |
| 53 | + if (theInstance == null) { | |
| 54 | + theInstance = new OGLRenderQueue(); | |
| 55 | + } | |
| 56 | + return theInstance; | |
| 57 | + } | |
| 58 | + | |
| 59 | + /** | |
| 60 | + * Flushes the single OGLRenderQueue instance synchronously. If an | |
| 61 | + * OGLRenderQueue has not yet been instantiated, this method is a no-op. | |
| 62 | + * This method is useful in the case of Toolkit.sync(), in which we want | |
| 63 | + * to flush the OGL pipeline, but only if the OGL pipeline is currently | |
| 64 | + * enabled. Since this class has few external dependencies, callers need | |
| 65 | + * not be concerned that calling this method will trigger initialization | |
| 66 | + * of the OGL pipeline and related classes. | |
| 67 | + */ | |
| 68 | + public static void sync() { | |
| 69 | + if (theInstance != null) { | |
| 70 | + theInstance.lock(); | |
| 71 | + try { | |
| 72 | + theInstance.ensureCapacity(4); | |
| 73 | + theInstance.getBuffer().putInt(SYNC); | |
| 74 | + theInstance.flushNow(); | |
| 75 | + } finally { | |
| 76 | + theInstance.unlock(); | |
| 77 | + } | |
| 78 | + } | |
| 79 | + } | |
| 80 | + | |
| 81 | + /** | |
| 82 | + * Disposes the native memory associated with the given native | |
| 83 | + * graphics config info pointer on the single queue flushing thread. | |
| 84 | + */ | |
| 85 | + public static void disposeGraphicsConfig(long pConfigInfo) { | |
| 86 | + OGLRenderQueue rq = getInstance(); | |
| 87 | + rq.lock(); | |
| 88 | + try { | |
| 89 | + // make sure we make the context associated with the given | |
| 90 | + // GraphicsConfig current before disposing the native resources | |
| 91 | + OGLContext.setScratchSurface(pConfigInfo); | |
| 92 | + | |
| 93 | + RenderBuffer buf = rq.getBuffer(); | |
| 94 | + rq.ensureCapacityAndAlignment(12, 4); | |
| 95 | + buf.putInt(DISPOSE_CONFIG); | |
| 96 | + buf.putLong(pConfigInfo); | |
| 97 | + | |
| 98 | + // this call is expected to complete synchronously, so flush now | |
| 99 | + rq.flushNow(); | |
| 100 | + } finally { | |
| 101 | + rq.unlock(); | |
| 102 | + } | |
| 103 | + } | |
| 104 | + | |
| 105 | + /** | |
| 106 | + * Returns true if the current thread is the OGL QueueFlusher thread. | |
| 107 | + */ | |
| 108 | + public static boolean isQueueFlusherThread() { | |
| 109 | + return (Thread.currentThread() == getInstance().flusher); | |
| 110 | + } | |
| 111 | + | |
| 112 | + public void flushNow() { | |
| 113 | + // assert lock.isHeldByCurrentThread(); | |
| 114 | + try { | |
| 115 | + flusher.flushNow(); | |
| 116 | + } catch (Exception e) { | |
| 117 | + System.err.println("exception in flushNow:"); | |
| 118 | + e.printStackTrace(); | |
| 119 | + } | |
| 120 | + } | |
| 121 | + | |
| 122 | + public void flushAndInvokeNow(Runnable r) { | |
| 123 | + // assert lock.isHeldByCurrentThread(); | |
| 124 | + try { | |
| 125 | + flusher.flushAndInvokeNow(r); | |
| 126 | + } catch (Exception e) { | |
| 127 | + System.err.println("exception in flushAndInvokeNow:"); | |
| 128 | + e.printStackTrace(); | |
| 129 | + } | |
| 130 | + } | |
| 131 | + | |
| 132 | + private native void flushBuffer(long buf, int limit); | |
| 133 | + | |
| 134 | + private void flushBuffer() { | |
| 135 | + // assert lock.isHeldByCurrentThread(); | |
| 136 | + int limit = buf.position(); | |
| 137 | + if (limit > 0) { | |
| 138 | + // process the queue | |
| 139 | + flushBuffer(buf.getAddress(), limit); | |
| 140 | + } | |
| 141 | + // reset the buffer position | |
| 142 | + buf.clear(); | |
| 143 | + // clear the set of references, since we no longer need them | |
| 144 | + refSet.clear(); | |
| 145 | + } | |
| 146 | + | |
| 147 | + private class QueueFlusher extends Thread { | |
| 148 | + private boolean needsFlush; | |
| 149 | + private Runnable task; | |
| 150 | + private Error error; | |
| 151 | + | |
| 152 | + public QueueFlusher() { | |
| 153 | + super("Java2D Queue Flusher"); | |
| 154 | + setDaemon(true); | |
| 155 | + setPriority(Thread.MAX_PRIORITY); | |
| 156 | + start(); | |
| 157 | + } | |
| 158 | + | |
| 159 | + public synchronized void flushNow() { | |
| 160 | + // wake up the flusher | |
| 161 | + needsFlush = true; | |
| 162 | + notify(); | |
| 163 | + | |
| 164 | + // wait for flush to complete | |
| 165 | + while (needsFlush) { | |
| 166 | + try { | |
| 167 | + wait(); | |
| 168 | + } catch (InterruptedException e) { | |
| 169 | + } | |
| 170 | + } | |
| 171 | + | |
| 172 | + // re-throw any error that may have occurred during the flush | |
| 173 | + if (error != null) { | |
| 174 | + throw error; | |
| 175 | + } | |
| 176 | + } | |
| 177 | + | |
| 178 | + public synchronized void flushAndInvokeNow(Runnable task) { | |
| 179 | + this.task = task; | |
| 180 | + flushNow(); | |
| 181 | + } | |
| 182 | + | |
| 183 | + public synchronized void run() { | |
| 184 | + boolean timedOut = false; | |
| 185 | + while (true) { | |
| 186 | + while (!needsFlush) { | |
| 187 | + try { | |
| 188 | + timedOut = false; | |
| 189 | + /* | |
| 190 | + * Wait until we're woken up with a flushNow() call, | |
| 191 | + * or the timeout period elapses (so that we can | |
| 192 | + * flush the queue periodically). | |
| 193 | + */ | |
| 194 | + wait(100); | |
| 195 | + /* | |
| 196 | + * We will automatically flush the queue if the | |
| 197 | + * following conditions apply: | |
| 198 | + * - the wait() timed out | |
| 199 | + * - we can lock the queue (without blocking) | |
| 200 | + * - there is something in the queue to flush | |
| 201 | + * Otherwise, just continue (we'll flush eventually). | |
| 202 | + */ | |
| 203 | + if (!needsFlush && (timedOut = tryLock())) { | |
| 204 | + if (buf.position() > 0) { | |
| 205 | + needsFlush = true; | |
| 206 | + } else { | |
| 207 | + unlock(); | |
| 208 | + } | |
| 209 | + } | |
| 210 | + } catch (InterruptedException e) { | |
| 211 | + } | |
| 212 | + } | |
| 213 | + try { | |
| 214 | + // reset the throwable state | |
| 215 | + error = null; | |
| 216 | + // flush the buffer now | |
| 217 | + flushBuffer(); | |
| 218 | + // if there's a task, invoke that now as well | |
| 219 | + if (task != null) { | |
| 220 | + task.run(); | |
| 221 | + } | |
| 222 | + } catch (Error e) { | |
| 223 | + error = e; | |
| 224 | + } catch (Exception x) { | |
| 225 | + System.err.println("exception in QueueFlusher:"); | |
| 226 | + x.printStackTrace(); | |
| 227 | + } finally { | |
| 228 | + if (timedOut) { | |
| 229 | + unlock(); | |
| 230 | + } | |
| 231 | + task = null; | |
| 232 | + // allow the waiting thread to continue | |
| 233 | + needsFlush = false; | |
| 234 | + notify(); | |
| 235 | + } | |
| 236 | + } | |
| 237 | + } | |
| 238 | + } | |
| 239 | +} | |
| @@ -0,0 +1,206 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2008, 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.Transparency; | |
| 29 | +import java.awt.geom.Path2D; | |
| 30 | +import sun.java2d.SunGraphics2D; | |
| 31 | +import sun.java2d.loops.GraphicsPrimitive; | |
| 32 | +import sun.java2d.pipe.BufferedRenderPipe; | |
| 33 | +import sun.java2d.pipe.ParallelogramPipe; | |
| 34 | +import sun.java2d.pipe.RenderQueue; | |
| 35 | +import sun.java2d.pipe.SpanIterator; | |
| 36 | +import static sun.java2d.pipe.BufferedOpCodes.*; | |
| 37 | + | |
| 38 | +class OGLRenderer extends BufferedRenderPipe { | |
| 39 | + | |
| 40 | + OGLRenderer(RenderQueue rq) { | |
| 41 | + super(rq); | |
| 42 | + } | |
| 43 | + | |
| 44 | + @Override | |
| 45 | + protected void validateContext(SunGraphics2D sg2d) { | |
| 46 | + int ctxflags = | |
| 47 | + sg2d.paint.getTransparency() == Transparency.OPAQUE ? | |
| 48 | + OGLContext.SRC_IS_OPAQUE : OGLContext.NO_CONTEXT_FLAGS; | |
| 49 | + OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; | |
| 50 | + OGLContext.validateContext(dstData, dstData, | |
| 51 | + sg2d.getCompClip(), sg2d.composite, | |
| 52 | + null, sg2d.paint, sg2d, ctxflags); | |
| 53 | + } | |
| 54 | + | |
| 55 | + @Override | |
| 56 | + protected void validateContextAA(SunGraphics2D sg2d) { | |
| 57 | + int ctxflags = OGLContext.NO_CONTEXT_FLAGS; | |
| 58 | + OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; | |
| 59 | + OGLContext.validateContext(dstData, dstData, | |
| 60 | + sg2d.getCompClip(), sg2d.composite, | |
| 61 | + null, sg2d.paint, sg2d, ctxflags); | |
| 62 | + } | |
| 63 | + | |
| 64 | + void copyArea(SunGraphics2D sg2d, | |
| 65 | + int x, int y, int w, int h, int dx, int dy) | |
| 66 | + { | |
| 67 | + rq.lock(); | |
| 68 | + try { | |
| 69 | + int ctxflags = | |
| 70 | + sg2d.surfaceData.getTransparency() == Transparency.OPAQUE ? | |
| 71 | + OGLContext.SRC_IS_OPAQUE : OGLContext.NO_CONTEXT_FLAGS; | |
| 72 | + OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData; | |
| 73 | + OGLContext.validateContext(dstData, dstData, | |
| 74 | + sg2d.getCompClip(), sg2d.composite, | |
| 75 | + null, null, null, ctxflags); | |
| 76 | + | |
| 77 | + rq.ensureCapacity(28); | |
| 78 | + buf.putInt(COPY_AREA); | |
| 79 | + buf.putInt(x).putInt(y).putInt(w).putInt(h); | |
| 80 | + buf.putInt(dx).putInt(dy); | |
| 81 | + } finally { | |
| 82 | + rq.unlock(); | |
| 83 | + } | |
| 84 | + } | |
| 85 | + | |
| 86 | + @Override | |
| 87 | + protected native void drawPoly(int[] xPoints, int[] yPoints, | |
| 88 | + int nPoints, boolean isClosed, | |
| 89 | + int transX, int transY); | |
| 90 | + | |
| 91 | + OGLRenderer traceWrap() { | |
| 92 | + return new Tracer(this); | |
| 93 | + } | |
| 94 | + | |
| 95 | + private class Tracer extends OGLRenderer { | |
| 96 | + private OGLRenderer oglr; | |
| 97 | + Tracer(OGLRenderer oglr) { | |
| 98 | + super(oglr.rq); | |
| 99 | + this.oglr = oglr; | |
| 100 | + } | |
| 101 | + public ParallelogramPipe getAAParallelogramPipe() { | |
| 102 | + final ParallelogramPipe realpipe = oglr.getAAParallelogramPipe(); | |
| 103 | + return new ParallelogramPipe() { | |
| 104 | + public void fillParallelogram(SunGraphics2D sg2d, | |
| 105 | + double ux1, double uy1, | |
| 106 | + double ux2, double uy2, | |
| 107 | + double x, double y, | |
| 108 | + double dx1, double dy1, | |
| 109 | + double dx2, double dy2) | |
| 110 | + { | |
| 111 | + GraphicsPrimitive.tracePrimitive("OGLFillAAParallelogram"); | |
| 112 | + realpipe.fillParallelogram(sg2d, | |
| 113 | + ux1, uy1, ux2, uy2, | |
| 114 | + x, y, dx1, dy1, dx2, dy2); | |
| 115 | + } | |
| 116 | + public void drawParallelogram(SunGraphics2D sg2d, | |
| 117 | + double ux1, double uy1, | |
| 118 | + double ux2, double uy2, | |
| 119 | + double x, double y, | |
| 120 | + double dx1, double dy1, | |
| 121 | + double dx2, double dy2, | |
| 122 | + double lw1, double lw2) | |
| 123 | + { | |
| 124 | + GraphicsPrimitive.tracePrimitive("OGLDrawAAParallelogram"); | |
| 125 | + realpipe.drawParallelogram(sg2d, | |
| 126 | + ux1, uy1, ux2, uy2, | |
| 127 | + x, y, dx1, dy1, dx2, dy2, | |
| 128 | + lw1, lw2); | |
| 129 | + } | |
| 130 | + }; | |
| 131 | + } | |
| 132 | + protected void validateContext(SunGraphics2D sg2d) { | |
| 133 | + oglr.validateContext(sg2d); | |
| 134 | + } | |
| 135 | + public void drawLine(SunGraphics2D sg2d, | |
| 136 | + int x1, int y1, int x2, int y2) | |
| 137 | + { | |
| 138 | + GraphicsPrimitive.tracePrimitive("OGLDrawLine"); | |
| 139 | + oglr.drawLine(sg2d, x1, y1, x2, y2); | |
| 140 | + } | |
| 141 | + public void drawRect(SunGraphics2D sg2d, int x, int y, int w, int h) { | |
| 142 | + GraphicsPrimitive.tracePrimitive("OGLDrawRect"); | |
| 143 | + oglr.drawRect(sg2d, x, y, w, h); | |
| 144 | + } | |
| 145 | + protected void drawPoly(SunGraphics2D sg2d, | |
| 146 | + int[] xPoints, int[] yPoints, | |
| 147 | + int nPoints, boolean isClosed) | |
| 148 | + { | |
| 149 | + GraphicsPrimitive.tracePrimitive("OGLDrawPoly"); | |
| 150 | + oglr.drawPoly(sg2d, xPoints, yPoints, nPoints, isClosed); | |
| 151 | + } | |
| 152 | + public void fillRect(SunGraphics2D sg2d, int x, int y, int w, int h) { | |
| 153 | + GraphicsPrimitive.tracePrimitive("OGLFillRect"); | |
| 154 | + oglr.fillRect(sg2d, x, y, w, h); | |
| 155 | + } | |
| 156 | + protected void drawPath(SunGraphics2D sg2d, | |
| 157 | + Path2D.Float p2df, int transx, int transy) | |
| 158 | + { | |
| 159 | + GraphicsPrimitive.tracePrimitive("OGLDrawPath"); | |
| 160 | + oglr.drawPath(sg2d, p2df, transx, transy); | |
| 161 | + } | |
| 162 | + protected void fillPath(SunGraphics2D sg2d, | |
| 163 | + Path2D.Float p2df, int transx, int transy) | |
| 164 | + { | |
| 165 | + GraphicsPrimitive.tracePrimitive("OGLFillPath"); | |
| 166 | + oglr.fillPath(sg2d, p2df, transx, transy); | |
| 167 | + } | |
| 168 | + protected void fillSpans(SunGraphics2D sg2d, SpanIterator si, | |
| 169 | + int transx, int transy) | |
| 170 | + { | |
| 171 | + GraphicsPrimitive.tracePrimitive("OGLFillSpans"); | |
| 172 | + oglr.fillSpans(sg2d, si, transx, transy); | |
| 173 | + } | |
| 174 | + public void fillParallelogram(SunGraphics2D sg2d, | |
| 175 | + double ux1, double uy1, | |
| 176 | + double ux2, double uy2, | |
| 177 | + double x, double y, | |
| 178 | + double dx1, double dy1, | |
| 179 | + double dx2, double dy2) | |
| 180 | + { | |
| 181 | + GraphicsPrimitive.tracePrimitive("OGLFillParallelogram"); | |
| 182 | + oglr.fillParallelogram(sg2d, | |
| 183 | + ux1, uy1, ux2, uy2, | |
| 184 | + x, y, dx1, dy1, dx2, dy2); | |
| 185 | + } | |
| 186 | + public void drawParallelogram(SunGraphics2D sg2d, | |
| 187 | + double ux1, double uy1, | |
| 188 | + double ux2, double uy2, | |
| 189 | + double x, double y, | |
| 190 | + double dx1, double dy1, | |
| 191 | + double dx2, double dy2, | |
| 192 | + double lw1, double lw2) | |
| 193 | + { | |
| 194 | + GraphicsPrimitive.tracePrimitive("OGLDrawParallelogram"); | |
| 195 | + oglr.drawParallelogram(sg2d, | |
| 196 | + ux1, uy1, ux2, uy2, | |
| 197 | + x, y, dx1, dy1, dx2, dy2, lw1, lw2); | |
| 198 | + } | |
| 199 | + public void copyArea(SunGraphics2D sg2d, | |
| 200 | + int x, int y, int w, int h, int dx, int dy) | |
| 201 | + { | |
| 202 | + GraphicsPrimitive.tracePrimitive("OGLCopyArea"); | |
| 203 | + oglr.copyArea(sg2d, x, y, w, h, dx, dy); | |
| 204 | + } | |
| 205 | + } | |
| 206 | +} | |
| @@ -0,0 +1,653 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2008, 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.GraphicsEnvironment; | |
| 30 | +import java.awt.Rectangle; | |
| 31 | +import java.awt.Transparency; | |
| 32 | +import java.awt.image.ColorModel; | |
| 33 | +import java.awt.image.Raster; | |
| 34 | +import sun.awt.SunHints; | |
| 35 | +import sun.awt.image.PixelConverter; | |
| 36 | +import sun.java2d.pipe.hw.AccelSurface; | |
| 37 | +import sun.java2d.SunGraphics2D; | |
| 38 | +import sun.java2d.SurfaceData; | |
| 39 | +import sun.java2d.SurfaceDataProxy; | |
| 40 | +import sun.java2d.loops.CompositeType; | |
| 41 | +import sun.java2d.loops.GraphicsPrimitive; | |
| 42 | +import sun.java2d.loops.MaskFill; | |
| 43 | +import sun.java2d.loops.SurfaceType; | |
| 44 | +import sun.java2d.pipe.ParallelogramPipe; | |
| 45 | +import sun.java2d.pipe.PixelToParallelogramConverter; | |
| 46 | +import sun.java2d.pipe.RenderBuffer; | |
| 47 | +import sun.java2d.pipe.TextPipe; | |
| 48 | +import static sun.java2d.pipe.BufferedOpCodes.*; | |
| 49 | +import static sun.java2d.opengl.OGLContext.OGLContextCaps.*; | |
| 50 | + | |
| 51 | +/** | |
| 52 | + * This class describes an OpenGL "surface", that is, a region of pixels | |
| 53 | + * managed via OpenGL. An OGLSurfaceData can be tagged with one of three | |
| 54 | + * different SurfaceType objects for the purpose of registering loops, etc. | |
| 55 | + * This diagram shows the hierarchy of OGL SurfaceTypes: | |
| 56 | + * | |
| 57 | + * Any | |
| 58 | + * / \ | |
| 59 | + * OpenGLSurface OpenGLTexture | |
| 60 | + * | | |
| 61 | + * OpenGLSurfaceRTT | |
| 62 | + * | |
| 63 | + * OpenGLSurface | |
| 64 | + * This kind of surface can be rendered to using OpenGL APIs. It is also | |
| 65 | + * possible to copy an OpenGLSurface to another OpenGLSurface (or to itself). | |
| 66 | + * This is typically accomplished by calling MakeContextCurrent(dstSD, srcSD) | |
| 67 | + * and then calling glCopyPixels() (although there are other techniques to | |
| 68 | + * achieve the same goal). | |
| 69 | + * | |
| 70 | + * OpenGLTexture | |
| 71 | + * This kind of surface cannot be rendered to using OpenGL (in the same sense | |
| 72 | + * as in OpenGLSurface). However, it is possible to upload a region of pixels | |
| 73 | + * to an OpenGLTexture object via glTexSubImage2D(). One can also copy a | |
| 74 | + * surface of type OpenGLTexture to an OpenGLSurface by binding the texture | |
| 75 | + * to a quad and then rendering it to the destination surface (this process | |
| 76 | + * is known as "texture mapping"). | |
| 77 | + * | |
| 78 | + * OpenGLSurfaceRTT | |
| 79 | + * This kind of surface can be thought of as a sort of hybrid between | |
| 80 | + * OpenGLSurface and OpenGLTexture, in that one can render to this kind of | |
| 81 | + * surface as if it were of type OpenGLSurface, but the process of copying | |
| 82 | + * this kind of surface to another is more like an OpenGLTexture. (Note that | |
| 83 | + * "RTT" stands for "render-to-texture".) | |
| 84 | + * | |
| 85 | + * In addition to these SurfaceType variants, we have also defined some | |
| 86 | + * constants that describe in more detail the type of underlying OpenGL | |
| 87 | + * surface. This table helps explain the relationships between those | |
| 88 | + * "type" constants and their corresponding SurfaceType: | |
| 89 | + * | |
| 90 | + * OGL Type Corresponding SurfaceType | |
| 91 | + * -------- ------------------------- | |
| 92 | + * WINDOW OpenGLSurface | |
| 93 | + * PBUFFER OpenGLSurface | |
| 94 | + * TEXTURE OpenGLTexture | |
| 95 | + * FLIP_BACKBUFFER OpenGLSurface | |
| 96 | + * FBOBJECT OpenGLSurfaceRTT | |
| 97 | + */ | |
| 98 | +public abstract class OGLSurfaceData extends SurfaceData | |
| 99 | + implements AccelSurface { | |
| 100 | + | |
| 101 | + /** | |
| 102 | + * OGL-specific surface types | |
| 103 | + * | |
| 104 | + * @see sun.java2d.pipe.hw.AccelSurface | |
| 105 | + */ | |
| 106 | + public static final int PBUFFER = RT_PLAIN; | |
| 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 | + | |
| 165 | + protected native boolean initTexture(long pData, | |
| 166 | + boolean isOpaque, boolean texNonPow2, | |
| 167 | + boolean texRect, | |
| 168 | + int width, int height); | |
| 169 | + protected native boolean initFBObject(long pData, | |
| 170 | + boolean isOpaque, boolean texNonPow2, | |
| 171 | + boolean texRect, | |
| 172 | + int width, int height); | |
| 173 | + protected native boolean initFlipBackbuffer(long pData); | |
| 174 | + protected abstract boolean initPbuffer(long pData, long pConfigInfo, | |
| 175 | + boolean isOpaque, | |
| 176 | + int width, int height); | |
| 177 | + | |
| 178 | + private native int getTextureTarget(long pData); | |
| 179 | + private native int getTextureID(long pData); | |
| 180 | + | |
| 181 | + static { | |
| 182 | + if (!GraphicsEnvironment.isHeadless()) { | |
| 183 | + // fbobject currently enabled by default; use "false" to disable | |
| 184 | + String fbo = (String)java.security.AccessController.doPrivileged( | |
| 185 | + new sun.security.action.GetPropertyAction( | |
| 186 | + "sun.java2d.opengl.fbobject")); | |
| 187 | + isFBObjectEnabled = !"false".equals(fbo); | |
| 188 | + | |
| 189 | + // lcdshader currently enabled by default; use "false" to disable | |
| 190 | + String lcd = (String)java.security.AccessController.doPrivileged( | |
| 191 | + new sun.security.action.GetPropertyAction( | |
| 192 | + "sun.java2d.opengl.lcdshader")); | |
| 193 | + isLCDShaderEnabled = !"false".equals(lcd); | |
| 194 | + | |
| 195 | + // biopshader currently enabled by default; use "false" to disable | |
| 196 | + String biop = (String)java.security.AccessController.doPrivileged( | |
| 197 | + new sun.security.action.GetPropertyAction( | |
| 198 | + "sun.java2d.opengl.biopshader")); | |
| 199 | + isBIOpShaderEnabled = !"false".equals(biop); | |
| 200 | + | |
| 201 | + // gradshader currently enabled by default; use "false" to disable | |
| 202 | + String grad = (String)java.security.AccessController.doPrivileged( | |
| 203 | + new sun.security.action.GetPropertyAction( | |
| 204 | + "sun.java2d.opengl.gradshader")); | |
| 205 | + isGradShaderEnabled = !"false".equals(grad); | |
| 206 | + | |
| 207 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 208 | + oglImagePipe = new OGLDrawImage(); | |
| 209 | + oglTextPipe = new OGLTextRenderer(rq); | |
| 210 | + oglRenderPipe = new OGLRenderer(rq); | |
| 211 | + if (GraphicsPrimitive.tracingEnabled()) { | |
| 212 | + oglTextPipe = oglTextPipe.traceWrap(); | |
| 213 | + //The wrapped oglRenderPipe will wrap the AA pipe as well... | |
| 214 | + //oglAAPgramPipe = oglRenderPipe.traceWrap(); | |
| 215 | + } | |
| 216 | + oglAAPgramPipe = oglRenderPipe.getAAParallelogramPipe(); | |
| 217 | + oglTxRenderPipe = | |
| 218 | + new PixelToParallelogramConverter(oglRenderPipe, | |
| 219 | + oglRenderPipe, | |
| 220 | + 1.0, 0.25, true); | |
| 221 | + | |
| 222 | + OGLBlitLoops.register(); | |
| 223 | + OGLMaskFill.register(); | |
| 224 | + OGLMaskBlit.register(); | |
| 225 | + } | |
| 226 | + } | |
| 227 | + | |
| 228 | + protected OGLSurfaceData(OGLGraphicsConfig gc, | |
| 229 | + ColorModel cm, int type) | |
| 230 | + { | |
| 231 | + super(getCustomSurfaceType(type), cm); | |
| 232 | + this.graphicsConfig = gc; | |
| 233 | + this.type = type; | |
| 234 | + setBlitProxyKey(gc.getProxyKey()); | |
| 235 | + } | |
| 236 | + | |
| 237 | + @Override | |
| 238 | + public SurfaceDataProxy makeProxyFor(SurfaceData srcData) { | |
| 239 | + return OGLSurfaceDataProxy.createProxy(srcData, graphicsConfig); | |
| 240 | + } | |
| 241 | + | |
| 242 | + /** | |
| 243 | + * Returns the appropriate SurfaceType corresponding to the given OpenGL | |
| 244 | + * surface type constant (e.g. TEXTURE -> OpenGLTexture). | |
| 245 | + */ | |
| 246 | + private static SurfaceType getCustomSurfaceType(int oglType) { | |
| 247 | + switch (oglType) { | |
| 248 | + case TEXTURE: | |
| 249 | + return OpenGLTexture; | |
| 250 | + case FBOBJECT: | |
| 251 | + return OpenGLSurfaceRTT; | |
| 252 | + case PBUFFER: | |
| 253 | + default: | |
| 254 | + return OpenGLSurface; | |
| 255 | + } | |
| 256 | + } | |
| 257 | + | |
| 258 | + /** | |
| 259 | + * Note: This should only be called from the QFT under the AWT lock. | |
| 260 | + * This method is kept separate from the initSurface() method below just | |
| 261 | + * to keep the code a bit cleaner. | |
| 262 | + */ | |
| 263 | + private void initSurfaceNow(int width, int height) { | |
| 264 | + boolean isOpaque = (getTransparency() == Transparency.OPAQUE); | |
| 265 | + boolean success = false; | |
| 266 | + | |
| 267 | + switch (type) { | |
| 268 | + case PBUFFER: | |
| 269 | + success = initPbuffer(getNativeOps(), | |
| 270 | + graphicsConfig.getNativeConfigInfo(), | |
| 271 | + isOpaque, | |
| 272 | + width, height); | |
| 273 | + break; | |
| 274 | + | |
| 275 | + case TEXTURE: | |
| 276 | + success = initTexture(getNativeOps(), | |
| 277 | + isOpaque, isTexNonPow2Available(), | |
| 278 | + isTexRectAvailable(), | |
| 279 | + width, height); | |
| 280 | + break; | |
| 281 | + | |
| 282 | + case FBOBJECT: | |
| 283 | + success = initFBObject(getNativeOps(), | |
| 284 | + isOpaque, isTexNonPow2Available(), | |
| 285 | + isTexRectAvailable(), | |
| 286 | + width, height); | |
| 287 | + break; | |
| 288 | + | |
| 289 | + case FLIP_BACKBUFFER: | |
| 290 | + success = initFlipBackbuffer(getNativeOps()); | |
| 291 | + break; | |
| 292 | + | |
| 293 | + default: | |
| 294 | + break; | |
| 295 | + } | |
| 296 | + | |
| 297 | + if (!success) { | |
| 298 | + throw new OutOfMemoryError("can't create offscreen surface"); | |
| 299 | + } | |
| 300 | + } | |
| 301 | + | |
| 302 | + /** | |
| 303 | + * Initializes the appropriate OpenGL offscreen surface based on the value | |
| 304 | + * of the type parameter. If the surface creation fails for any reason, | |
| 305 | + * an OutOfMemoryError will be thrown. | |
| 306 | + */ | |
| 307 | + protected void initSurface(final int width, final int height) { | |
| 308 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 309 | + rq.lock(); | |
| 310 | + try { | |
| 311 | + switch (type) { | |
| 312 | + case TEXTURE: | |
| 313 | + case PBUFFER: | |
| 314 | + case FBOBJECT: | |
| 315 | + // need to make sure the context is current before | |
| 316 | + // creating the texture (or pbuffer, or fbobject) | |
| 317 | + OGLContext.setScratchSurface(graphicsConfig); | |
| 318 | + break; | |
| 319 | + default: | |
| 320 | + break; | |
| 321 | + } | |
| 322 | + rq.flushAndInvokeNow(new Runnable() { | |
| 323 | + public void run() { | |
| 324 | + initSurfaceNow(width, height); | |
| 325 | + } | |
| 326 | + }); | |
| 327 | + } finally { | |
| 328 | + rq.unlock(); | |
| 329 | + } | |
| 330 | + } | |
| 331 | + | |
| 332 | + /** | |
| 333 | + * Returns the OGLContext for the GraphicsConfig associated with this | |
| 334 | + * surface. | |
| 335 | + */ | |
| 336 | + public final OGLContext getContext() { | |
| 337 | + return graphicsConfig.getContext(); | |
| 338 | + } | |
| 339 | + | |
| 340 | + /** | |
| 341 | + * Returns the OGLGraphicsConfig associated with this surface. | |
| 342 | + */ | |
| 343 | + final OGLGraphicsConfig getOGLGraphicsConfig() { | |
| 344 | + return graphicsConfig; | |
| 345 | + } | |
| 346 | + | |
| 347 | + /** | |
| 348 | + * Returns one of the surface type constants defined above. | |
| 349 | + */ | |
| 350 | + public final int getType() { | |
| 351 | + return type; | |
| 352 | + } | |
| 353 | + | |
| 354 | + /** | |
| 355 | + * If this surface is backed by a texture object, returns the target | |
| 356 | + * for that texture (either GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB). | |
| 357 | + * Otherwise, this method will return zero. | |
| 358 | + */ | |
| 359 | + public final int getTextureTarget() { | |
| 360 | + return getTextureTarget(getNativeOps()); | |
| 361 | + } | |
| 362 | + | |
| 363 | + /** | |
| 364 | + * If this surface is backed by a texture object, returns the texture ID | |
| 365 | + * for that texture. | |
| 366 | + * Otherwise, this method will return zero. | |
| 367 | + */ | |
| 368 | + public final int getTextureID() { | |
| 369 | + return getTextureID(getNativeOps()); | |
| 370 | + } | |
| 371 | + | |
| 372 | + /** | |
| 373 | + * Returns native resource of specified {@code resType} associated with | |
| 374 | + * this surface. | |
| 375 | + * | |
| 376 | + * Specifically, for {@code OGLSurfaceData} this method returns the | |
| 377 | + * the following: | |
| 378 | + * <pre> | |
| 379 | + * TEXTURE - texture id | |
| 380 | + * </pre> | |
| 381 | + * | |
| 382 | + * Note: the resource returned by this method is only valid on the rendering | |
| 383 | + * thread. | |
| 384 | + * | |
| 385 | + * @return native resource of specified type or 0L if | |
| 386 | + * such resource doesn't exist or can not be retrieved. | |
| 387 | + * @see sun.java2d.pipe.hw.AccelSurface#getNativeResource | |
| 388 | + */ | |
| 389 | + public long getNativeResource(int resType) { | |
| 390 | + if (resType == TEXTURE) { | |
| 391 | + return getTextureID(); | |
| 392 | + } | |
| 393 | + return 0L; | |
| 394 | + } | |
| 395 | + | |
| 396 | + public Raster getRaster(int x, int y, int w, int h) { | |
| 397 | + throw new InternalError("not implemented yet"); | |
| 398 | + } | |
| 399 | + | |
| 400 | + /** | |
| 401 | + * For now, we can only render LCD text if: | |
| 402 | + * - the fragment shader extension is available, and | |
| 403 | + * - blending is disabled, and | |
| 404 | + * - the source color is opaque | |
| 405 | + * - and the destination is opaque | |
| 406 | + * | |
| 407 | + * Eventually, we could enhance the native OGL text rendering code | |
| 408 | + * and remove the above restrictions, but that would require significantly | |
| 409 | + * more code just to support a few uncommon cases. | |
| 410 | + */ | |
| 411 | + public boolean canRenderLCDText(SunGraphics2D sg2d) { | |
| 412 | + return | |
| 413 | + graphicsConfig.isCapPresent(CAPS_EXT_LCD_SHADER) && | |
| 414 | + sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY && | |
| 415 | + sg2d.paintState <= SunGraphics2D.PAINT_OPAQUECOLOR && | |
| 416 | + sg2d.surfaceData.getTransparency() == Transparency.OPAQUE; | |
| 417 | + } | |
| 418 | + | |
| 419 | + public void validatePipe(SunGraphics2D sg2d) { | |
| 420 | + TextPipe textpipe; | |
| 421 | + boolean validated = false; | |
| 422 | + | |
| 423 | + // OGLTextRenderer handles both AA and non-AA text, but | |
| 424 | + // only works with the following modes: | |
| 425 | + // (Note: For LCD text we only enter this code path if | |
| 426 | + // canRenderLCDText() has already validated that the mode is | |
| 427 | + // CompositeType.SrcNoEa (opaque color), which will be subsumed | |
| 428 | + // by the CompositeType.SrcNoEa (any color) test below.) | |
| 429 | + | |
| 430 | + if (/* CompositeType.SrcNoEa (any color) */ | |
| 431 | + (sg2d.compositeState <= sg2d.COMP_ISCOPY && | |
| 432 | + sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) || | |
| 433 | + | |
| 434 | + /* CompositeType.SrcOver (any color) */ | |
| 435 | + (sg2d.compositeState == sg2d.COMP_ALPHA && | |
| 436 | + sg2d.paintState <= sg2d.PAINT_ALPHACOLOR && | |
| 437 | + (((AlphaComposite)sg2d.composite).getRule() == | |
| 438 | + AlphaComposite.SRC_OVER)) || | |
| 439 | + | |
| 440 | + /* CompositeType.Xor (any color) */ | |
| 441 | + (sg2d.compositeState == sg2d.COMP_XOR && | |
| 442 | + sg2d.paintState <= sg2d.PAINT_ALPHACOLOR)) | |
| 443 | + { | |
| 444 | + textpipe = oglTextPipe; | |
| 445 | + } else { | |
| 446 | + // do this to initialize textpipe correctly; we will attempt | |
| 447 | + // to override the non-text pipes below | |
| 448 | + super.validatePipe(sg2d); | |
| 449 | + textpipe = sg2d.textpipe; | |
| 450 | + validated = true; | |
| 451 | + } | |
| 452 | + | |
| 453 | + PixelToParallelogramConverter txPipe = null; | |
| 454 | + OGLRenderer nonTxPipe = null; | |
| 455 | + | |
| 456 | + if (sg2d.antialiasHint != SunHints.INTVAL_ANTIALIAS_ON) { | |
| 457 | + if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) { | |
| 458 | + if (sg2d.compositeState <= sg2d.COMP_XOR) { | |
| 459 | + txPipe = oglTxRenderPipe; | |
| 460 | + nonTxPipe = oglRenderPipe; | |
| 461 | + } | |
| 462 | + } else if (sg2d.compositeState <= sg2d.COMP_ALPHA) { | |
| 463 | + if (OGLPaints.isValid(sg2d)) { | |
| 464 | + txPipe = oglTxRenderPipe; | |
| 465 | + nonTxPipe = oglRenderPipe; | |
| 466 | + } | |
| 467 | + // custom paints handled by super.validatePipe() below | |
| 468 | + } | |
| 469 | + } else { | |
| 470 | + if (sg2d.paintState <= sg2d.PAINT_ALPHACOLOR) { | |
| 471 | + if (graphicsConfig.isCapPresent(CAPS_PS30) && | |
| 472 | + (sg2d.imageComp == CompositeType.SrcOverNoEa || | |
| 473 | + sg2d.imageComp == CompositeType.SrcOver)) | |
| 474 | + { | |
| 475 | + if (!validated) { | |
| 476 | + super.validatePipe(sg2d); | |
| 477 | + validated = true; | |
| 478 | + } | |
| 479 | + PixelToParallelogramConverter aaConverter = | |
| 480 | + new PixelToParallelogramConverter(sg2d.shapepipe, | |
| 481 | + oglAAPgramPipe, | |
| 482 | + 1.0/8.0, 0.499, | |
| 483 | + false); | |
| 484 | + sg2d.drawpipe = aaConverter; | |
| 485 | + sg2d.fillpipe = aaConverter; | |
| 486 | + sg2d.shapepipe = aaConverter; | |
| 487 | + } else if (sg2d.compositeState == sg2d.COMP_XOR) { | |
| 488 | + // install the solid pipes when AA and XOR are both enabled | |
| 489 | + txPipe = oglTxRenderPipe; | |
| 490 | + nonTxPipe = oglRenderPipe; | |
| 491 | + } | |
| 492 | + } | |
| 493 | + // other cases handled by super.validatePipe() below | |
| 494 | + } | |
| 495 | + | |
| 496 | + if (txPipe != null) { | |
| 497 | + if (sg2d.transformState >= sg2d.TRANSFORM_TRANSLATESCALE) { | |
| 498 | + sg2d.drawpipe = txPipe; | |
| 499 | + sg2d.fillpipe = txPipe; | |
| 500 | + } else if (sg2d.strokeState != sg2d.STROKE_THIN) { | |
| 501 | + sg2d.drawpipe = txPipe; | |
| 502 | + sg2d.fillpipe = nonTxPipe; | |
| 503 | + } else { | |
| 504 | + sg2d.drawpipe = nonTxPipe; | |
| 505 | + sg2d.fillpipe = nonTxPipe; | |
| 506 | + } | |
| 507 | + // Note that we use the transforming pipe here because it | |
| 508 | + // will examine the shape and possibly perform an optimized | |
| 509 | + // operation if it can be simplified. The simplifications | |
| 510 | + // will be valid for all STROKE and TRANSFORM types. | |
| 511 | + sg2d.shapepipe = txPipe; | |
| 512 | + } else { | |
| 513 | + if (!validated) { | |
| 514 | + super.validatePipe(sg2d); | |
| 515 | + } | |
| 516 | + } | |
| 517 | + | |
| 518 | + // install the text pipe based on our earlier decision | |
| 519 | + sg2d.textpipe = textpipe; | |
| 520 | + | |
| 521 | + // always override the image pipe with the specialized OGL pipe | |
| 522 | + sg2d.imagepipe = oglImagePipe; | |
| 523 | + } | |
| 524 | + | |
| 525 | + @Override | |
| 526 | + protected MaskFill getMaskFill(SunGraphics2D sg2d) { | |
| 527 | + if (sg2d.paintState > sg2d.PAINT_ALPHACOLOR) { | |
| 528 | + /* | |
| 529 | + * We can only accelerate non-Color MaskFill operations if | |
| 530 | + * all of the following conditions hold true: | |
| 531 | + * - there is an implementation for the given paintState | |
| 532 | + * - the current Paint can be accelerated for this destination | |
| 533 | + * - multitexturing is available (since we need to modulate | |
| 534 | + * the alpha mask texture with the paint texture) | |
| 535 | + * | |
| 536 | + * In all other cases, we return null, in which case the | |
| 537 | + * validation code will choose a more general software-based loop. | |
| 538 | + */ | |
| 539 | + if (!OGLPaints.isValid(sg2d) || | |
| 540 | + !graphicsConfig.isCapPresent(CAPS_MULTITEXTURE)) | |
| 541 | + { | |
| 542 | + return null; | |
| 543 | + } | |
| 544 | + } | |
| 545 | + return super.getMaskFill(sg2d); | |
| 546 | + } | |
| 547 | + | |
| 548 | + public boolean copyArea(SunGraphics2D sg2d, | |
| 549 | + int x, int y, int w, int h, int dx, int dy) | |
| 550 | + { | |
| 551 | + if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE && | |
| 552 | + sg2d.compositeState < sg2d.COMP_XOR) | |
| 553 | + { | |
| 554 | + x += sg2d.transX; | |
| 555 | + y += sg2d.transY; | |
| 556 | + | |
| 557 | + oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy); | |
| 558 | + | |
| 559 | + return true; | |
| 560 | + } | |
| 561 | + return false; | |
| 562 | + } | |
| 563 | + | |
| 564 | + public void flush() { | |
| 565 | + invalidate(); | |
| 566 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 567 | + rq.lock(); | |
| 568 | + try { | |
| 569 | + // make sure we have a current context before | |
| 570 | + // disposing the native resources (e.g. texture object) | |
| 571 | + OGLContext.setScratchSurface(graphicsConfig); | |
| 572 | + | |
| 573 | + RenderBuffer buf = rq.getBuffer(); | |
| 574 | + rq.ensureCapacityAndAlignment(12, 4); | |
| 575 | + buf.putInt(FLUSH_SURFACE); | |
| 576 | + buf.putLong(getNativeOps()); | |
| 577 | + | |
| 578 | + // this call is expected to complete synchronously, so flush now | |
| 579 | + rq.flushNow(); | |
| 580 | + } finally { | |
| 581 | + rq.unlock(); | |
| 582 | + } | |
| 583 | + } | |
| 584 | + | |
| 585 | + /** | |
| 586 | + * Disposes the native resources associated with the given OGLSurfaceData | |
| 587 | + * (referenced by the pData parameter). This method is invoked from | |
| 588 | + * the native Dispose() method from the Disposer thread when the | |
| 589 | + * Java-level OGLSurfaceData object is about to go away. Note that we | |
| 590 | + * also pass a reference to the native GLX/WGLGraphicsConfigInfo | |
| 591 | + * (pConfigInfo) for the purposes of making a context current. | |
| 592 | + */ | |
| 593 | + static void dispose(long pData, long pConfigInfo) { | |
| 594 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 595 | + rq.lock(); | |
| 596 | + try { | |
| 597 | + // make sure we have a current context before | |
| 598 | + // disposing the native resources (e.g. texture object) | |
| 599 | + OGLContext.setScratchSurface(pConfigInfo); | |
| 600 | + | |
| 601 | + RenderBuffer buf = rq.getBuffer(); | |
| 602 | + rq.ensureCapacityAndAlignment(12, 4); | |
| 603 | + buf.putInt(DISPOSE_SURFACE); | |
| 604 | + buf.putLong(pData); | |
| 605 | + | |
| 606 | + // this call is expected to complete synchronously, so flush now | |
| 607 | + rq.flushNow(); | |
| 608 | + } finally { | |
| 609 | + rq.unlock(); | |
| 610 | + } | |
| 611 | + } | |
| 612 | + | |
| 613 | + static void swapBuffers(long window) { | |
| 614 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 615 | + rq.lock(); | |
| 616 | + try { | |
| 617 | + RenderBuffer buf = rq.getBuffer(); | |
| 618 | + rq.ensureCapacityAndAlignment(12, 4); | |
| 619 | + buf.putInt(SWAP_BUFFERS); | |
| 620 | + buf.putLong(window); | |
| 621 | + rq.flushNow(); | |
| 622 | + } finally { | |
| 623 | + rq.unlock(); | |
| 624 | + } | |
| 625 | + } | |
| 626 | + | |
| 627 | + /** | |
| 628 | + * Returns true if OpenGL textures can have non-power-of-two dimensions | |
| 629 | + * when using the basic GL_TEXTURE_2D target. | |
| 630 | + */ | |
| 631 | + boolean isTexNonPow2Available() { | |
| 632 | + return graphicsConfig.isCapPresent(CAPS_TEXNONPOW2); | |
| 633 | + } | |
| 634 | + | |
| 635 | + /** | |
| 636 | + * Returns true if OpenGL textures can have non-power-of-two dimensions | |
| 637 | + * when using the GL_TEXTURE_RECTANGLE_ARB target (only available when the | |
| 638 | + * GL_ARB_texture_rectangle extension is present). | |
| 639 | + */ | |
| 640 | + boolean isTexRectAvailable() { | |
| 641 | + return graphicsConfig.isCapPresent(CAPS_EXT_TEXRECT); | |
| 642 | + } | |
| 643 | + | |
| 644 | + public Rectangle getNativeBounds() { | |
| 645 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 646 | + rq.lock(); | |
| 647 | + try { | |
| 648 | + return new Rectangle(nativeWidth, nativeHeight); | |
| 649 | + } finally { | |
| 650 | + rq.unlock(); | |
| 651 | + } | |
| 652 | + } | |
| 653 | +} | |
| @@ -0,0 +1,81 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 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.Color; | |
| 29 | +import java.awt.Transparency; | |
| 30 | + | |
| 31 | +import sun.java2d.SurfaceData; | |
| 32 | +import sun.java2d.SurfaceDataProxy; | |
| 33 | +import sun.java2d.loops.SurfaceType; | |
| 34 | +import sun.java2d.loops.CompositeType; | |
| 35 | + | |
| 36 | +/** | |
| 37 | + * The proxy class contains the logic for when to replace a | |
| 38 | + * SurfaceData with a cached OGL Texture and the code to create | |
| 39 | + * the accelerated surfaces. | |
| 40 | + */ | |
| 41 | +public class OGLSurfaceDataProxy extends SurfaceDataProxy { | |
| 42 | + public static SurfaceDataProxy createProxy(SurfaceData srcData, | |
| 43 | + OGLGraphicsConfig dstConfig) | |
| 44 | + { | |
| 45 | + if (srcData instanceof OGLSurfaceData) { | |
| 46 | + // srcData must be a VolatileImage which either matches | |
| 47 | + // our pixel format or not - either way we do not cache it... | |
| 48 | + return UNCACHED; | |
| 49 | + } | |
| 50 | + | |
| 51 | + return new OGLSurfaceDataProxy(dstConfig, srcData.getTransparency()); | |
| 52 | + } | |
| 53 | + | |
| 54 | + OGLGraphicsConfig oglgc; | |
| 55 | + int transparency; | |
| 56 | + | |
| 57 | + public OGLSurfaceDataProxy(OGLGraphicsConfig oglgc, int transparency) { | |
| 58 | + this.oglgc = oglgc; | |
| 59 | + this.transparency = transparency; | |
| 60 | + } | |
| 61 | + | |
| 62 | + @Override | |
| 63 | + public SurfaceData validateSurfaceData(SurfaceData srcData, | |
| 64 | + SurfaceData cachedData, | |
| 65 | + int w, int h) | |
| 66 | + { | |
| 67 | + if (cachedData == null) { | |
| 68 | + cachedData = oglgc.createManagedSurface(w, h, transparency); | |
| 69 | + } | |
| 70 | + return cachedData; | |
| 71 | + } | |
| 72 | + | |
| 73 | + @Override | |
| 74 | + public boolean isSupportedOperation(SurfaceData srcData, | |
| 75 | + int txtype, | |
| 76 | + CompositeType comp, | |
| 77 | + Color bgColor) | |
| 78 | + { | |
| 79 | + return (bgColor == null || transparency == Transparency.OPAQUE); | |
| 80 | + } | |
| 81 | +} | |
| @@ -0,0 +1,71 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2003, 2006, 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.Composite; | |
| 29 | +import sun.font.GlyphList; | |
| 30 | +import sun.java2d.SunGraphics2D; | |
| 31 | +import sun.java2d.loops.GraphicsPrimitive; | |
| 32 | +import sun.java2d.pipe.BufferedTextPipe; | |
| 33 | +import sun.java2d.pipe.RenderQueue; | |
| 34 | + | |
| 35 | +class OGLTextRenderer extends BufferedTextPipe { | |
| 36 | + | |
| 37 | + OGLTextRenderer(RenderQueue rq) { | |
| 38 | + super(rq); | |
| 39 | + } | |
| 40 | + | |
| 41 | + @Override | |
| 42 | + protected native void drawGlyphList(int numGlyphs, boolean usePositions, | |
| 43 | + boolean subPixPos, boolean rgbOrder, | |
| 44 | + int lcdContrast, | |
| 45 | + float glOrigX, float glOrigY, | |
| 46 | + long[] images, float[] positions); | |
| 47 | + | |
| 48 | + @Override | |
| 49 | + protected void validateContext(SunGraphics2D sg2d, Composite comp) { | |
| 50 | + // assert rq.lock.isHeldByCurrentThread(); | |
| 51 | + OGLSurfaceData oglDst = (OGLSurfaceData)sg2d.surfaceData; | |
| 52 | + OGLContext.validateContext(oglDst, oglDst, | |
| 53 | + sg2d.getCompClip(), comp, | |
| 54 | + null, sg2d.paint, sg2d, | |
| 55 | + OGLContext.NO_CONTEXT_FLAGS); | |
| 56 | + } | |
| 57 | + | |
| 58 | + OGLTextRenderer traceWrap() { | |
| 59 | + return new Tracer(this); | |
| 60 | + } | |
| 61 | + | |
| 62 | + private static class Tracer extends OGLTextRenderer { | |
| 63 | + Tracer(OGLTextRenderer ogltr) { | |
| 64 | + super(ogltr.rq); | |
| 65 | + } | |
| 66 | + protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) { | |
| 67 | + GraphicsPrimitive.tracePrimitive("OGLDrawGlyphs"); | |
| 68 | + super.drawGlyphList(sg2d, gl); | |
| 69 | + } | |
| 70 | + } | |
| 71 | +} | |
| @@ -0,0 +1,338 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2005, 2006, 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.Graphics; | |
| 29 | +import java.awt.GraphicsConfiguration; | |
| 30 | +import java.awt.Rectangle; | |
| 31 | +import sun.java2d.SunGraphics2D; | |
| 32 | +import sun.java2d.SurfaceData; | |
| 33 | +import sun.java2d.pipe.Region; | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * This class contains a number of static utility methods that may be | |
| 37 | + * called (via reflection) by a third-party library, such as JOGL, in order | |
| 38 | + * to interoperate with the OGL-based Java 2D pipeline. | |
| 39 | + * | |
| 40 | + * WARNING: These methods are being made available as a temporary measure | |
| 41 | + * until we offer a more complete, public solution. Like any sun.* class, | |
| 42 | + * this class is not an officially supported public API; it may be modified | |
| 43 | + * at will or removed completely in a future release. | |
| 44 | + */ | |
| 45 | +class OGLUtilities { | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * These OGL-specific surface type constants are the same as those | |
| 49 | + * defined in the OGLSurfaceData class and are duplicated here so that | |
| 50 | + * clients of this API can access them more easily via reflection. | |
| 51 | + */ | |
| 52 | + public static final int UNDEFINED = OGLSurfaceData.UNDEFINED; | |
| 53 | + public static final int WINDOW = OGLSurfaceData.WINDOW; | |
| 54 | + public static final int PBUFFER = OGLSurfaceData.PBUFFER; | |
| 55 | + public static final int TEXTURE = OGLSurfaceData.TEXTURE; | |
| 56 | + public static final int FLIP_BACKBUFFER = OGLSurfaceData.FLIP_BACKBUFFER; | |
| 57 | + public static final int FBOBJECT = OGLSurfaceData.FBOBJECT; | |
| 58 | + | |
| 59 | + private OGLUtilities() { | |
| 60 | + } | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * Returns true if the current thread is the OGL QueueFlusher thread. | |
| 64 | + */ | |
| 65 | + public static boolean isQueueFlusherThread() { | |
| 66 | + return OGLRenderQueue.isQueueFlusherThread(); | |
| 67 | + } | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * Invokes the given Runnable on the OGL QueueFlusher thread with the | |
| 71 | + * OpenGL context corresponding to the given Graphics object made | |
| 72 | + * current. It is legal for OpenGL code executed in the given | |
| 73 | + * Runnable to change the current OpenGL context; it will be reset | |
| 74 | + * once the Runnable completes. No guarantees are made as to the | |
| 75 | + * state of the OpenGL context of the Graphics object; for | |
| 76 | + * example, calling code must set the scissor box using the return | |
| 77 | + * value from {@link #getOGLScissorBox} to avoid drawing | |
| 78 | + * over other Swing components, and must typically set the OpenGL | |
| 79 | + * viewport using the return value from {@link #getOGLViewport} to | |
| 80 | + * make the client's OpenGL rendering appear in the correct place | |
| 81 | + * relative to the scissor region. | |
| 82 | + * | |
| 83 | + * In order to avoid deadlock, it is important that the given Runnable | |
| 84 | + * does not attempt to acquire the AWT lock, as that will be handled | |
| 85 | + * automatically as part of the <code>rq.flushAndInvokeNow()</code> step. | |
| 86 | + * | |
| 87 | + * @param g the Graphics object for the corresponding destination surface; | |
| 88 | + * if null, the step making a context current to the destination surface | |
| 89 | + * will be skipped | |
| 90 | + * @param r the action to be performed on the QFT; cannot be null | |
| 91 | + * @return true if the operation completed successfully, or false if | |
| 92 | + * there was any problem making a context current to the surface | |
| 93 | + * associated with the given Graphics object | |
| 94 | + */ | |
| 95 | + public static boolean invokeWithOGLContextCurrent(Graphics g, Runnable r) { | |
| 96 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 97 | + rq.lock(); | |
| 98 | + try { | |
| 99 | + if (g != null) { | |
| 100 | + if (!(g instanceof SunGraphics2D)) { | |
| 101 | + return false; | |
| 102 | + } | |
| 103 | + SurfaceData sData = ((SunGraphics2D)g).surfaceData; | |
| 104 | + if (!(sData instanceof OGLSurfaceData)) { | |
| 105 | + return false; | |
| 106 | + } | |
| 107 | + | |
| 108 | + // make a context current to the destination surface | |
| 109 | + OGLContext.validateContext((OGLSurfaceData)sData); | |
| 110 | + } | |
| 111 | + | |
| 112 | + // invoke the given runnable on the QFT | |
| 113 | + rq.flushAndInvokeNow(r); | |
| 114 | + | |
| 115 | + // invalidate the current context so that the next time we render | |
| 116 | + // with Java 2D, the context state will be completely revalidated | |
| 117 | + OGLContext.invalidateCurrentContext(); | |
| 118 | + } finally { | |
| 119 | + rq.unlock(); | |
| 120 | + } | |
| 121 | + | |
| 122 | + return true; | |
| 123 | + } | |
| 124 | + | |
| 125 | + /** | |
| 126 | + * Invokes the given Runnable on the OGL QueueFlusher thread with the | |
| 127 | + * "shared" OpenGL context (corresponding to the given | |
| 128 | + * GraphicsConfiguration object) made current. This method is typically | |
| 129 | + * used when the Runnable needs a current context to complete its | |
| 130 | + * operation, but does not require that the context be made current to | |
| 131 | + * a particular surface. For example, an application may call this | |
| 132 | + * method so that the given Runnable can query the OpenGL capabilities | |
| 133 | + * of the given GraphicsConfiguration, without making a context current | |
| 134 | + * to a dummy surface (or similar hacky techniques). | |
| 135 | + * | |
| 136 | + * In order to avoid deadlock, it is important that the given Runnable | |
| 137 | + * does not attempt to acquire the AWT lock, as that will be handled | |
| 138 | + * automatically as part of the <code>rq.flushAndInvokeNow()</code> step. | |
| 139 | + * | |
| 140 | + * @param config the GraphicsConfiguration object whose "shared" | |
| 141 | + * context will be made current during this operation; if this value is | |
| 142 | + * null or if OpenGL is not enabled for the GraphicsConfiguration, this | |
| 143 | + * method will return false | |
| 144 | + * @param r the action to be performed on the QFT; cannot be null | |
| 145 | + * @return true if the operation completed successfully, or false if | |
| 146 | + * there was any problem making the shared context current | |
| 147 | + */ | |
| 148 | + public static boolean | |
| 149 | + invokeWithOGLSharedContextCurrent(GraphicsConfiguration config, | |
| 150 | + Runnable r) | |
| 151 | + { | |
| 152 | + if (!(config instanceof OGLGraphicsConfig)) { | |
| 153 | + return false; | |
| 154 | + } | |
| 155 | + | |
| 156 | + OGLRenderQueue rq = OGLRenderQueue.getInstance(); | |
| 157 | + rq.lock(); | |
| 158 | + try { | |
| 159 | + // make the "shared" context current for the given GraphicsConfig | |
| 160 | + OGLContext.setScratchSurface((OGLGraphicsConfig)config); | |
| 161 | + | |
| 162 | + // invoke the given runnable on the QFT | |
| 163 | + rq.flushAndInvokeNow(r); | |
| 164 | + | |
| 165 | + // invalidate the current context so that the next time we render | |
| 166 | + // with Java 2D, the context state will be completely revalidated | |
| 167 | + OGLContext.invalidateCurrentContext(); | |
| 168 | + } finally { | |
| 169 | + rq.unlock(); | |
| 170 | + } | |
| 171 | + | |
| 172 | + return true; | |
| 173 | + } | |
| 174 | + | |
| 175 | + /** | |
| 176 | + * Returns the Rectangle describing the OpenGL viewport on the | |
| 177 | + * Java 2D surface associated with the given Graphics object and | |
| 178 | + * component width and height. When a third-party library is | |
| 179 | + * performing OpenGL rendering directly into the visible region of | |
| 180 | + * the associated surface, this viewport helps the application | |
| 181 | + * position the OpenGL output correctly on that surface. | |
| 182 | + * | |
| 183 | + * Note that the x/y values in the returned Rectangle object represent | |
| 184 | + * the lower-left corner of the viewport region, relative to the | |
| 185 | + * lower-left corner of the given surface. | |
| 186 | + * | |
| 187 | + * @param g the Graphics object for the corresponding destination surface; | |
| 188 | + * cannot be null | |
| 189 | + * @param componentWidth width of the component to be painted | |
| 190 | + * @param componentHeight height of the component to be painted | |
| 191 | + * @return a Rectangle describing the OpenGL viewport for the given | |
| 192 | + * destination surface and component dimensions, or null if the given | |
| 193 | + * Graphics object is invalid | |
| 194 | + */ | |
| 195 | + public static Rectangle getOGLViewport(Graphics g, | |
| 196 | + int componentWidth, | |
| 197 | + int componentHeight) | |
| 198 | + { | |
| 199 | + if (!(g instanceof SunGraphics2D)) { | |
| 200 | + return null; | |
| 201 | + } | |
| 202 | + | |
| 203 | + SunGraphics2D sg2d = (SunGraphics2D)g; | |
| 204 | + SurfaceData sData = (SurfaceData)sg2d.surfaceData; | |
| 205 | + | |
| 206 | + // this is the upper-left origin of the region to be painted, | |
| 207 | + // relative to the upper-left origin of the surface | |
| 208 | + // (in Java2D coordinates) | |
| 209 | + int x0 = sg2d.transX; | |
| 210 | + int y0 = sg2d.transY; | |
| 211 | + | |
| 212 | + // this is the lower-left origin of the region to be painted, | |
| 213 | + // relative to the lower-left origin of the surface | |
| 214 | + // (in OpenGL coordinates) | |
| 215 | + Rectangle surfaceBounds = sData.getBounds(); | |
| 216 | + int x1 = x0; | |
| 217 | + int y1 = surfaceBounds.height - (y0 + componentHeight); | |
| 218 | + | |
| 219 | + return new Rectangle(x1, y1, componentWidth, componentHeight); | |
| 220 | + } | |
| 221 | + | |
| 222 | + /** | |
| 223 | + * Returns the Rectangle describing the OpenGL scissor box on the | |
| 224 | + * Java 2D surface associated with the given Graphics object. When a | |
| 225 | + * third-party library is performing OpenGL rendering directly | |
| 226 | + * into the visible region of the associated surface, this scissor box | |
| 227 | + * must be set to avoid drawing over existing rendering results. | |
| 228 | + * | |
| 229 | + * Note that the x/y values in the returned Rectangle object represent | |
| 230 | + * the lower-left corner of the scissor region, relative to the | |
| 231 | + * lower-left corner of the given surface. | |
| 232 | + * | |
| 233 | + * @param g the Graphics object for the corresponding destination surface; | |
| 234 | + * cannot be null | |
| 235 | + * @return a Rectangle describing the OpenGL scissor box for the given | |
| 236 | + * Graphics object and corresponding destination surface, or null if the | |
| 237 | + * given Graphics object is invalid or the clip region is non-rectangular | |
| 238 | + */ | |
| 239 | + public static Rectangle getOGLScissorBox(Graphics g) { | |
| 240 | + if (!(g instanceof SunGraphics2D)) { | |
| 241 | + return null; | |
| 242 | + } | |
| 243 | + | |
| 244 | + SunGraphics2D sg2d = (SunGraphics2D)g; | |
| 245 | + SurfaceData sData = (SurfaceData)sg2d.surfaceData; | |
| 246 | + Region r = sg2d.getCompClip(); | |
| 247 | + if (!r.isRectangular()) { | |
| 248 | + // caller probably doesn't know how to handle shape clip | |
| 249 | + // appropriately, so just return null (Swing currently never | |
| 250 | + // sets a shape clip, but that could change in the future) | |
| 251 | + return null; | |
| 252 | + } | |
| 253 | + | |
| 254 | + // this is the upper-left origin of the scissor box relative to the | |
| 255 | + // upper-left origin of the surface (in Java 2D coordinates) | |
| 256 | + int x0 = r.getLoX(); | |
| 257 | + int y0 = r.getLoY(); | |
| 258 | + | |
| 259 | + // this is the width and height of the scissor region | |
| 260 | + int w = r.getWidth(); | |
| 261 | + int h = r.getHeight(); | |
| 262 | + | |
| 263 | + // this is the lower-left origin of the scissor box relative to the | |
| 264 | + // lower-left origin of the surface (in OpenGL coordinates) | |
| 265 | + Rectangle surfaceBounds = sData.getBounds(); | |
| 266 | + int x1 = x0; | |
| 267 | + int y1 = surfaceBounds.height - (y0 + h); | |
| 268 | + | |
| 269 | + return new Rectangle(x1, y1, w, h); | |
| 270 | + } | |
| 271 | + | |
| 272 | + /** | |
| 273 | + * Returns an Object identifier for the Java 2D surface associated with | |
| 274 | + * the given Graphics object. This identifier may be used to determine | |
| 275 | + * whether the surface has changed since the last invocation of this | |
| 276 | + * operation, and thereby whether the OpenGL state corresponding to the | |
| 277 | + * old surface must be destroyed and recreated. | |
| 278 | + * | |
| 279 | + * @param g the Graphics object for the corresponding destination surface; | |
| 280 | + * cannot be null | |
| 281 | + * @return an identifier for the surface associated with the given | |
| 282 | + * Graphics object, or null if the given Graphics object is invalid | |
| 283 | + */ | |
| 284 | + public static Object getOGLSurfaceIdentifier(Graphics g) { | |
| 285 | + if (!(g instanceof SunGraphics2D)) { | |
| 286 | + return null; | |
| 287 | + } | |
| 288 | + return ((SunGraphics2D)g).surfaceData; | |
| 289 | + } | |
| 290 | + | |
| 291 | + /** | |
| 292 | + * Returns one of the OGL-specific surface type constants (defined in | |
| 293 | + * this class), which describes the surface associated with the given | |
| 294 | + * Graphics object. | |
| 295 | + * | |
| 296 | + * @param g the Graphics object for the corresponding destination surface; | |
| 297 | + * cannot be null | |
| 298 | + * @return a constant that describes the surface associated with the | |
| 299 | + * given Graphics object; if the given Graphics object is invalid (i.e. | |
| 300 | + * is not associated with an OpenGL surface) this method will return | |
| 301 | + * <code>OGLUtilities.UNDEFINED</code> | |
| 302 | + */ | |
| 303 | + public static int getOGLSurfaceType(Graphics g) { | |
| 304 | + if (!(g instanceof SunGraphics2D)) { | |
| 305 | + return UNDEFINED; | |
| 306 | + } | |
| 307 | + SurfaceData sData = ((SunGraphics2D)g).surfaceData; | |
| 308 | + if (!(sData instanceof OGLSurfaceData)) { | |
| 309 | + return UNDEFINED; | |
| 310 | + } | |
| 311 | + return ((OGLSurfaceData)sData).getType(); | |
| 312 | + } | |
| 313 | + | |
| 314 | + /** | |
| 315 | + * Returns the OpenGL texture target constant (either GL_TEXTURE_2D | |
| 316 | + * or GL_TEXTURE_RECTANGLE_ARB) for the surface associated with the | |
| 317 | + * given Graphics object. This method is only useful for those surface | |
| 318 | + * types that are backed by an OpenGL texture, namely {@code TEXTURE}, | |
| 319 | + * {@code FBOBJECT}, and (on Windows only) {@code PBUFFER}. | |
| 320 | + * | |
| 321 | + * @param g the Graphics object for the corresponding destination surface; | |
| 322 | + * cannot be null | |
| 323 | + * @return the texture target constant for the surface associated with the | |
| 324 | + * given Graphics object; if the given Graphics object is invalid (i.e. | |
| 325 | + * is not associated with an OpenGL surface), or the associated surface | |
| 326 | + * is not backed by an OpenGL texture, this method will return zero. | |
| 327 | + */ | |
| 328 | + public static int getOGLTextureType(Graphics g) { | |
| 329 | + if (!(g instanceof SunGraphics2D)) { | |
| 330 | + return 0; | |
| 331 | + } | |
| 332 | + SurfaceData sData = ((SunGraphics2D)g).surfaceData; | |
| 333 | + if (!(sData instanceof OGLSurfaceData)) { | |
| 334 | + return 0; | |
| 335 | + } | |
| 336 | + return ((OGLSurfaceData)sData).getTextureTarget(); | |
| 337 | + } | |
| 338 | +} | |
| @@ -0,0 +1,21 @@ | ||
| 1 | +<../../../../../mkconfig | |
| 2 | + | |
| 3 | +TARG=\ | |
| 4 | + OGLBlitLoops.dis\ | |
| 5 | + OGLBufImgOps.dis\ | |
| 6 | + OGLContext.dis\ | |
| 7 | + OGLDrawImage.dis\ | |
| 8 | + OGLGraphicsConfig.dis\ | |
| 9 | + OGLMaskBlit.dis\ | |
| 10 | + OGLMaskFill.dis\ | |
| 11 | + OGLPaints.dis\ | |
| 12 | + OGLRenderer.dis\ | |
| 13 | + OGLRenderQueue.dis\ | |
| 14 | + OGLSurfaceData.dis\ | |
| 15 | + OGLSurfaceDataProxy.dis\ | |
| 16 | + OGLTextRenderer.dis\ | |
| 17 | + OGLUtilities.dis\ | |
| 18 | + | |
| 19 | +DISBIN=$ROOT/java/dis/java/java/sun/java2d/opengl | |
| 20 | + | |
| 21 | +<$ROOT/mkfiles/mkjava | |