1 /* 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.opengl; 27 28 import java.awt.AlphaComposite; 29 import java.awt.Composite; 30 import java.awt.Transparency; 31 import java.awt.geom.AffineTransform; 32 import java.awt.image.AffineTransformOp; 33 import java.awt.image.BufferedImage; 34 import java.awt.image.BufferedImageOp; 35 import java.lang.ref.WeakReference; 36 import sun.java2d.SurfaceData; 37 import sun.java2d.loops.Blit; 38 import sun.java2d.loops.CompositeType; 39 import sun.java2d.loops.GraphicsPrimitive; 40 import sun.java2d.loops.GraphicsPrimitiveMgr; 41 import sun.java2d.loops.ScaledBlit; 42 import sun.java2d.loops.SurfaceType; 43 import sun.java2d.loops.TransformBlit; 44 import sun.java2d.pipe.Region; 45 import sun.java2d.pipe.RenderBuffer; 46 import sun.java2d.pipe.RenderQueue; 47 import static sun.java2d.pipe.BufferedOpCodes.*; 48 import java.lang.annotation.Native; 49 50 class OGLBlitLoops { 51 52 static void register() { 53 Blit blitIntArgbPreToSurface = 54 new OGLSwToSurfaceBlit(SurfaceType.IntArgbPre, 55 OGLSurfaceData.PF_INT_ARGB_PRE); 56 Blit blitIntArgbPreToTexture = 57 new OGLSwToTextureBlit(SurfaceType.IntArgbPre, 58 OGLSurfaceData.PF_INT_ARGB_PRE); 59 60 GraphicsPrimitive[] primitives = { 61 // surface->surface ops 62 new OGLSurfaceToSurfaceBlit(), 63 new OGLSurfaceToSurfaceScale(), 64 new OGLSurfaceToSurfaceTransform(), 65 66 // render-to-texture surface->surface ops 67 new OGLRTTSurfaceToSurfaceBlit(), 68 new OGLRTTSurfaceToSurfaceScale(), 69 new OGLRTTSurfaceToSurfaceTransform(), 70 71 // surface->sw ops 72 new OGLSurfaceToSwBlit(SurfaceType.IntArgb, 73 OGLSurfaceData.PF_INT_ARGB), 74 75 // sw->surface ops 76 blitIntArgbPreToSurface, 77 new OGLSwToSurfaceBlit(SurfaceType.IntRgb, 78 OGLSurfaceData.PF_INT_RGB), 79 new OGLSwToSurfaceBlit(SurfaceType.IntRgbx, 80 OGLSurfaceData.PF_INT_RGBX), 81 new OGLSwToSurfaceBlit(SurfaceType.IntBgr, 82 OGLSurfaceData.PF_INT_BGR), 83 new OGLSwToSurfaceBlit(SurfaceType.IntBgrx, 84 OGLSurfaceData.PF_INT_BGRX), 85 new OGLSwToSurfaceBlit(SurfaceType.ThreeByteBgr, 86 OGLSurfaceData.PF_3BYTE_BGR), 87 new OGLSwToSurfaceBlit(SurfaceType.Ushort565Rgb, 88 OGLSurfaceData.PF_USHORT_565_RGB), 89 new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgb, 90 OGLSurfaceData.PF_USHORT_555_RGB), 91 new OGLSwToSurfaceBlit(SurfaceType.Ushort555Rgbx, 92 OGLSurfaceData.PF_USHORT_555_RGBX), 93 new OGLSwToSurfaceBlit(SurfaceType.ByteGray, 94 OGLSurfaceData.PF_BYTE_GRAY), 95 new OGLSwToSurfaceBlit(SurfaceType.UshortGray, 96 OGLSurfaceData.PF_USHORT_GRAY), 97 new OGLGeneralBlit(OGLSurfaceData.OpenGLSurface, 98 CompositeType.AnyAlpha, 99 blitIntArgbPreToSurface), 100 101 new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface), 102 103 new OGLSwToSurfaceScale(SurfaceType.IntRgb, 104 OGLSurfaceData.PF_INT_RGB), 105 new OGLSwToSurfaceScale(SurfaceType.IntRgbx, 106 OGLSurfaceData.PF_INT_RGBX), 107 new OGLSwToSurfaceScale(SurfaceType.IntBgr, 108 OGLSurfaceData.PF_INT_BGR), 109 new OGLSwToSurfaceScale(SurfaceType.IntBgrx, 110 OGLSurfaceData.PF_INT_BGRX), 111 new OGLSwToSurfaceScale(SurfaceType.ThreeByteBgr, 112 OGLSurfaceData.PF_3BYTE_BGR), 113 new OGLSwToSurfaceScale(SurfaceType.Ushort565Rgb, 114 OGLSurfaceData.PF_USHORT_565_RGB), 115 new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgb, 116 OGLSurfaceData.PF_USHORT_555_RGB), 117 new OGLSwToSurfaceScale(SurfaceType.Ushort555Rgbx, 118 OGLSurfaceData.PF_USHORT_555_RGBX), 119 new OGLSwToSurfaceScale(SurfaceType.ByteGray, 120 OGLSurfaceData.PF_BYTE_GRAY), 121 new OGLSwToSurfaceScale(SurfaceType.UshortGray, 122 OGLSurfaceData.PF_USHORT_GRAY), 123 new OGLSwToSurfaceScale(SurfaceType.IntArgbPre, 124 OGLSurfaceData.PF_INT_ARGB_PRE), 125 126 new OGLSwToSurfaceTransform(SurfaceType.IntRgb, 127 OGLSurfaceData.PF_INT_RGB), 128 new OGLSwToSurfaceTransform(SurfaceType.IntRgbx, 129 OGLSurfaceData.PF_INT_RGBX), 130 new OGLSwToSurfaceTransform(SurfaceType.IntBgr, 131 OGLSurfaceData.PF_INT_BGR), 132 new OGLSwToSurfaceTransform(SurfaceType.IntBgrx, 133 OGLSurfaceData.PF_INT_BGRX), 134 new OGLSwToSurfaceTransform(SurfaceType.ThreeByteBgr, 135 OGLSurfaceData.PF_3BYTE_BGR), 136 new OGLSwToSurfaceTransform(SurfaceType.Ushort565Rgb, 137 OGLSurfaceData.PF_USHORT_565_RGB), 138 new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgb, 139 OGLSurfaceData.PF_USHORT_555_RGB), 140 new OGLSwToSurfaceTransform(SurfaceType.Ushort555Rgbx, 141 OGLSurfaceData.PF_USHORT_555_RGBX), 142 new OGLSwToSurfaceTransform(SurfaceType.ByteGray, 143 OGLSurfaceData.PF_BYTE_GRAY), 144 new OGLSwToSurfaceTransform(SurfaceType.UshortGray, 145 OGLSurfaceData.PF_USHORT_GRAY), 146 new OGLSwToSurfaceTransform(SurfaceType.IntArgbPre, 147 OGLSurfaceData.PF_INT_ARGB_PRE), 148 149 // texture->surface ops 150 new OGLTextureToSurfaceBlit(), 151 new OGLTextureToSurfaceScale(), 152 new OGLTextureToSurfaceTransform(), 153 154 // sw->texture ops 155 blitIntArgbPreToTexture, 156 new OGLSwToTextureBlit(SurfaceType.IntRgb, 157 OGLSurfaceData.PF_INT_RGB), 158 new OGLSwToTextureBlit(SurfaceType.IntRgbx, 159 OGLSurfaceData.PF_INT_RGBX), 160 new OGLSwToTextureBlit(SurfaceType.IntBgr, 161 OGLSurfaceData.PF_INT_BGR), 162 new OGLSwToTextureBlit(SurfaceType.IntBgrx, 163 OGLSurfaceData.PF_INT_BGRX), 164 new OGLSwToTextureBlit(SurfaceType.ThreeByteBgr, 165 OGLSurfaceData.PF_3BYTE_BGR), 166 new OGLSwToTextureBlit(SurfaceType.Ushort565Rgb, 167 OGLSurfaceData.PF_USHORT_565_RGB), 168 new OGLSwToTextureBlit(SurfaceType.Ushort555Rgb, 169 OGLSurfaceData.PF_USHORT_555_RGB), 170 new OGLSwToTextureBlit(SurfaceType.Ushort555Rgbx, 171 OGLSurfaceData.PF_USHORT_555_RGBX), 172 new OGLSwToTextureBlit(SurfaceType.ByteGray, 173 OGLSurfaceData.PF_BYTE_GRAY), 174 new OGLSwToTextureBlit(SurfaceType.UshortGray, 175 OGLSurfaceData.PF_USHORT_GRAY), 176 new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture, 177 CompositeType.SrcNoEa, 178 blitIntArgbPreToTexture), 179 180 new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLTexture), 181 182 }; 183 GraphicsPrimitiveMgr.register(primitives); 184 } 185 186 /** 187 * The following offsets are used to pack the parameters in 188 * createPackedParams(). (They are also used at the native level when 189 * unpacking the params.) 190 */ 191 @Native private static final int OFFSET_SRCTYPE = 16; 192 @Native private static final int OFFSET_HINT = 8; 193 @Native private static final int OFFSET_TEXTURE = 3; 194 @Native private static final int OFFSET_RTT = 2; 195 @Native private static final int OFFSET_XFORM = 1; 196 @Native private static final int OFFSET_ISOBLIT = 0; 197 198 /** 199 * Packs the given parameters into a single int value in order to save 200 * space on the rendering queue. 201 */ 202 private static int createPackedParams(boolean isoblit, boolean texture, 203 boolean rtt, boolean xform, 204 int hint, int srctype) 205 { 206 return 207 ((srctype << OFFSET_SRCTYPE) | 208 (hint << OFFSET_HINT ) | 209 ((texture ? 1 : 0) << OFFSET_TEXTURE) | 210 ((rtt ? 1 : 0) << OFFSET_RTT ) | 211 ((xform ? 1 : 0) << OFFSET_XFORM ) | 212 ((isoblit ? 1 : 0) << OFFSET_ISOBLIT)); 213 } 214 215 /** 216 * Enqueues a BLIT operation with the given parameters. Note that the 217 * RenderQueue lock must be held before calling this method. 218 */ 219 private static void enqueueBlit(RenderQueue rq, 220 SurfaceData src, SurfaceData dst, 221 int packedParams, 222 int sx1, int sy1, 223 int sx2, int sy2, 224 double dx1, double dy1, 225 double dx2, double dy2) 226 { 227 // assert rq.lock.isHeldByCurrentThread(); 228 RenderBuffer buf = rq.getBuffer(); 229 rq.ensureCapacityAndAlignment(72, 24); 230 buf.putInt(BLIT); 231 buf.putInt(packedParams); 232 buf.putInt(sx1).putInt(sy1); 233 buf.putInt(sx2).putInt(sy2); 234 buf.putDouble(dx1).putDouble(dy1); 235 buf.putDouble(dx2).putDouble(dy2); 236 buf.putLong(src.getNativeOps()); 237 buf.putLong(dst.getNativeOps()); 238 } 239 240 static void Blit(SurfaceData srcData, SurfaceData dstData, 241 Composite comp, Region clip, 242 AffineTransform xform, int hint, 243 int sx1, int sy1, 244 int sx2, int sy2, 245 double dx1, double dy1, 246 double dx2, double dy2, 247 int srctype, boolean texture) 248 { 249 int ctxflags = 0; 250 if (srcData.getTransparency() == Transparency.OPAQUE) { 251 ctxflags |= OGLContext.SRC_IS_OPAQUE; 252 } 253 254 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 255 rq.lock(); 256 try { 257 // make sure the RenderQueue keeps a hard reference to the 258 // source (sysmem) SurfaceData to prevent it from being 259 // disposed while the operation is processed on the QFT 260 rq.addReference(srcData); 261 262 OGLSurfaceData oglDst = (OGLSurfaceData)dstData; 263 if (texture) { 264 // make sure we have a current context before uploading 265 // the sysmem data to the texture object 266 OGLGraphicsConfig gc = oglDst.getOGLGraphicsConfig(); 267 OGLContext.setScratchSurface(gc); 268 } else { 269 OGLContext.validateContext(oglDst, oglDst, 270 clip, comp, xform, null, null, 271 ctxflags); 272 } 273 274 int packedParams = createPackedParams(false, texture, 275 false, xform != null, 276 hint, srctype); 277 enqueueBlit(rq, srcData, dstData, 278 packedParams, 279 sx1, sy1, sx2, sy2, 280 dx1, dy1, dx2, dy2); 281 282 // always flush immediately, since we (currently) have no means 283 // of tracking changes to the system memory surface 284 rq.flushNow(); 285 } finally { 286 rq.unlock(); 287 } 288 } 289 290 /** 291 * Note: The srcImg and biop parameters are only used when invoked 292 * from the OGLBufImgOps.renderImageWithOp() method; in all other cases, 293 * this method can be called with null values for those two parameters, 294 * and they will be effectively ignored. 295 */ 296 static void IsoBlit(SurfaceData srcData, SurfaceData dstData, 297 BufferedImage srcImg, BufferedImageOp biop, 298 Composite comp, Region clip, 299 AffineTransform xform, int hint, 300 int sx1, int sy1, 301 int sx2, int sy2, 302 double dx1, double dy1, 303 double dx2, double dy2, 304 boolean texture) 305 { 306 int ctxflags = 0; 307 if (srcData.getTransparency() == Transparency.OPAQUE) { 308 ctxflags |= OGLContext.SRC_IS_OPAQUE; 309 } 310 311 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 312 rq.lock(); 313 try { 314 OGLSurfaceData oglSrc = (OGLSurfaceData)srcData; 315 OGLSurfaceData oglDst = (OGLSurfaceData)dstData; 316 int srctype = oglSrc.getType(); 317 boolean rtt; 318 OGLSurfaceData srcCtxData; 319 if (srctype == OGLSurfaceData.TEXTURE) { 320 // the source is a regular texture object; we substitute 321 // the destination surface for the purposes of making a 322 // context current 323 rtt = false; 324 srcCtxData = oglDst; 325 } else { 326 // the source is a pbuffer, backbuffer, or render-to-texture 327 // surface; we set rtt to true to differentiate this kind 328 // of surface from a regular texture object 329 rtt = true; 330 if (srctype == OGLSurfaceData.FBOBJECT) { 331 srcCtxData = oglDst; 332 } else { 333 srcCtxData = oglSrc; 334 } 335 } 336 337 OGLContext.validateContext(srcCtxData, oglDst, 338 clip, comp, xform, null, null, 339 ctxflags); 340 341 if (biop != null) { 342 OGLBufImgOps.enableBufImgOp(rq, oglSrc, srcImg, biop); 343 } 344 345 int packedParams = createPackedParams(true, texture, 346 rtt, xform != null, 347 hint, 0 /*unused*/); 348 enqueueBlit(rq, srcData, dstData, 349 packedParams, 350 sx1, sy1, sx2, sy2, 351 dx1, dy1, dx2, dy2); 352 353 if (biop != null) { 354 OGLBufImgOps.disableBufImgOp(rq, biop); 355 } 356 357 if (rtt && oglDst.isOnScreen()) { 358 // we only have to flush immediately when copying from a 359 // (non-texture) surface to the screen; otherwise Swing apps 360 // might appear unresponsive until the auto-flush completes 361 rq.flushNow(); 362 } 363 } finally { 364 rq.unlock(); 365 } 366 } 367 } 368 369 class OGLSurfaceToSurfaceBlit extends Blit { 370 371 OGLSurfaceToSurfaceBlit() { 372 super(OGLSurfaceData.OpenGLSurface, 373 CompositeType.AnyAlpha, 374 OGLSurfaceData.OpenGLSurface); 375 } 376 377 public void Blit(SurfaceData src, SurfaceData dst, 378 Composite comp, Region clip, 379 int sx, int sy, int dx, int dy, int w, int h) 380 { 381 OGLBlitLoops.IsoBlit(src, dst, 382 null, null, 383 comp, clip, null, 384 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 385 sx, sy, sx+w, sy+h, 386 dx, dy, dx+w, dy+h, 387 false); 388 } 389 } 390 391 class OGLSurfaceToSurfaceScale extends ScaledBlit { 392 393 OGLSurfaceToSurfaceScale() { 394 super(OGLSurfaceData.OpenGLSurface, 395 CompositeType.AnyAlpha, 396 OGLSurfaceData.OpenGLSurface); 397 } 398 399 public void Scale(SurfaceData src, SurfaceData dst, 400 Composite comp, Region clip, 401 int sx1, int sy1, 402 int sx2, int sy2, 403 double dx1, double dy1, 404 double dx2, double dy2) 405 { 406 OGLBlitLoops.IsoBlit(src, dst, 407 null, null, 408 comp, clip, null, 409 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 410 sx1, sy1, sx2, sy2, 411 dx1, dy1, dx2, dy2, 412 false); 413 } 414 } 415 416 class OGLSurfaceToSurfaceTransform extends TransformBlit { 417 418 OGLSurfaceToSurfaceTransform() { 419 super(OGLSurfaceData.OpenGLSurface, 420 CompositeType.AnyAlpha, 421 OGLSurfaceData.OpenGLSurface); 422 } 423 424 public void Transform(SurfaceData src, SurfaceData dst, 425 Composite comp, Region clip, 426 AffineTransform at, int hint, 427 int sx, int sy, int dx, int dy, 428 int w, int h) 429 { 430 OGLBlitLoops.IsoBlit(src, dst, 431 null, null, 432 comp, clip, at, hint, 433 sx, sy, sx+w, sy+h, 434 dx, dy, dx+w, dy+h, 435 false); 436 } 437 } 438 439 class OGLRTTSurfaceToSurfaceBlit extends Blit { 440 441 OGLRTTSurfaceToSurfaceBlit() { 442 super(OGLSurfaceData.OpenGLSurfaceRTT, 443 CompositeType.AnyAlpha, 444 OGLSurfaceData.OpenGLSurface); 445 } 446 447 public void Blit(SurfaceData src, SurfaceData dst, 448 Composite comp, Region clip, 449 int sx, int sy, int dx, int dy, int w, int h) 450 { 451 OGLBlitLoops.IsoBlit(src, dst, 452 null, null, 453 comp, clip, null, 454 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 455 sx, sy, sx+w, sy+h, 456 dx, dy, dx+w, dy+h, 457 true); 458 } 459 } 460 461 class OGLRTTSurfaceToSurfaceScale extends ScaledBlit { 462 463 OGLRTTSurfaceToSurfaceScale() { 464 super(OGLSurfaceData.OpenGLSurfaceRTT, 465 CompositeType.AnyAlpha, 466 OGLSurfaceData.OpenGLSurface); 467 } 468 469 public void Scale(SurfaceData src, SurfaceData dst, 470 Composite comp, Region clip, 471 int sx1, int sy1, 472 int sx2, int sy2, 473 double dx1, double dy1, 474 double dx2, double dy2) 475 { 476 OGLBlitLoops.IsoBlit(src, dst, 477 null, null, 478 comp, clip, null, 479 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 480 sx1, sy1, sx2, sy2, 481 dx1, dy1, dx2, dy2, 482 true); 483 } 484 } 485 486 class OGLRTTSurfaceToSurfaceTransform extends TransformBlit { 487 488 OGLRTTSurfaceToSurfaceTransform() { 489 super(OGLSurfaceData.OpenGLSurfaceRTT, 490 CompositeType.AnyAlpha, 491 OGLSurfaceData.OpenGLSurface); 492 } 493 494 public void Transform(SurfaceData src, SurfaceData dst, 495 Composite comp, Region clip, 496 AffineTransform at, int hint, 497 int sx, int sy, int dx, int dy, int w, int h) 498 { 499 OGLBlitLoops.IsoBlit(src, dst, 500 null, null, 501 comp, clip, at, hint, 502 sx, sy, sx+w, sy+h, 503 dx, dy, dx+w, dy+h, 504 true); 505 } 506 } 507 508 class OGLSurfaceToSwBlit extends Blit { 509 510 private int typeval; 511 512 // REMIND: destination will actually be opaque/premultiplied... 513 OGLSurfaceToSwBlit(SurfaceType dstType, int typeval) { 514 super(OGLSurfaceData.OpenGLSurface, 515 CompositeType.SrcNoEa, 516 dstType); 517 this.typeval = typeval; 518 } 519 520 public void Blit(SurfaceData src, SurfaceData dst, 521 Composite comp, Region clip, 522 int sx, int sy, int dx, int dy, 523 int w, int h) 524 { 525 OGLRenderQueue rq = OGLRenderQueue.getInstance(); 526 rq.lock(); 527 try { 528 // make sure the RenderQueue keeps a hard reference to the 529 // destination (sysmem) SurfaceData to prevent it from being 530 // disposed while the operation is processed on the QFT 531 rq.addReference(dst); 532 533 RenderBuffer buf = rq.getBuffer(); 534 OGLContext.validateContext((OGLSurfaceData)src); 535 536 rq.ensureCapacityAndAlignment(48, 32); 537 buf.putInt(SURFACE_TO_SW_BLIT); 538 buf.putInt(sx).putInt(sy); 539 buf.putInt(dx).putInt(dy); 540 buf.putInt(w).putInt(h); 541 buf.putInt(typeval); 542 buf.putLong(src.getNativeOps()); 543 buf.putLong(dst.getNativeOps()); 544 545 // always flush immediately 546 rq.flushNow(); 547 } finally { 548 rq.unlock(); 549 } 550 } 551 } 552 553 class OGLSwToSurfaceBlit extends Blit { 554 555 private int typeval; 556 557 OGLSwToSurfaceBlit(SurfaceType srcType, int typeval) { 558 super(srcType, 559 CompositeType.AnyAlpha, 560 OGLSurfaceData.OpenGLSurface); 561 this.typeval = typeval; 562 } 563 564 public void Blit(SurfaceData src, SurfaceData dst, 565 Composite comp, Region clip, 566 int sx, int sy, int dx, int dy, int w, int h) 567 { 568 OGLBlitLoops.Blit(src, dst, 569 comp, clip, null, 570 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 571 sx, sy, sx+w, sy+h, 572 dx, dy, dx+w, dy+h, 573 typeval, false); 574 } 575 } 576 577 class OGLSwToSurfaceScale extends ScaledBlit { 578 579 private int typeval; 580 581 OGLSwToSurfaceScale(SurfaceType srcType, int typeval) { 582 super(srcType, 583 CompositeType.AnyAlpha, 584 OGLSurfaceData.OpenGLSurface); 585 this.typeval = typeval; 586 } 587 588 public void Scale(SurfaceData src, SurfaceData dst, 589 Composite comp, Region clip, 590 int sx1, int sy1, 591 int sx2, int sy2, 592 double dx1, double dy1, 593 double dx2, double dy2) 594 { 595 OGLBlitLoops.Blit(src, dst, 596 comp, clip, null, 597 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 598 sx1, sy1, sx2, sy2, 599 dx1, dy1, dx2, dy2, 600 typeval, false); 601 } 602 } 603 604 class OGLSwToSurfaceTransform extends TransformBlit { 605 606 private int typeval; 607 608 OGLSwToSurfaceTransform(SurfaceType srcType, int typeval) { 609 super(srcType, 610 CompositeType.AnyAlpha, 611 OGLSurfaceData.OpenGLSurface); 612 this.typeval = typeval; 613 } 614 615 public void Transform(SurfaceData src, SurfaceData dst, 616 Composite comp, Region clip, 617 AffineTransform at, int hint, 618 int sx, int sy, int dx, int dy, int w, int h) 619 { 620 OGLBlitLoops.Blit(src, dst, 621 comp, clip, at, hint, 622 sx, sy, sx+w, sy+h, 623 dx, dy, dx+w, dy+h, 624 typeval, false); 625 } 626 } 627 628 class OGLSwToTextureBlit extends Blit { 629 630 private int typeval; 631 632 OGLSwToTextureBlit(SurfaceType srcType, int typeval) { 633 super(srcType, 634 CompositeType.SrcNoEa, 635 OGLSurfaceData.OpenGLTexture); 636 this.typeval = typeval; 637 } 638 639 public void Blit(SurfaceData src, SurfaceData dst, 640 Composite comp, Region clip, 641 int sx, int sy, int dx, int dy, int w, int h) 642 { 643 OGLBlitLoops.Blit(src, dst, 644 comp, clip, null, 645 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 646 sx, sy, sx+w, sy+h, 647 dx, dy, dx+w, dy+h, 648 typeval, true); 649 } 650 } 651 652 class OGLTextureToSurfaceBlit extends Blit { 653 654 OGLTextureToSurfaceBlit() { 655 super(OGLSurfaceData.OpenGLTexture, 656 CompositeType.AnyAlpha, 657 OGLSurfaceData.OpenGLSurface); 658 } 659 660 public void Blit(SurfaceData src, SurfaceData dst, 661 Composite comp, Region clip, 662 int sx, int sy, int dx, int dy, int w, int h) 663 { 664 OGLBlitLoops.IsoBlit(src, dst, 665 null, null, 666 comp, clip, null, 667 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 668 sx, sy, sx+w, sy+h, 669 dx, dy, dx+w, dy+h, 670 true); 671 } 672 } 673 674 class OGLTextureToSurfaceScale extends ScaledBlit { 675 676 OGLTextureToSurfaceScale() { 677 super(OGLSurfaceData.OpenGLTexture, 678 CompositeType.AnyAlpha, 679 OGLSurfaceData.OpenGLSurface); 680 } 681 682 public void Scale(SurfaceData src, SurfaceData dst, 683 Composite comp, Region clip, 684 int sx1, int sy1, 685 int sx2, int sy2, 686 double dx1, double dy1, 687 double dx2, double dy2) 688 { 689 OGLBlitLoops.IsoBlit(src, dst, 690 null, null, 691 comp, clip, null, 692 AffineTransformOp.TYPE_NEAREST_NEIGHBOR, 693 sx1, sy1, sx2, sy2, 694 dx1, dy1, dx2, dy2, 695 true); 696 } 697 } 698 699 class OGLTextureToSurfaceTransform extends TransformBlit { 700 701 OGLTextureToSurfaceTransform() { 702 super(OGLSurfaceData.OpenGLTexture, 703 CompositeType.AnyAlpha, 704 OGLSurfaceData.OpenGLSurface); 705 } 706 707 public void Transform(SurfaceData src, SurfaceData dst, 708 Composite comp, Region clip, 709 AffineTransform at, int hint, 710 int sx, int sy, int dx, int dy, 711 int w, int h) 712 { 713 OGLBlitLoops.IsoBlit(src, dst, 714 null, null, 715 comp, clip, at, hint, 716 sx, sy, sx+w, sy+h, 717 dx, dy, dx+w, dy+h, 718 true); 719 } 720 } 721 722 /** 723 * This general Blit implementation converts any source surface to an 724 * intermediate IntArgbPre surface, and then uses the more specific 725 * IntArgbPre->OpenGLSurface/Texture loop to get the intermediate 726 * (premultiplied) surface down to OpenGL. 727 */ 728 class OGLGeneralBlit extends Blit { 729 730 private Blit performop; 731 private WeakReference<SurfaceData> srcTmp; 732 733 OGLGeneralBlit(SurfaceType dstType, 734 CompositeType compType, 735 Blit performop) 736 { 737 super(SurfaceType.Any, compType, dstType); 738 this.performop = performop; 739 } 740 741 public synchronized void Blit(SurfaceData src, SurfaceData dst, 742 Composite comp, Region clip, 743 int sx, int sy, int dx, int dy, 744 int w, int h) 745 { 746 Blit convertsrc = Blit.getFromCache(src.getSurfaceType(), 747 CompositeType.SrcNoEa, 748 SurfaceType.IntArgbPre); 749 750 SurfaceData cachedSrc = null; 751 if (srcTmp != null) { 752 // use cached intermediate surface, if available 753 cachedSrc = srcTmp.get(); 754 } 755 756 // convert source to IntArgbPre 757 src = convertFrom(convertsrc, src, sx, sy, w, h, 758 cachedSrc, BufferedImage.TYPE_INT_ARGB_PRE); 759 760 // copy IntArgbPre intermediate surface to OpenGL surface 761 performop.Blit(src, dst, comp, clip, 762 0, 0, dx, dy, w, h); 763 764 if (src != cachedSrc) { 765 // cache the intermediate surface 766 srcTmp = new WeakReference<>(src); 767 } 768 } 769 } 770 771 class OGLAnyCompositeBlit extends Blit { 772 private WeakReference<SurfaceData> dstTmp; 773 774 public OGLAnyCompositeBlit(SurfaceType dstType) { 775 super(SurfaceType.Any, CompositeType.Any, dstType); 776 } 777 public synchronized void Blit(SurfaceData src, SurfaceData dst, 778 Composite comp, Region clip, 779 int sx, int sy, int dx, int dy, 780 int w, int h) 781 { 782 Blit convertdst = Blit.getFromCache(dst.getSurfaceType(), 783 CompositeType.SrcNoEa, 784 SurfaceType.IntArgbPre); 785 786 SurfaceData cachedDst = null; 787 788 if (dstTmp != null) { 789 // use cached intermediate surface, if available 790 cachedDst = dstTmp.get(); 791 } 792 793 // convert source to IntArgbPre 794 SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h, 795 cachedDst, BufferedImage.TYPE_INT_ARGB_PRE); 796 797 Blit performop = Blit.getFromCache(src.getSurfaceType(), 798 CompositeType.Any, dstBuffer.getSurfaceType()); 799 800 performop.Blit(src, dstBuffer, comp, clip, 801 sx, sy, 0, 0, w, h); 802 803 if (dstBuffer != cachedDst) { 804 // cache the intermediate surface 805 dstTmp = new WeakReference<>(dstBuffer); 806 } 807 808 // now blit the buffer back to the destination 809 convertdst = Blit.getFromCache(dstBuffer.getSurfaceType(), 810 CompositeType.SrcNoEa, 811 dst.getSurfaceType()); 812 convertdst.Blit(dstBuffer, dst, AlphaComposite.Src, 813 clip, 0, 0, dx, dy, w, h); 814 } 815 }